MySQL 参数化查询

2024-12-03 08:44:00
admin
原创
160
摘要:问题描述:我很难使用 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大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用