Sql server 在SQL-Python 3.4中,如何将表名作为变量传递

Sql server 在SQL-Python 3.4中,如何将表名作为变量传递,sql-server,python-3.x,pyodbc,Sql Server,Python 3.x,Pyodbc,我试图用python编写一条SQL语句,它将表名作为变量传递。但是,我得到以下错误:必须声明表变量“@P1” 产生错误的代码是: query = cursor.execute('''SELECT * FROM ?''', (table_variable,)) 我还有其他代码,其中我使用相同的语法将变量传递给SQL语句,这很好(下面的代码按预期工作) 当我使用变量传递表名时,似乎会发生错误 如果您能帮助解决此错误,我们将不胜感激。您试图做的事情是不可能的。您只能将值作为参数传递到查询中-因此 S

我试图用python编写一条SQL语句,它将表名作为变量传递。但是,我得到以下错误:必须声明表变量“@P1”

产生错误的代码是:

query = cursor.execute('''SELECT * FROM ?''', (table_variable,))
我还有其他代码,其中我使用相同的语法将变量传递给SQL语句,这很好(下面的代码按预期工作)

当我使用变量传递表名时,似乎会发生错误


如果您能帮助解决此错误,我们将不胜感激。

您试图做的事情是不可能的。您只能将值作为参数传递到查询中-因此

SELECT * FROM @Table
是被禁止的,但是

SELECT * FROM TableName WHERE Column=@Value 
这是完全合法的

现在,关于为什么它被禁止。从逻辑的角度来看,数据库层根本无法缓存查询计划,以了解您正在尝试执行的操作-参数将完全、彻底地更改它的位置和返回的内容-并且无法提前保证它可以或不能执行的操作。这就像试图在运行时加载一个抽象源文件并执行它——混乱、不可预测、不可靠,还有潜在的安全漏洞

从可靠性的角度来看,请不要这样做

SELECT * FROM Table 
要么。它会降低代码的可读性,因为您无法看到返回的内容,但也会降低可靠性,因为它可能会在没有警告的情况下更改并破坏您的应用程序


我知道一开始似乎有很长的路要走,但老实说,编写单独的SELECT语句来指定他们实际想要返回的字段是一种更好的方法。它还将使您的应用程序运行得更快:-)

您试图做的事情是不可能的。您只能将值作为参数传递到查询中-因此

SELECT * FROM @Table
是被禁止的,但是

SELECT * FROM TableName WHERE Column=@Value 
这是完全合法的

现在,关于为什么它被禁止。从逻辑的角度来看,数据库层根本无法缓存查询计划,以了解您正在尝试执行的操作-参数将完全、彻底地更改它的位置和返回的内容-并且无法提前保证它可以或不能执行的操作。这就像试图在运行时加载一个抽象源文件并执行它——混乱、不可预测、不可靠,还有潜在的安全漏洞

从可靠性的角度来看,请不要这样做

SELECT * FROM Table 
要么。它会降低代码的可读性,因为您无法看到返回的内容,但也会降低可靠性,因为它可能会在没有警告的情况下更改并破坏您的应用程序


我知道一开始似乎有很长的路要走,但老实说,编写单独的SELECT语句来指定他们实际想要返回的字段是一种更好的方法。它还将使您的应用程序运行得更快:-)

有了来自OP的新评论,这已经发生了相当大的变化。如果您所要做的只是从每个表中获取几行样本,则可以轻松利用sys.tables目录视图。这将为数据库中的每个表创建一个select语句。如果您有多个模式,您可以扩展它来添加模式名称

select 'select top 10 * from ' + QUOTENAME(t.name)
from sys.tables t

随着OP的新评论,情况发生了相当大的变化。如果您所要做的只是从每个表中获取几行样本,则可以轻松利用sys.tables目录视图。这将为数据库中的每个表创建一个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)
这将解决问题

您还可以将表\u var\u 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])

如果查询很长,则应将其写入一行而不是多行。

您可以定义字符串变量:

table_var_str = 'Table_name'
st = 'SELECT * FROM ' + table_var_str
query = cursor.execute(st)
这将解决问题

您还可以将表\u var\u 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])

如果查询很长,则应将其写入一行而不是多行。

不能使用参数作为表名。要做到这一点,需要动态sql。这一限制是否仅限于表名,或者是否存在无法传递参数的其他实例(我没有找到任何详细说明这些限制的文档)。参数设计用于谓词中以表示值。这意味着您可以在联接、where子句等中使用它们。它们不是设计用来动态替换对象名的。如果要将参数用作对象名称替换,则必须使用动态sql。如果你沿着这条路走下去,小心别让博比·泰尔斯来看你。感谢你的回应,肖恩。我使用这段代码的目的是为数据库中的每个表提取表名及其关联的列名。我之前不知道数据库中有什么,所以这是我第一次尝试研究数据库内容并理解它包含什么。这个数据库中只有11个表,所以为每个表编写单独的代码以获取列名和数据样本并不困难,但我可以看出,当有更多的表时,这样做是多么的麻烦。甚至可能有更好的方法来实现我的目标。您可以通过查询来查找表名和列名。您不能使用参数作为表名。要做到这一点,需要动态sql。这一限制是否仅限于表名,或者是否存在无法传递参数的其他实例(我没有找到任何详细说明这些限制的文档)。参数设计用于谓词中以表示值。这意味着您可以在联接、where子句等中使用它们。它们不是设计用来动态替换对象名的。如果要将参数用作对象名称替换,则必须使用动态sql。如果你沿着这条路走下去,小心别让博比·泰尔斯来看你。感谢你的回应,肖恩。我使用这段代码的目的是为数据库中的每个表提取表名及其关联的列名。我之前不知道数据库中有什么,所以这是我第一次尝试研究数据库内容并理解它包含什么。这个数据库中只有11个表,所以写单独的co