为什么查询中的 Snowflake 变量绑定会抛出带有 table 名称而非整数的错误?
Why does Snowflake variable binding in query throw error with table name but not integer?
我正在关注 Snowflake Python Connector 变量绑定文档以避免 SQL 注入。我成功地使用以下凭据字典建立了数据库连接:
import snowflake.connector
CONN = snowflake.connector.connect(
user=snowflake_creds['user'],
password=snowflake_creds['password'],
account=snowflake_creds['account'],
warehouse=snowflake_creds["warehouse"],
database=snowflake_creds['database'],
schema=snowflake_creds['schema'],
)
cur = CONN.cursor(snowflake.connector.DictCursor)
以下块工作正常,我得到查询结果,对 table 名称进行硬编码并使用标准 format
绑定:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %s")
bind_params = (2)
results = cur.execute(command % bind_params).fetchall()
同样,这个块工作正常,使用 pyformat
绑定:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %(id)s")
bind_params = {"id": 2}
results = cur.execute(command, bind_params).fetchall()
但是以下两个块都会导致 ProgrammingError
(粘贴在第二个块下方):
command = ("SELECT * FROM %s WHERE batch_id = %s")
bind_params = ("TEST_INPUT_TABLE", 2)
results = cur.execute(command, bind_params).fetchall()
command = ("SELECT * FROM %(tablename)s WHERE batch_id = %(id)s")
bind_params = {
"tablename": "TEST_INPUT_TABLE",
"id": 2
}
results = cur.execute(command, bind_params).fetchall()
ProgrammingError: 001011 (42601): SQL compilation error:
invalid URL prefix found in: 'TEST_INPUT_TABLE'
字符串和整数的插值方式有什么不同吗?我会
不认为这会有所作为,但这就是我能想到的。我是吗
这里缺少一些简单的东西?我不想在硬编码 table 名称和让系统面临 SQL 注入风险之间做出选择。感谢您的指导。
当绑定变量引用对象而不是字符串文字时,您应该使用 INDENTIFER()
函数对其进行包装。例如:
command = ("SELECT * FROM IDENTIFIER(%(tablename)s) WHERE batch_id = %(id)s")
https://docs.snowflake.com/en/sql-reference/identifier-literal.html
试一试。
我正在关注 Snowflake Python Connector 变量绑定文档以避免 SQL 注入。我成功地使用以下凭据字典建立了数据库连接:
import snowflake.connector
CONN = snowflake.connector.connect(
user=snowflake_creds['user'],
password=snowflake_creds['password'],
account=snowflake_creds['account'],
warehouse=snowflake_creds["warehouse"],
database=snowflake_creds['database'],
schema=snowflake_creds['schema'],
)
cur = CONN.cursor(snowflake.connector.DictCursor)
以下块工作正常,我得到查询结果,对 table 名称进行硬编码并使用标准 format
绑定:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %s")
bind_params = (2)
results = cur.execute(command % bind_params).fetchall()
同样,这个块工作正常,使用 pyformat
绑定:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %(id)s")
bind_params = {"id": 2}
results = cur.execute(command, bind_params).fetchall()
但是以下两个块都会导致 ProgrammingError
(粘贴在第二个块下方):
command = ("SELECT * FROM %s WHERE batch_id = %s")
bind_params = ("TEST_INPUT_TABLE", 2)
results = cur.execute(command, bind_params).fetchall()
command = ("SELECT * FROM %(tablename)s WHERE batch_id = %(id)s")
bind_params = {
"tablename": "TEST_INPUT_TABLE",
"id": 2
}
results = cur.execute(command, bind_params).fetchall()
ProgrammingError: 001011 (42601): SQL compilation error:
invalid URL prefix found in: 'TEST_INPUT_TABLE'
字符串和整数的插值方式有什么不同吗?我会 不认为这会有所作为,但这就是我能想到的。我是吗 这里缺少一些简单的东西?我不想在硬编码 table 名称和让系统面临 SQL 注入风险之间做出选择。感谢您的指导。
当绑定变量引用对象而不是字符串文字时,您应该使用 INDENTIFER()
函数对其进行包装。例如:
command = ("SELECT * FROM IDENTIFIER(%(tablename)s) WHERE batch_id = %(id)s")
https://docs.snowflake.com/en/sql-reference/identifier-literal.html
试一试。