SQL声明变量

SQL声明变量,sql,sql-server,tsql,variables,Sql,Sql Server,Tsql,Variables,有人能查一下我的陈述吗 DECLARE @tblName varchar(MAX), @strSQL varchar(MAX) SET @tblName ='SELECT DISTINCT o.name as TableName FROM sysobjects o JOIN sysindexes x on o.id = x.id WHERE o.name LIKE ''

有人能查一下我的陈述吗

DECLARE @tblName varchar(MAX), 
        @strSQL varchar(MAX)

SET @tblName ='SELECT DISTINCT o.name as TableName 
                 FROM sysobjects o 
                 JOIN sysindexes x on o.id = x.id  
                WHERE o.name LIKE ''%empty%'''  

SET @strSQL = 'INSERT INTO @tblName VALUES(''trylng'', ''1'')'
EXEC (@strSQL)
我的错误是

味精1087,第15级,第2状态,第1行
必须声明表变量“@tblName”


我不确定你到底想做什么,但我认为你想要这样的东西:

DECLARE @tblName varchar(MAX), @strSQL varchar(MAX)
SET @tblName = 
    (select distinct o.name as TableName 
     from sysobjects o 
     join sysindexes x on o.id = x.id  
     where o.name LIKE '%empty%')
SET @strSQL = 'INSERT INTO [' + @tblName + '] VALUES(''trylng'', ''1'')'
exec (@strSQL)
 SELECT TOP 1 @tblName = t.name
 FROM sys.tables t
 INNER JOIN sys.indexes i on i.object_id = t.object_id  
 WHERE t.name LIKE '%empty%'

尽管如此,这里仍有一些事情需要注意。您需要处理
SELECT DISTINCT
返回除单个记录以外的任何内容的情况。另外,当
@tblName
总是具有相同的值时(因为
WHERE
子句中没有使用变量),我真的不理解构建动态SQL(在
@strSQL
中)的必要性。

@tblName
属性存在于外部作用域中,即“正常”的作用域代码行-但不在您正在那里的字符串中构造的SQL的内部范围内

您需要将行更改为:

SET @strSQL = 'INSERT INTO ' + @tblName + ' VALUES(''trylng'', ''1'')'
然后它就可以正常工作了

另外,您没有提到您的SQL Server版本-但是从SQL Server 2005或更新版本开始,您应该停止使用
sysobjects
sysindexes
-而是使用新的
sys
架构,该架构包含或多或少相同的信息-但更容易获得。将查询更改为:

SET @tblName ='SELECT DISTINCT t.name as TableName 
               FROM sys.tables t
               INNER JOIN sys.indexes i on i.object_id = t.object_id  
               WHERE t.name LIKE ''%empty%'''  
有关新的
sys
schema中的可用内容以及如何充分利用它的更多信息,请参阅

正如“rsbarro”所指出的:将这条SQL语句放在引号中是很奇怪的-您是否也使用
EXEC(…)
执行这条语句??但是,如何将该值分配回
@tblName
属性?真的没有道理

如果要实际运行此查询以获取值,则应具有以下内容:

DECLARE @tblName varchar(MAX), @strSQL varchar(MAX)
SET @tblName = 
    (select distinct o.name as TableName 
     from sysobjects o 
     join sysindexes x on o.id = x.id  
     where o.name LIKE '%empty%')
SET @strSQL = 'INSERT INTO [' + @tblName + '] VALUES(''trylng'', ''1'')'
exec (@strSQL)
 SELECT TOP 1 @tblName = t.name
 FROM sys.tables t
 INNER JOIN sys.indexes i on i.object_id = t.object_id  
 WHERE t.name LIKE '%empty%'

您需要有一个
TOP 1
才能确保只获取一个值-否则此语句可能会失败(如果选择了多行)。

我希望返回的表中只有两列,并且数据类型匹配…@OMGPonies:当然,您是指可插入的列。我遗漏了什么吗?为什么@tblName用单引号括起来?这不就是将它设置为字符串,而不是表名吗?不,我是指第二条语句。它不应该读不带引号的
SET@tblName=SELECT DISTINCT t.name…
?@strSQL的写入方式将有一个值
INSERT到selectdistinct.Name作为TableName…
。在我看来,这将是无效的,不是吗?@rsbarro:啊,好吧,不确定-我假设OP也将使用
EXEC(…)
执行SQL语句。如果没有-那么你是绝对正确的,它不会工作!酷。现在已经很晚了,我想我不是看到了一些新的语法,就是失去了理智……=]另一个问题…为什么我们需要使用连接到SYS.INDEXES,因为在与SYS.tables中的“WHERE”匹配的表列表中,只有一个注意事项:一般来说,将名称合并到动态脚本中更安全,比如:
'INSERT-into'+QUOTENAME(@tblName)+'.
,而不是简单地用方括号括起来。