0

私は 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 では実行できないことですか?

ああ、もう 1 つ、Access でテーブルをリンク テーブルとして追加し、そこでクエリを実行すると、すべて正常に動作しますが、この状況では Access が SQL Server ではなく評価を行うと思います。

編集: (解決済み) バージョン 2012 より前のバージョンでは、Case ステートメントを使用する必要があるようです。いつものように、stackoverflow ユーザーの意見に感謝します。yall は素晴らしいです!

4

1 に答える 1

3

CASE 式を使用できます。

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.IpPbxCDRdbo.IpPbxCDRIpPbxCDRdbo


補遺

それが当てはまるかどうかはわかりませんが、上記は onOriginationNumberにある可能性のあるインデックスを使用しません。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 を実行したときの実行計画 (上) と最初のクエリ (下) を比較したものです。

ここに画像の説明を入力

テストスキーマ

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);
于 2013-10-21T13:05:25.560 に答える