9

我正在尝试将从文件中读取的字符串插入到sqlitePython 中的数据库中。字符串具有空格(换行符、制表符和空格),并且还具有单引号或双引号的外观。这是我尝试这样做的方法:

import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()

# Create table
c.execute('''CREATE TABLE test
             (a text, b text)''')

f = open("foo", "w")
f.write("hello\n\'world\'\n")
f.close()

testfield = open("foo").read()

# Insert a row of data
c.execute("INSERT INTO test VALUES ('%s', 'bar')" %(testfield))

# Save (commit) the changes
conn.commit()

我发现这失败并出现错误:

    c.execute("INSERT INTO test VALUES ('%s', 'bar')" %(testfield))
sqlite3.OperationalError: near "world": syntax error

我怎样才能做到这一点?在插入数据库之前是否需要对字符串进行转义,如果需要,如何转义?谢谢。

4

1 回答 1

25

您使用 SQL 参数而不是字符串格式:

c.execute("INSERT INTO test VALUES (?, 'bar')", (testfield,))

使用 SQL 参数时,您可以让数据库库处理引用,甚至更好的是,让数据库优化查询并将优化的查询计划重用于同一基本查询的多次执行(使用不同的参数)。

最后但并非最不重要的一点是,您可以更好地防御 SQL 注入攻击,因为数据库库最了解如何逃避危险的类似 SQL 的值。

引用sqlite3 文档

通常,您的 SQL 操作将需要使用 Python 变量中的值。你不应该使用 Python 的字符串操作来组装你的查询,因为这样做是不安全的;它使您的程序容易受到 SQL 注入攻击(有关可能出错的幽默示例,请参见http://xkcd.com/327/ )。

相反,使用 DB-API 的参数替换。将?作为占位符放在要使用值的任何位置,然后提供一个值元组作为游标execute()方法的第二个参数。

于 2013-02-04T20:36:20.550 回答