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

在Transact-sql子查询中使用变量,sql,tsql,subquery,Sql,Tsql,Subquery,这似乎应该非常简单,因此如果在transact-sql文档页面上可以轻松访问此信息,我提前表示歉意。我搜索了一下自己,但似乎什么也没找到 我正在尝试修改当前在Windows server 2000上运行的transact-sql语句。我想检查另一个数据库中是否存在一个表,然后做一些事情。数据库名称作为字符串参数“@dbName”提供 CREATE PROCEDURE CopyTables @dbName char(4) AS IF EXISTS (SELECT * FROM @dbName

这似乎应该非常简单,因此如果在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语句中使用bare@dbName变量。这样做有特殊的语法吗


提前感谢。

尝试执行以下操作:

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它要求执行语句的用户对其他数据库的信息\u SCHEMA.TABLES具有SELECT访问权


2它的副作用是实际选择行,因此如果您使用读卡器访问结果,则必须调用reader.NextResult或wait reader.NextResultAsync,因为它实际输出SELECT语句的结果,而不是在if EXISTS上下文中执行此操作。

下面的代码应该执行您想要的操作。如前所述,运行查询的帐户将需要查询目标数据库中的信息\u架构的权限

为了进一步验证存储过程,我还建议增加数据库名称参数的长度,并将其声明为nchar或nvarchar而不是char


通过合并这两种解决方案,我们可以得到:

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;

此解决方案要求执行该语句的用户具有对其他数据库的信息\u SCHEMA.TABLES的SELECT访问权限,但它不会像我以前的解决方案那样产生选择行的副作用。

您不能从中选择1吗。。。而不是从…中选择*。。。?这样。@@ROWCOUNT要么是0要么是1。@@ROWCOUNT要么是0要么是1,因为表名必须是唯一的,但您肯定是正确的。您可以选择1而不是选择*。该语句的目的实际上只是为了查看表是否存在,因此两者都可以工作。
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;