这看起来应该非常简单,所以如果在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变量。这样做有特殊的语法吗?
提前致谢。
答案 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
的访问权限,但它没有选择行的副作用,就像我之前的解决方案一样。