pysqlite:占位符替换列名或表名?

时间:2012-01-12 20:01:17

标签: python sql sqlite pysqlite

使用pysqlite我正在制作一个程序来处理某些数据。在多个表和列中的类似字段上执行相同类型的操作,因此我认为我可以参数化sql语句,如下所示:

def foo():
  column = 'c'
  table = 't'
  row = 1
  # preferred approach, gives syntax error
  c.execute('SELECT ? FROM ? WHERE id=?', (column, table, row))
  # sanity check, works fine
  c.execute('SELECT c FROM t WHERE id=?', (row))
  # workaround, also works, but is this the right way?
  c.execute('SELECT % FROM % WHERE id=?' % (column, table), row))

我得到的错误不是很有帮助(sqlite3.OperationalError: near "?": syntax error),但我明白了一点:Pysqlite不赞赏以这种方式使用占位符。

有人能指出这里发生了什么以及正确的做法吗?

2 个答案:

答案 0 :(得分:18)

您根本无法使用占位符作为列名或表名。我没有这方面的权威性引用 - 我只是通过尝试和失败来“知道”这一点。这有点道理:

  • 如果列和表可以参数化,那么几乎没有 目的是在获取之前准备(execute - )SQL语句,因为语句的所有部分都可以 替换。
  • 我不确定pysqlite 1 ,但MySQLdb会自动引用所有内容 字符串参数。不应引用列名和表名。所以 如果必须的话,会使驱动程序所需的解析复杂化 判断占位符是代表列还是表名称 需要引用的价值。

简而言之,您找到了正确的方法 - 使用字符串格式化。

c.execute('SELECT {} FROM {} WHERE id=?'.format(column, table), row))

1 并非所有驱动程序引用参数 - oursql都没有,因为它会单独向服务器发送SQL和参数。

答案 1 :(得分:2)

正如@unutbu回答的那样,没有办法使用占位符来表/列名。我建议你现在就做你正在做的事情,但也要引用表名来保护自己免受可能有奇怪名字的表或列的影响。

What does the SQL Standard say about usage of backtick(`)?已经在某种程度上解释了这一点,尽管在答案中有意见,但我会说,在你的情况下,引用是一个好主意。