Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的sqlite3:手动设置字符串格式对于选择或更新变量列是否安全?_Python_Sqlite - Fatal编程技术网

Python中的sqlite3:手动设置字符串格式对于选择或更新变量列是否安全?

Python中的sqlite3:手动设置字符串格式对于选择或更新变量列是否安全?,python,sqlite,Python,Sqlite,众所周知,不应该使用本机字符串操作组装SQL查询,而应该使用带有占位符的准备语句作为变量。Python中的sqlite3是这样处理的: c.execute('UPDATE stock SET price = ? WHERE symbol = ?', the_price, the_symbol) 这种方法的限制是无法为选定或更新的列设置参数。在上面的示例中,价格列被更新。但是,其他请求将以相同的方式更新另一列。除了列的名称之外,这些请求中的每一个都几乎相同。因此,对于干燥(不要重复你自己),很容

众所周知,不应该使用本机字符串操作组装SQL查询,而应该使用带有占位符的准备语句作为变量。Python中的sqlite3是这样处理的:

c.execute('UPDATE stock SET price = ? WHERE symbol = ?', the_price, the_symbol)
这种方法的限制是无法为选定或更新的列设置参数。在上面的示例中,价格列被更新。但是,其他请求将以相同的方式更新另一列。除了列的名称之外,这些请求中的每一个都几乎相同。因此,对于干燥(不要重复你自己),很容易采取以下措施:

if my_col in LIST_OK_COLUMNS:
    c.execute('UPDATE stock SET {} = ? WHERE symbol = ?'.format(my_col), the_symbol, the_price)
不过,这是一个使用本机字符串操作构建的查询,根据文档,这是不安全的


正确执行此操作的最标准方法是什么?

如果直接插入SQL语句的任何字符串可能由用户控制,则说明您有问题

对于值,可以使用SQL参数

表/列名没有这种机制(因为向用户询问这些名称通常不会发生;SQL是在邪恶的互联网出现之前设计的,一半的应用程序运行在不受信任的客户端上)

要生成列名称,例如
price=-100,其中1或symbol=--无害,您必须正确地避开它:

def sql_escape_identifier(s):
    return '"' + s.replace('"', '""') + '"'

c.execute('UPDATE stock SET {} = ...'.format(sql_escape_identifier(my_col)), ...

如果直接插入到SQL语句中的任何字符串可能由用户控制,则会出现问题

对于值,可以使用SQL参数

表/列名没有这种机制(因为向用户询问这些名称通常不会发生;SQL是在邪恶的互联网出现之前设计的,一半的应用程序运行在不受信任的客户端上)

要生成列名称,例如
price=-100,其中1或symbol=--无害,您必须正确地避开它:

def sql_escape_identifier(s):
    return '"' + s.replace('"', '""') + '"'

c.execute('UPDATE stock SET {} = ...'.format(sql_escape_identifier(my_col)), ...

晚一点可以。。。由于您控制着SQL的输入(列名等)-风险在于实际参数通常位于程序外部,很容易忘记对其进行清理,因此建议使用现有功能,而不是字符串格式。(当然…如果你让
my_col
来自外部源-那是件坏事(tm))好吧,我的_col确实来自外部源,因为只有前端最终知道要更新什么。啊,对不起-我误读了最后一个代码块-是的-只要你验证-那很好…)后者没问题。。。由于您控制着SQL的输入(列名等)-风险在于实际参数通常位于程序外部,很容易忘记对其进行清理,因此建议使用现有功能,而不是字符串格式。(当然…如果你让
my_col
来自外部源-那是件坏事(tm))好吧,我的_col确实来自外部源,因为只有前端最终知道要更新什么。啊,对不起-我误读了最后一个代码块-是-只要你验证-那很好…)