SQLite用变量指定列名/表名执行SELECT报语法错误是什么原因?
问题原因
SQLite 中的问号?参数占位符仅支持传入值类型参数,不支持传入表名、列名这类 SQL 标识符(SQL 结构组成部分)。
数据库执行 SQL 前会先完成语法解析、执行计划生成,这一步必须明确知道涉及的表、列等结构信息,才能完成权限校验、索引匹配等逻辑。而占位符传入的参数是在执行计划生成后才会代入,只会被当作普通字符串值处理,不会被识别为 SQL 结构的一部分。
你写的c.execute('SELECT (?) FROM (?)',('Unit_ID','Units'))执行时相当于尝试执行SELECT 'Unit_ID' FROM 'Units',表名位置出现字符串常量不符合 SQL 语法规范,因此抛出语法错误。
解决方法
如果你需要动态指定列名、表名,需要通过字符串拼接的方式生成 SQL 语句,需要注意两点:
- 拼接时建议用双引号包裹标识符,避免表名/列名是 SQL 关键字、包含特殊字符时的语法问题
- 严格校验动态传入的表名、列名是否合法,避免 SQL 注入风险:如果变量来自用户输入,一定要先通过查询
sqlite_master确认表名存在、通过PRAGMA table_info(你的表名)确认列名存在后再拼接执行,禁止直接使用未校验的用户输入拼接 SQL。
示例代码:
col_name = "Unit_ID" table_name = "Units" # 字符串格式化拼接SQL c.execute(f'SELECT "{col_name}" FROM "{table_name}"')
内容的提问来源于stack exchange,提问作者Jack Hasselbring
相关产品推荐
相关产品推荐

