1

谁能告诉我为什么这不起作用?

if ((select @@servername) = 'ServerA')
begin
    use DatabaseA
    select top 5 * from dbo.SignUPRequest
end
else if ((select @@servername) = 'ServerB')
begin
    use DatabaseB
    select top 5 * from dbo.SignUPRequest
end

当我在 ServerA 上运行它时,我收到一条消息,指出 DatabaseB 在 ServerA 上不存在,但它不存在,但我不明白为什么如果第二个 if 评估为 false,它为什么要尝试读取。

消息 911,级别 16,状态 1,第 8 行
数据库“DatabaseB”不存在。确保输入的名称正确。

4

2 回答 2

2

代码在运行之前被解析。当它被解析时,SQL Server 检查它是否可以访问代码中的所有内容,它无法访问其他服务器上存在的数据库,因此运行代码的解析步骤失败。结果,您会收到显示的错误消息。

如果你想解决这个问题,你可以将 IF 块中的代码作为动态执行的代码(我总是觉得这有点像 hack/workaround)。

DECLARE @sql NVARCHAR(4000);
if ((select @@servername) = 'ServerA')
begin
    SET @sql = 'use DatabaseA; select top 5 * from dbo.SignUPRequest;'
end
else if ((select @@servername) = 'ServerB')
begin
    SET @sql = 'use DatabaseB; select top 5 * from dbo.SignUPRequest'
end

EXEC (@sql)

因此,这里发生的情况是,您推迟了使用适当数据库为服务器运行时间的代码的解析和运行,就像最后的 EXEC 语句所做的那样。

更新

根据下面的附加评论,您还可以将其重写为:

DECLARE @sql NVARCHAR(4000);
if ((select @@servername) = 'ServerA')
begin
    select top 5 * from DatabaseA.dbo.SignUPRequest;
end
else if ((select @@servername) = 'ServerB')
begin
    select top 5 * from DatabaseB.dbo.SignUPRequest;
end

因此,USE <database-name>您还可以在 select 语句中更全面地限定表的名称,而不是在开头添加 a。如果你只有一行 SQL 来处理这可能会更有效。

于 2012-08-04T21:11:49.973 回答
1

您在编译查询时收到错误,而不是在执行时。您可以执行语句以exec将它们分批获取,仅当数据库存在时才编译。

if ((select @@servername) = 'ServerA')
begin
   exec(N'use DatabaseA
          select top 5 * from dbo.SignUPRequest')
end
else if ((select @@servername) = 'ServerB')
begin
   exec(N'use DatabaseB
          select top 5 * from dbo.SignUPRequest')
end
于 2012-08-04T21:10:11.027 回答