cur.executescript使用占位符插入数据异常问题排查与修复
问题原因与修复方案
问题原因
sqlite3的executescript()方法不支持参数占位符(?),它的设计目标是执行一段包含多个SQL语句的纯文本脚本,不会对占位符做解析替换。你写的(?, ?)因为没有被赋值,会被当作NULL插入表中,这就是结果里出现(None, None)行的原因,而后面直接写死的字面量值能正常插入。
修复方案
方案1:使用executemany()批量插入(推荐)
这是参数化插入的标准方式,既安全又高效:
import sqlite3 conn = sqlite3.connect('SingleTableSql.sqlite') cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS Track') cur.execute('CREATE TABLE Track (title TEXT, plays INTEGER)') # 准备批量插入的数据 tracks = [ ('Thunderstruck', 20), ('My Way', 15) ] # 用executemany执行批量插入 cur.executemany('INSERT INTO Track (title, plays) VALUES (?, ?)', tracks) conn.commit() cur.execute('SELECT title, plays FROM Track') for row in cur: print(row) cur.close()
方案2:直接在executescript中写死所有值(不推荐,存在SQL注入风险)
如果一定要用executescript(),可去掉占位符,直接写完整的INSERT语句:
import sqlite3 conn = sqlite3.connect('SingleTableSql.sqlite') cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS Track') cur.execute('CREATE TABLE Track (title TEXT, plays INTEGER)') cur.executescript(""" INSERT INTO Track (title, plays) VALUES ('Thunderstruck', 20); INSERT INTO Track (title, plays) VALUES ('My Way', 15); """) conn.commit() cur.execute('SELECT title, plays FROM Track') for row in cur: print(row) cur.close()
方案3:分开用execute()执行每个参数化INSERT
如果数据量不大,也可以逐个执行参数化插入:
import sqlite3 conn = sqlite3.connect('SingleTableSql.sqlite') cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS Track') cur.execute('CREATE TABLE Track (title TEXT, plays INTEGER)') cur.execute('INSERT INTO Track (title, plays) VALUES (?, ?)', ('Thunderstruck', 20)) cur.execute('INSERT INTO Track (title, plays) VALUES (?, ?)', ('My Way', 15)) conn.commit() cur.execute('SELECT title, plays FROM Track') for row in cur: print(row) cur.close()
内容的提问来源于stack exchange,提问作者ElIgo
相关产品推荐
相关产品推荐

