mysql参数化查询

pb3skfrl  于 2021-06-20  发布在  Mysql
关注(0)|答案(7)|浏览(332)

我很难使用mysqldb模块将信息插入到我的数据库中。我需要在表中插入6个变量。

cursor.execute ("""
    INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
    VALUES
        (var1, var2, var3, var4, var5, var6)

""")

有人能帮我学一下语法吗?

vmpqdwk3

vmpqdwk31#

链接的文档给出了以下示例:

cursor.execute ("""
         UPDATE animal SET name = %s
         WHERE name = %s
       """, ("snake", "turtle"))
   print "Number of rows updated: %d" % cursor.rowcount

因此,您只需根据自己的代码调整它—例如:

cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%s, %s, %s, %s, %s, %s)

        """, (var1, var2, var3, var4, var5, var6))

(如果songlength是数字,您可能需要使用%d而不是%s)。

13z8s7eq

13z8s7eq2#

这是另一种方法。在mysql官方网站上有记录。https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
在精神上,它使用了@trey stout的答案的相同机制。不过,我觉得这个更漂亮,更可读。

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

为了更好地说明变量的必要性:
注意正在做的越狱。

employee_id = 2
first_name = "Jane"
last_name = "Doe"

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
8ftvxx2r

8ftvxx2r3#

注意不要对sql查询使用字符串插值,因为它不会正确地转义输入参数,并且会使应用程序对sql注入漏洞开放。这种差别看似微不足道,但实际上却是巨大的。

不正确(有安全问题)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))

正确(带转义)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))

在sql语句中用于绑定参数的修饰符在不同的dbapi实现之间以及mysql客户机库使用的修饰符之间存在差异,这增加了混淆 printf 样式语法,而不是更普遍接受的“?”标记(例如。 python-sqlite ).

mefy6pfw

mefy6pfw4#

你有几个选择。您需要熟悉python的string iterporation。这是一个术语,你可能会有更成功的搜索在未来当你想知道这样的东西。
更适合查询:

some_dictionary_with_the_data = {
    'name': 'awesome song',
    'artist': 'some band',
    etc...
}
cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)

        """, some_dictionary_with_the_data)

考虑到您的所有数据可能已经存在于对象或字典中,第二种格式更适合您。而且,当您必须在一年内回来更新此方法时,在字符串中计算“%s”的出现次数也很糟糕:)

hc8w905p

hc8w905p5#

作为所选答案的另一种选择,使用与marcel相同的安全语义,这里提供了一种使用python字典指定值的简洁方法。它的优点是在添加或删除要插入的列时易于修改:

meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
  insert='insert into Songs ({0}) values ({1})'.
        .format(','.join(meta_cols), ','.join( ['%s']*len(meta_cols) ))
  args = [ meta[i] for i in meta_cols ]
  cursor=db.cursor()
  cursor.execute(insert,args)
  db.commit()

其中meta是保存要插入的值的字典。更新的方法相同:

meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
  update='update Songs set {0} where id=%s'.
        .format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
  args = [ meta[i] for i in meta_cols ]
  args.append( songid )
  cursor=db.cursor()
  cursor.execute(update,args)
  db.commit()
mhd8tkvw

mhd8tkvw6#

第一种解决方案效果很好。我想在这里补充一个小细节。确保您尝试替换/更新的变量必须是str类型。我的mysql类型是decimal,但我必须将参数变量设置为str才能执行查询。

temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)
jq6vz3qz

jq6vz3qz7#

实际上,即使您的变量(songlength)是数字,为了正确绑定参数,您仍然需要用%s格式化它。如果尝试使用%d,则会出现错误。下面是这个链接的一个小摘录http://mysql-python.sourceforge.net/mysqldb.html:
要执行查询,首先需要一个游标,然后可以对其执行查询:

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

在本例中,max\u price=5为什么在字符串中使用%s?因为mysqldb会将其转换为sql文本值,即字符串“5”。完成后,查询实际上会说“…where price<5”。

相关问题