为什么我不能使用 CASE 语句来查看列是否存在而不是从中选择?

Car*_*nke 18 sql-server t-sql

为什么这样的事情不起作用?

SELECT
CASE 
WHEN NULLIF(COL_LENGTH('Customers', 'Somecol'), '') IS NULL THEN NULL
ELSE Somecol
END AS MyTest
FROM Customers;
Run Code Online (Sandbox Code Playgroud)

我只是检查该列是否存在,但是,SQL Server 抱怨Somecol不存在。在单个语句中是否有替代方法?

And*_*y M 45

下面的查询使用相同的想法,在这个惊人的答案ypercube

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM dbo.Customers
) AS x;
Run Code Online (Sandbox Code Playgroud)

它是这样工作的:

  • 如果dbo.Customers有一个名为 的列SomeCol,则SomeColinSomeCol AS MyTest将解析为dbo.Customers.SomeCol

  • 如果表没有这样的列,引用仍然有效,因为现在它将被解析为dummy.SomeColdummy可以在该上下文中引用列。

您可以通过这种方式指定多个“备用”列。诀窍是不要为此类列使用表别名(在大多数情况下这是一种令人不悦的做法,但在这种情况下,省略表别名有助于您解决问题)。

如果该表用于连接,而另一个表有自己的SomeCol,则您可能需要在将上述查询用于连接之前将其用作派生表,以保持该技巧有效,如下所示:

SELECT ...
FROM
(
  SELECT x.*
  FROM (SELECT NULL AS SomeCol) AS dummy
  CROSS APPLY (
    SELECT
      ID,
      SomeCol AS MyTest
    FROM dbo.Customers
  ) AS x
) AS cust
INNER JOIN ...
;
Run Code Online (Sandbox Code Playgroud)


Mar*_*son 9

一种方法是检查列是否存在,然后根据该列是否存在构建动态 SQL。

如果没有动态 SQL,SQL Server 甚至会在执行语句之前尝试评估该列是否存在,从而导致错误。

但是,这确实意味着您将有 2 个查询要编写并且将来可能会更改。但我不相信你真的应该针对SELECT可能不存在的列的陈述。

declare @SQL varchar(max)

If exists (select 1 from sys.columns where Name = N'NameOfColumn' and object_id=object_id(N'yourTableName'))
begin
set @SQL = 'select ID, NameOfColumn from yourTableName'
exec(@sql)
end
else
begin
Print 'Column does not exist'
end
Run Code Online (Sandbox Code Playgroud)