如果存在,则在TSQL中包括一个有时会丢失的列(如果不存在,则另选一个)

时间:2018-08-08 17:08:41

标签: sql-server tsql ssms

我有一个奇怪的表要处理,有时表会消失。如果该列在那里,则需要使用它。但是,如果没有,我需要解决这个问题并使用替代方法。但是,当我在缺少列的情况下尝试此代码时,SSMS会引发错误(无效的列名'DOB')。如果该色谱柱不存在,并且永远也不会到达其称为色谱柱的那一部分,就不应该发生这种短路吗?那么为什么会出现错误消息?有什么办法吗?预先感谢您的帮助!

choice = 0;

2 个答案:

答案 0 :(得分:2)

如果性能很重要(尤其是许多行和大列),则可能必须使用动态SQL,但是还有另一种使用XML通用能力的方法。

这不会很快,但是可以完全内联(在VIEW或iTVF中)。

SELECT * FOR XML RAW

将生成XML,其中每一行是一个元素<row>,而列是属性。这允许像下面这样的通用方法:

DECLARE @tbl TABLE(ID INT IDENTITY,SomeString VARCHAR(100));
INSERT INTO @tbl VALUES('test1'),('test2');

DECLARE @tbl2 TABLE(ID INT IDENTITY,SomeString VARCHAR(100),DOB DATE);
INSERT INTO @tbl2 VALUES('test1','20180101'),('test2','20180202');

--try this with @tbl and with @tbl2, it works in both cases
SELECT r.value('@ID','int') AS ID
      ,r.value('@DOB','date') AS DOB
FROM
(SELECT * FROM @tbl2 FOR XML RAW, TYPE) A(x)
CROSS APPLY x.nodes('/row') B(r);

FOR XML RAW将生成类似这样的内容

<row ID="1" SomeString="test1" DOB="2018-01-01" />
<row ID="2" SomeString="test2" DOB="2018-02-02" />

...和.nodes('/row')将返回每个<row>作为表的行(派生表)。

如果找不到属性,.value()方法将仅返回NULL

答案 1 :(得分:0)

尝试一下

SELECT 
    SalesClients.ClientName,

CASE WHEN EXISTS(
                SELECT 
                    COLUMN_NAME 
                FROM 
                    INFORMATION_SCHEMA.COLUMNS 
                WHERE 
                    TABLE_NAME = 'SalesClients' 
                    AND COLUMN_NAME = 'DOB'
                )
    THEN 
        SalesClients.DOB
    ELSE
        DATEADD(month, -SalesClients.AgeInMonth, GETDATE()) 
    END AS DOB
FROM 
    dbo.SalesClients AS SalesClients