在Transact-sql中使用变量存在子查询

时间:2015-08-31 16:34:09

标签: sql tsql subquery

这看起来应该非常简单,所以如果在transact-sql文档页面上可以轻松访问这些信息,我会提前道歉。我自己搜索,但似乎找不到任何东西。

我正在尝试修改当前在我们的Windows Server 2000上运行的transact-sql语句。我想检查另一个数据库中的表是否存在,然后做一堆东西。数据库名称以字符串参数“@dbName”

的形式给出
CREATE  PROCEDURE CopyTables
@dbName char(4)
AS

IF EXISTS (SELECT * FROM  @dbName.INFORMATION_SCHEMA.TABLES  WHERE 
           TABLE_NAME = N'MainTable')

BEGIN
     --Do Stuff

在当前状态下,它不喜欢在select语句中使用裸@dbName变量。这样做有特殊的语法吗?

提前致谢。

3 个答案:

答案 0 :(得分:2)

以下代码应该做你想要的。如前所述,运行查询的帐户需要具有查询目标数据库中的INFORMATION_SCHEMAs的权限。

为了使您的存储过程能够面向未来,我还建议增加数据库名称参数的长度,并将其声明为nchar或nvarchar而不是char。


CREATE PROCEDURE CopyTables
@dbName char(4)
AS
DECLARE
  @SQLStr nvarchar (max),
  @Params nvarchar (max),
  @Count tinyint;
SET
  @Count = 0;
SET @SQLStr = N'SELECT @qCount = 1 FROM [' + @dbName + N'].INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N''MainTable''';
SET @Params = N'@qdbName char (4), @qCount tinyint OUTPUT';
EXECUTE sp_executesql @SQLStr, @Params, @qdbName = @dbName, @qCount = @Count OUTPUT;
IF @Count = 1
BEGIN
     --Do Stuff
END; -- if
GO

答案 1 :(得分:1)

尝试执行以下操作:

DECLARE @dbName NVARCHAR(MAX) = 'master', @TableName NVARCHAR(MAX) = N'spt_monitor';
DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM [' + @dbName + N'].INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ''' + REPLACE(@TableName,N'''',N'''''') + N'''';

SET NOCOUNT OFF;
EXEC(@sql);

IF @@ROWCOUNT > 0 BEGIN;
    -- DO STUFF
    SELECT NULL;
END;

此解决方案存在一些缺点:

1)要求执行该语句的用户SELECT访问其他数据库的INFORMATION_SCHEMA.TABLES

2)它具有实际选择行的副作用,因此如果您使用阅读器访问结果,则必须致电reader.NextResult()await reader.NextResultAsync(),因为它实际上是输出SELECT语句的结果,而不是在IF EXISTS上下文中进行。

答案 2 :(得分:0)

通过合并这两个解决方案,我们得到了这个:

DECLARE @dbName NVARCHAR(MAX) = 'master', @TableName NVARCHAR(MAX) = N'spt_monitor';
DECLARE @sql NVARCHAR(MAX) = N'SELECT @count = COUNT(*) FROM [' + @dbName + N'].INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ''' + REPLACE(@TableName,N'''',N'''''') + N'''';
DECLARE @Count INT;

EXECUTE sp_executesql @sql, N'@Count INT OUTPUT', @Count OUTPUT;

IF @Count > 0 BEGIN;
    -- Do stuff
    SELECT 'the table exists';
END ELSE BEGIN;
    -- Do stuff
    SELECT 'the table does not exist';
END;

此解决方案要求执行该语句的用户具有SELECT对其他数据库INFORMATION_SCHEMA.TABLES的访问权限,但它没有选择行的副作用,就像我之前的解决方案一样。