web-dev-qa-db-ja.com

LTRIM / RTRIM / ISNULLでの操作の順序

LTRIMと組み合わせて使用​​する場合、RTRIMおよびISNULLを配置する操作の順序は重要ですか?たとえば、ユーザーがフィールドに大量のスペースを入力する可能性がある次の例を考えますが、空の文字列を格納しないように、入力を実際のNULL値にトリミングします。

TRIM外でISNULL操作を実行しています:

DECLARE @Test1 varchar(16) = '    '

IF LTRIM(RTRIM(ISNULL(@Test1,''))) = ''
BEGIN
    SET @Test1 = NULL
END

SELECT @Test1

これにより、真のNULL値が適切に返されます。次に、ISNULLを外側に配置します。

DECLARE @Test2 varchar(16) = '    '

IF ISNULL(LTRIM(RTRIM(@Test2)),'') = ''
BEGIN
    SET @Test2 = NULL
END

SELECT @Test2

これはNULL値も返します。どちらも意図した使用法でうまく機能しますが、SQLクエリオプティマイザーがこれを処理する方法に違いがあるかどうか知りたいですか?

2
PicoDeGallo

テストは冗長です。最初に、NULL入力を指定すると、LTRIMとRTRIMの両方がNULLを返します。

declare @Test1 varchar(16) = null;

select
    lft = LTRIM(@test1),
    rgt = RTRIM(@Test1);

lft              rgt
---------------- ----------------
NULL             NULL

次に、標準SQLは文字列を比較するときに末尾のスペースを無視します。

select
    A =case
        when '' = '   ' then 'equal'
    end,
    B = case
        when '  ' = '     ' then 'equal'
    end;

A     B
----- -----
equal equal

SQL Serverは [〜#〜] nullif [〜#〜] 関数を提供します。これは2つのパラメーターを取ります。それらが異なる場合、最初のものが返されます。それらが等しい場合、NULLを返します。これはあなたの要件に対処すると思います。

declare @Test1 varchar(16) = '    ';

select
    first = nullif(@Test1, '');

set @Test1 = NULL;

select
    second = nullif(@Test1, '');

set @Test1 = 'some value';

select
    third = nullif(@Test1, '');

first
----------------
NULL

second
----------------
NULL

third
----------------
some value

入力検証によっては、依然としてLTRIMが必要な場合があります。

5
Michael Green

SQL Serverは関数を完全に評価します。最初の例は次と同等です。

DECLARE @Test1 varchar(16) = '    '

SET @Test1 = ISNULL(@Test1,'')
SET @Test1 = RTRIM(@Test1)
SET @Test1 = LTRIM(@Test1)

IF @Test1 = ''
BEGIN
    SET @Test1 = NULL
END

SELECT @Test1

ISNULLは最初のNULL以外の値を返すだけなので、関数は@Test1を返すだけです。次に、空白を削除します。これらの順序を逆にすると、ISNULLは常にFALSEと評価されるため、まったく同じように動作します。

説明されている目的では、順序はほとんど関係ありません。 ISNULL関数は、空白のトリミングについてドントケアの場合にのみ必要で、逆も同様です(LTRIM/RTRIMが何もしない場合) NULL値に)。

4
Dan