【问题标题】:How to set the edited attribute to a variable in SQL如何在 SQL 中将已编辑的属性设置为变量
【发布时间】:2021-12-31 03:27:09
【问题描述】:

基本上,为了能够编写更少的函数,我将edited 属性设为变量。所以我的编辑代码如下所示:

cur.execute("""
                    UPDATE acteurs SET ?=? WHERE IDACTEUR=?;
                    """, (attribute, newvalue, actorid))
        conn.commit()

但是在运行它时,我得到一个语法错误。我应该如何编辑它以使其工作?

【问题讨论】:

  • 出于安全原因,在某些地方您不能使用?。例如,您不能使用? 作为表名。您可能需要使用string formattingf-string 输入一些值
  • @esqew 也许这是 SQLIte 中的标准替换,但 Python 可能会阻止它 - 出于安全原因
  • @esqew 我会说这个问题可能是因为 Python 可能会转义参数以使其安全。因此,它可能会创建两个字符串 "column"="value" 而不是 column=value,这在 SQL 中是不正确的。

标签: python sql sqlite


【解决方案1】:

出于安全原因,Python 在输入查询之前会转义值,因此在某些地方无法使用值,因为它会创建错误的查询。

使用?=? 你期望column=value 但它会创建两个字符串"column"="value" 并且会产生错误。

出于安全原因,它还可能检查? 是否存在表名或列名并引发错误。

可能需要使用string formattingf-string 输入column。但这不是首选。查询不应使用? 作为表名、列名。


最小的工作示例。

它使用con.set_trace_callback(print) 显示最后一个查询。

import sqlite3

con = sqlite3.connect(":memory:")#
con.set_trace_callback(print)

cur = con.cursor()

cur.execute("CREATE TABLE test(key TEXT, value TEXT)")
print('---')
cur.execute("INSERT INTO test(key, value) VALUES (?, ?)", ("a", "1"))
con.commit()
print('---')

cur.execute("SELECT key, value FROM test WHERE key=?", ('a',))
row = cur.fetchone()
print(row)
print('---')

cur.execute("SELECT key, value FROM test WHERE ?=?", ('key', 'a'))
row = cur.fetchone()
print(row)
print('---')

try:
    cur.execute("UPDATE test SET ?=? WHERE key=?", ('value', '3', 'a',))
    con.commit()
except Exception as ex:
    print('Exception:', ex)
print('---')

try:
    column = 'value'
    cur.execute(f"UPDATE test SET {column}=? WHERE key=?", ('3', 'a',))
    con.commit()
except Exception as ex:
    print('Exception:', ex)
print('---')

cur.execute("SELECT key, value FROM test WHERE key=?", ('a',))
row = cur.fetchone()
print(row)
print('---')

con.close()

示例WHERE key=?", ('a',) 创建WHERE key='a' 并获得一行。

示例 WHERE ?=?", ('key', 'a',) 创建 WHERE 'key'='a' 并获得零行。

示例SET ?=? 引发错误。

CREATE TABLE test(key TEXT, value TEXT)
---
BEGIN 
INSERT INTO test(key, value) VALUES ('a', '1')
COMMIT
---
SELECT key, value FROM test WHERE key='a'
('a', '1')
---
SELECT key, value FROM test WHERE 'key'='a'
None
---
Exception: near "?": syntax error
---
BEGIN 
UPDATE test SET value='3' WHERE key='a'
COMMIT
---
SELECT key, value FROM test WHERE key='a'
('a', '3')

【讨论】:

  • 简而言之 - 您不能使用占位符替换表和列名之类的内容,因为它会产生重大的安全风险,这种替换类型试图减轻这种风险。
  • @esqew 是的,它会检查查询是否存在安全风险——因此查询不应使用表和列的占位符
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多