【问题标题】:Joining a table based on @@servername基于@@servername 加入表
【发布时间】:2021-07-13 21:53:41
【问题描述】:

如何使用条件语句(或任何其他解决方案)来确定是否引用可能存在或不存在的数据库?

我创建了一个多服务器 查询,它可以正确地从两台不同服务器上的同一数据库中返回数据。但是,Server2 包含一个在 Server1 上不存在的辅助数据库。如果存在,我还需要从该数据库返回一个值。

以下 Case 语句用作 Server1 的列,因为引用的数据库存在于该服务器上。当针对 Server2 运行时,我预计第二个 When 子句甚至不会被评估,但我收到一个引用不存在的数据库的“无效对象名称”错误。

CASE 
   WHEN @@SERVERNAME = 'Server2' 
      THEN 'N/A'
   WHEN @@SERVERNAME = 'Server1' 
      THEN (SELECT Column1 FROM databasename.Table1
            WHERE Column1 = a.column1) 
END AS 'AliasName'

自我注意:似乎 when 子句即使未通过逻辑测试部分也会被评估。

[如果不明显,a.column1 引用指向主(外部)查询]

有没有人有创造性的解决方案来解决这个障碍?

【问题讨论】:

  • SQL 在执行点被解析和编译。如果您在尝试运行该语句时引用了一个不存在的对象,它将失败。即使该语句/表达式永远无法执行也没关系,整个语句必须是有效的。
  • 如果您需要在不同的环境中运行不同的语句,您要么需要确保您的应用程序/实例具有针对所述环境的不同语句,要么使用动态 SQL 以便根据环境。
  • T-SQL 实际上是一种编译语言,即使编译是即时进行的,所以在查询中包含不存在的对象通常不起作用——存储过程除外, where 编译将被推迟,但如果对象不存在,即使在执行时编译也会失败。使用动态 SQL(如果这是一次性的)或重写此查询以使用始终存在但不会在 Server2 上返回任何内容的视图或函数。
  • 一种选择是创建一个存储过程或一个视图来执行查询,因此在两个服务器之间有所不同,但可以从代码中以相同的方式调用。

标签: sql-server conditional-statements


【解决方案1】:

根据我得到的反馈,这是我自己问题的答案:

  1. SQL 是一种编译语言。我知道这一点,但没有想到它的含义。查询中的所有对象都必须实际存在,即使查询的这一部分可能并未实际运行。
  2. 最佳解决方案是在特定于该数据库的每台服务器上创建视图或存储过程。它们应该返回相同数量的列。例如:如果服务器 1 返回的数据在服务器 2 上不存在,则来自服务器 2 的 SP 应包含数据的空白或空列。然后从多服务器连接中调用每个以返回并加入来自每个数据库的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 2018-01-24
    • 2014-02-10
    • 1970-01-01
    • 2010-12-08
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多