MySQL 参数化查询

2024-12-03 08:44:00
admin
原创
163
摘要:问题描述:我很难使用 MySQLdb 模块将信息插入数据库。我需要将 6 个变量插入表中。cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLeng...

问题描述:

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

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

""")

有人能帮我解释一下这里的语法吗?


解决方案 1:

谨慎使用字符串插值进行 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)。

解决方案 2:

您有几个可用的选项。您需要熟悉 python 的字符串迭代。当您将来想要了解这类内容时,您可能会更成功地搜索这个术语。

更适合查询:

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”的出现次数也很糟糕 :)

解决方案 3:

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

   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)。

解决方案 4:

实际上,即使变量 (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”。完成后,查询实际上会说“...WHERE price < 5”。

解决方案 5:

作为所选答案的替代,并且具有与 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()

解决方案 6:

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

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

解决方案 7:

这是另一种方法。它记录在 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)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用