计算列不包含其中一个值

时间:2016-02-18 15:48:02

标签: sql sql-server sql-server-2008-r2

我试图创建一个计算列,以便在可空列上具有唯一索引,忽略NULL行 1 。我编写了这个测试用例:

SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
    SELECT TEST_ID, CODE,
    ISNULL(CODE, CONVERT(VARCHAR, SPACE(10)) + CONVERT(VARCHAR, TEST_ID)) AS UNIQUE_CODE
    FROM (
        SELECT 1 AS TEST_ID, 'ABCDEFGHIJ' AS CODE
        UNION ALL
        SELECT 2, 'XYZ'
        UNION ALL
        SELECT 3, NULL
    ) TEST
) X;

CODE不为null时,它按预期工作,但当CODE为空时,我只获得一个空格字符串(即,缺少尾随的TEST_ID):

TEST_ID | CODE       | UNIQUE_CODE | HEX
--------+------------+-------------+-----------------------
      1 | ABCDEFGHIJ | ABCDEFGHIJ  | 0x4142434445464748494A
      2 |  XYZ       | XYZ         | 0x58595A
      3 | NULL       |             | 0x20202020202020202020

有趣的是,我已经在另一张桌子上成功使用了这项技术,但我无法发现差异:

CREATE TABLE SOME_OTHER_TABLE (
    SOME_OTHER_TABLE_ID INT IDENTITY(1, 1) NOT NULL,
    NOMBRE VARCHAR(50),

    -- This works just fine:
    NOMBRE_UNICO AS ISNULL(NOMBRE, CONVERT(VARCHAR, SPACE(50)) + CONVERT(VARCHAR, SOME_OTHER_TABLE_ID)),

    CONSTRAINT SOME_OTHER_TABLE_PK PRIMARY KEY (SOME_OTHER_TABLE_ID)
);

我错过了什么?

1 )这是SQL Server 2005的一种解决方法,由于过滤了索引,在以后的版本中不再需要它。

3 个答案:

答案 0 :(得分:3)

您可以使用" 3"

SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
    SELECT TEST_ID, CODE,
    ISNULL(CODE, CONVERT(VARCHAR(20), SPACE(10)) + CONVERT(VARCHAR(20), TEST_ID)) AS UNIQUE_CODE
    FROM (
        SELECT 1 AS TEST_ID, cast('ABCDEFGHIJ' as varchar(20)) AS CODE
        UNION ALL
        SELECT 2, 'XYZ'
        UNION ALL
        SELECT 3, NULL
    ) TEST
) X;

enter image description here

'ABCDEFGHIJ'(联合列表中的第一个值)正好是10个字符,此列是IsNull的第一个参数。因此,IsNull结果需要10个字符作为大小。这对于空间来说足够了。用'ABCDEFGHIJKLMNOPQR'替换这个常量也可以解决问题。

答案 1 :(得分:1)

看起来SQL正试图帮助定义内部查询中的列长度。通过转换/转换为特定大小,这可以解决问题。在UNIQUE_CODE字段超过此值后,返回的值将限制为列的大小。

SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
    SELECT TEST_ID, CODE,
    ISNULL(CODE, CONVERT(VARCHAR, SPACE(10)) + CONVERT(VARCHAR, TEST_ID)) AS UNIQUE_CODE
    FROM (
        SELECT 1 AS TEST_ID, CONVERT(VARCHAR(50), 'ABCDEFGHIJ') AS CODE
        UNION ALL
        SELECT 2, 'XYZ'
        UNION ALL
        SELECT 3, NULL
    ) TEST
) X;

答案 2 :(得分:1)

你可以运行以下代码来找出原因吗?

这失败了:

declare @a char(20)
set @a=null

declare @b char(10)
set @b='aaaaaa'

select isnull(@a,convert(char(10),space(10)+@b))

这有效:

declare @a char(20)
set @a=null

declare @b char(10)
set @b='aaaaaa'

select isnull(@a,convert(char(30),space(10)+@b))