是否可以在IIF声明的第一部分中使用类似的声明?

时间:2013-10-21 12:53:29

标签: sql sql-server

我正在研究SQL服务器(2008),似乎无法在IIF语句的布尔部分中使用LIKE语句。

以下查询正确运行,因此我的LIKE语句的语法似乎很好:

SELECT *
FROM dbo.IpPbxCDR
WHERE dbo.IpPbxCDR.OriginationNumber LIKE '+31%'

但是在运行以下查询时:

SELECT *
FROM dbo.IpPbxCDR
WHERE IIF(dbo.IpPbxCDR.OriginationNumber LIKE '+31%','0' + Right([dbo.IpPbxCDR].[OriginationNumber],9), Replace([dbo.IpPbxCDR].[OriginationNumber],'+','00')) = '0201234567'

我收到以下错误:关键字'LIKE'附近的语法不正确。

我做错了什么,或者是我在SQL Server 2008上无法做到的事情?

哦,另外一件事,如果我将表作为链接表添加到Access中,并在那里运行查询,一切正常,但我认为在这种情况下Access执行评估而不是SQL Server。

编辑:(已解决)好吧,看起来在版本2012之前需要使用Case语句。一如既往,感谢您输入stackoverflow用户,yall太棒了!

1 个答案:

答案 0 :(得分:2)

您可以使用CASE Expression

SELECT  *
FROM    dbo.IpPbxCDR
WHERE   CASE WHEN dbo.IpPbxCDR.OriginationNumber LIKE '+31%'
            THEN '0' + Right(dbo.IpPbxCDR.OriginationNumber,9)
            ELSE Replace(dbo.IpPbxCDR.OriginationNumber,'+','00'))
        END = '0201234567';

注意我已将[dbo.IpPbxCDR]替换为dbo.IpPbxCDR,因为这样会在{dbo.IpPbxCDR中找到一个名为IpPbxCDR的表,而不是dbo 1}}架构。


<强>附录

我不知道它是否适用,但上面不会使用你在OriginationNumber上可能有的任何索引,如果你在select中使用表达式,但在where子句中使用它是很好的它是否可能导致性能问题。要使用索引,您可以按如下方式重写:

DECLARE @Number VARCHAR(10) = '0201234567';

SELECT  *
FROM    dbo.IpPbxCDR
WHERE   OriginationNumber = CASE WHEN @Number LIKE '00%' THEN STUFF(@Number, 1, 2, '+') ELSE STUFF(@Number, 1, 1, '+31') END;

这对常量进行了所有操作,因此它只执行一次,而不是在每一行上执行函数。为了进行比较,这是运行ablve(顶部)与第一个查询(底部)相比的执行计划:

enter image description here

测试架构

CREATE TABLE dbo.IpPbxCDR (OriginationNumber VARCHAR(15));
INSERT dbo.IpPbxCDR (OriginationNumber)
VALUES ('+31201234567'), ('+3469694535'), ('+44208979754');

INSERT dbo.IpPbxCDR (OriginationNumber)
SELECT  TOP 10000 '+312012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b
UNION ALL
SELECT  TOP 10000 '+342012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b
UNION ALL
SELECT  TOP 10000 '+332012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b

CREATE NONCLUSTERED INDEX IX_IpPbxCDR_OriginationNumber ON dbo.IpPbxCDR (OriginationNumber);