CHARIND变量的CHARINDEX问题

时间:2016-07-27 09:06:32

标签: sql sql-server

DECLARE @MyChar CHAR = NULL

SELECT  CHARINDEX(' ', ISNULL(NULL, '')),
        CHARINDEX(' ', ISNULL(@MyChar, '')),
        CHARINDEX(' ', ISNULL(CONVERT(VARCHAR, @MyChar), ''))

上述查询按顺序返回值010
此结果应为000。这是MS SQL的一个问题,还是有一些我无法理解的功能?

3 个答案:

答案 0 :(得分:2)

我相信这会回答这个问题:

DECLARE @MyChar CHAR = NULL

SELECT  CHARINDEX(' ', ISNULL(NULL, '')) a,
        CHARINDEX(' ', ISNULL(@MyChar, '')) b,
        CHARINDEX(' ', ISNULL(CONVERT(VARCHAR, @MyChar), '')) c

结果:

a           b           c
----------- ----------- -----------
0           1           0

测试值:

SELECT  '|' + @MyChar + '|' a,
        '|' + ISNULL(@MyChar, '') + '|' b,
        '|' + ISNULL(CONVERT(VARCHAR, @MyChar), '') + '|' c

结果:

a    b    c
---- ---- --------------------------------
NULL | |  ||

ISNULL方法返回它接收的第一个参数的数据类型。因为char的最小长度为1,并且如果需要,将使用尾随空格填充值,ISNULL(@MyChar, '')的结果是一个包含单个空格的字符串,因此您得到的结果为1。 / p>

答案 1 :(得分:2)

让我们尝试分两部分来理解第二个问题。

第一部分:SELECT ISNULL(@MyChar, '')

根据MSDN关于ISNULL功能:

  

根据第一个参数的数据类型确定结果表达式的数据类型确定。

所以你的第一个参数@MyChar是Char,它的值是NULL,当你在ISNULL函数中使用它时,第二个参数''(空白)会隐式转换为CHAR,就像这样 -

SELECT CAST('' AS CHAR)

执行此查询时,它会为您提供空格。

现在,当您使用CharIndex

执行实际查询时

SELECT CHARINDEX(' ', ISNULL(@MyChar, '')

您将获得1

答案 2 :(得分:0)

由于您已将变量定义为CHAR并将值指定为NULL,因此它将占用一些空间(2个字节)。因此,如果变量是固定宽度列,并且如果您尝试在其中存储NULL值,那么它将占用与任何其他值相同的空间量。来自here

  

如果我们在表中有NULL值,那就有一种误解   不占用存储空间。事实是,NULL值占用空间    - 2个字节

如果将数据类型更改为varchar(1),然后将值提供为NULL,则会发现结果为0,0,0。因此,如果为变量提供了可变宽度,则NULL不占用空间。

一篇好文章:How does SQL Server really store NULL-s