LTRIM/RTRIM/ISNULL 的操作顺序

Pic*_*llo 2 performance sql-server optimization t-sql query-performance

LTRIMRTRIM结合使用时,您放置的操作顺序是否重要ISNULL?例如,以下面的示例为例,用户可能会在字段中输入一堆空格,但我们将其输入修剪为实际NULL值以避免存储空字符串。

我正在执行以下TRIM操作ISNULL

DECLARE @Test1 varchar(16) = '    '

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

SELECT @Test1
Run Code Online (Sandbox Code Playgroud)

这适当地返回一个真NULL值。现在让我们ISNULL放在外面:

DECLARE @Test2 varchar(16) = '    '

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

SELECT @Test2
Run Code Online (Sandbox Code Playgroud)

这也返回一个NULL值。两者都适用于预期用途,但我很好奇 SQL 查询优化器处理此问题的方式是否有任何不同?

Mic*_*een 6

你的测试是多余的。首先,当给定 NULL 输入时,LTRIM 和 RTRIM 都返回 NULL:

declare @Test1 varchar(16) = null;

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

lft              rgt
---------------- ----------------
NULL             NULL
Run Code Online (Sandbox Code Playgroud)

其次,标准 SQL 在比较字符串时会忽略尾随空格:

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

A     B
----- -----
equal equal
Run Code Online (Sandbox Code Playgroud)

SQL Server 提供了NULLIF函数。这需要两个参数。如果它们不同,将返回第一个。如果它们相等,它将返回 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
Run Code Online (Sandbox Code Playgroud)

您可能仍需要 LTRIM,具体取决于您的输入验证。