题
我使用MySQLdb的模块插入信息到我的数据库具有一个硬的时间。我需要插入6个变量插入表中。
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
有人可以帮助我在这里的语法?
解决方案
小心使用字符串插值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语句中的参数绑定改性剂不同的DB API实现之间和MySQL客户端库使用printf
风格的语法,而不是更通常接受的变化的混乱“?”标记(例如通过。python-sqlite
使用)。
其他提示
您有几个选项可用。你会想舒服python的字符串iterpolation。这是一个术语,你可能有更多的成功搜索在未来,当你想知道这样的东西。
更好地为查询:
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的”出场:)
链接的文档给出以下示例:
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)。
其实,即使你的变量(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_PRICE = 5那么,为什么用%S字符串中?因为MySQLdb的将其转换为SQL字面值,这是字符串“5”。当它完成后,查询将居然说,” ......在价格<5" 。
作为替代选择的答案,并用马塞尔的相同安全语义,这里是使用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_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()
下面是另一种方式来做到这一点。它记录了MySQL的官方网站上。 HTTPS://dev.mysql。 COM / DOC /连接器的Python / EN /连接器的python-API-mysqlcursor-execute.html
在的精神,它使用@Trey烈性黑啤酒的回答相同的机械师。但是,我发现这个漂亮和更具有可读性。
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)
和更好地示出任何需要的变量:
NB:注意所做的逃逸
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)
在第一溶液效果很好。我想在这里补充一个小细节。请确保您要更换可变/更新它会必须是一个类型的海峡。我的MySQL类型是小数,但我不得不做出的参数变量STR能够执行查询。
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)