如何在 SQL 中将 table 名称作为变量传递 - Python 3.4
How can I pass a table name as a variable in SQL - Python 3.4
我正在尝试在 python 中编写一个 SQL 语句,它将 table 名称作为变量传递。但是,我收到以下错误:必须声明 table 变量“@P1”。
pypyodbc.Programming Error: ('42000', '[42000]' [Miscrosoft] [SQL SERVER NATIVE CLIENT 10.0] [SQL SERVER] Must declare the table variable "@P1"
产生错误的代码是:
query = cursor.execute('''SELECT * FROM ?''', (table_variable,))
我还有其他代码,我使用相同的语法将变量传递给 SQL 语句,该语句工作正常(下面的代码按预期工作)。
query = cursor.execute('''SELECT column_name FROM information_schema.columns WHERE table_name = ?''', (table_variable,))
当我使用变量传递 table 名称时似乎发生了错误。
如能帮助解决此错误,我们将不胜感激。
你想做的事是不可能的。您只能将值作为参数传递到查询中 - 所以
SELECT * FROM @Table
被禁止但是
SELECT * FROM TableName WHERE Column=@Value
完全合法。
现在,关于它被禁止的原因。从逻辑的角度来看,数据库层根本无法缓存您要执行的操作的查询计划-参数将完全彻底地改变它的去向和内容returns-并且不能保证提前知道它能做什么或不能做什么。这就像试图在 运行 时间加载一个抽象源文件并执行它 - 混乱、不可预测、不可靠并且存在潜在的安全漏洞。
从可靠性的角度,请不要这样做
SELECT * FROM Table
要么。它会降低您的代码的可读性,因为您看不到返回的内容,但也会降低代码的可靠性,因为它可能会在没有警告的情况下发生更改并破坏您的应用程序。
我知道乍一看这似乎有很长的路要走,但老实说 - 编写单独的 SELECT 语句来指定他们实际想要带回的字段是一种更好的方法。它还将使您的应用程序 运行 更快 :-)
随着 OP 的新评论,这已经发生了相当大的变化。如果您只想从每个 table 中获取几行样本,您可以轻松利用 sys.tables 目录视图。这将为数据库中的每个 table 创建一个 select 语句。如果您有多个架构,您可以扩展它以添加架构名称。
select 'select top 10 * from ' + QUOTENAME(t.name)
from sys.tables t
您可以定义一个字符串变量:
table_var_str = 'Table_name'
st = 'SELECT * FROM ' + table_var_str
query = cursor.execute(st)
它将解决问题。
您还可以将 table_var_str 设置为列表:
table_var_str = []
st = []
for i in range(N):
table_var_str.append = 'Table_name' + str(i)
st.append('SELECT * FROM ' + table_var_str[i])
for j in range(J):
query = cursor.execute(st[j])
如果查询很长,你应该把它们写在一行而不是多行。
我正在尝试在 python 中编写一个 SQL 语句,它将 table 名称作为变量传递。但是,我收到以下错误:必须声明 table 变量“@P1”。
pypyodbc.Programming Error: ('42000', '[42000]' [Miscrosoft] [SQL SERVER NATIVE CLIENT 10.0] [SQL SERVER] Must declare the table variable "@P1"
产生错误的代码是:
query = cursor.execute('''SELECT * FROM ?''', (table_variable,))
我还有其他代码,我使用相同的语法将变量传递给 SQL 语句,该语句工作正常(下面的代码按预期工作)。
query = cursor.execute('''SELECT column_name FROM information_schema.columns WHERE table_name = ?''', (table_variable,))
当我使用变量传递 table 名称时似乎发生了错误。
如能帮助解决此错误,我们将不胜感激。
你想做的事是不可能的。您只能将值作为参数传递到查询中 - 所以
SELECT * FROM @Table
被禁止但是
SELECT * FROM TableName WHERE Column=@Value
完全合法。
现在,关于它被禁止的原因。从逻辑的角度来看,数据库层根本无法缓存您要执行的操作的查询计划-参数将完全彻底地改变它的去向和内容returns-并且不能保证提前知道它能做什么或不能做什么。这就像试图在 运行 时间加载一个抽象源文件并执行它 - 混乱、不可预测、不可靠并且存在潜在的安全漏洞。
从可靠性的角度,请不要这样做
SELECT * FROM Table
要么。它会降低您的代码的可读性,因为您看不到返回的内容,但也会降低代码的可靠性,因为它可能会在没有警告的情况下发生更改并破坏您的应用程序。
我知道乍一看这似乎有很长的路要走,但老实说 - 编写单独的 SELECT 语句来指定他们实际想要带回的字段是一种更好的方法。它还将使您的应用程序 运行 更快 :-)
随着 OP 的新评论,这已经发生了相当大的变化。如果您只想从每个 table 中获取几行样本,您可以轻松利用 sys.tables 目录视图。这将为数据库中的每个 table 创建一个 select 语句。如果您有多个架构,您可以扩展它以添加架构名称。
select 'select top 10 * from ' + QUOTENAME(t.name)
from sys.tables t
您可以定义一个字符串变量:
table_var_str = 'Table_name'
st = 'SELECT * FROM ' + table_var_str
query = cursor.execute(st)
它将解决问题。
您还可以将 table_var_str 设置为列表:
table_var_str = []
st = []
for i in range(N):
table_var_str.append = 'Table_name' + str(i)
st.append('SELECT * FROM ' + table_var_str[i])
for j in range(J):
query = cursor.execute(st[j])
如果查询很长,你应该把它们写在一行而不是多行。