防止在SQL Server中使用case when和子字符串时删除前导零

时间:2019-03-30 10:47:16

标签: sql-server stored-procedures

我有一个像这样的变量

DECLARE @CODE NVARCHAR(10) = '09000:09502';

我需要将@CODE变量分成两个变量,然后将它们插入临时表中以进行批量插入。

但是当我在select语句中使用'CASE WHEN'时,分割后的值将删除前导零,'09000'将变为'9000'(似乎这些值被视为数字而不是字符串)。即使使用了CAST功能,它仍然无法正常工作。

我使用以下代码进行一些测试:

DECLARE @CODE   VARCHAR(10) = '09000:09502';
DECLARE @Split1 VARCHAR(10) = '';
DECLARE @Split2 VARCHAR(10) = '';

SET @Split1 = CAST((CASE WHEN CHARINDEX(':', @CODE) > 0 
                            THEN LEFT(@CODE, CHARINDEX(':', @CODE) - 1)
                            ELSE -1 
                    END) AS VARCHAR(20))
SET @Split2 = LEFT(@CODE, 5);

PRINT(@Split1);
PRINT(@Split2);

我得到的输出是:

9000
09000

当我不使用'CASE WHEN'时,可以得到想要的值,但是我使用'CASE WHEN'时,前导零将被删除。

在SQL Server存储过程中使用CASE WHENLEFT函数时,如何保留前导零值?

谢谢。

4 个答案:

答案 0 :(得分:1)

在您的CASE语句中,THENELSE语句的结果数据类型应该相同。但是在您的查询中,ELSE块的返回结果为-1,因此考虑到case语句的输出为INT,因此从结果中删除前导零并返回为整数,这是您所期望的输出仅作为varchar。

因此,如果将ELSE块修改为ELSE '' ENDELSE '-1' END,它将返回预期结果varchar(10)。

答案 1 :(得分:1)

CASE语句的所有分支都必须返回相同的数据类型。
当您在else部分返回-1时,此CASE返回的值将转换为整数,因此09000将变为9000
您可以将-1更改为'-1'

DECLARE @CODE    VARCHAR(11) = '09000:09502';
DECLARE @Split1  VARCHAR(10) = '';
DECLARE @Split2  VARCHAR(10) = '';
SET @Split1      = CASE 
                     WHEN CHARINDEX(':',@CODE)>0 THEN LEFT(@CODE, CHARINDEX(':', @CODE)-1)
                     ELSE '-1' 
                   END
SET @Split2      = RIGHT(@CODE, LEN(@CODE)-CHARINDEX(':', @CODE));
PRINT(@Split1);
PRINT(@Split2);

通过这种方式,您不需要CAST()函数。
另外,您将@CODE声明为VARCHAR(10),这将截断最后一个字符。
更改为VARCHAR(11)
另外,我猜您想为@Split2分配5个字符,分别为@CODE right 个字符,而不是代码中的左侧字符。

请参见demo

答案 2 :(得分:1)

正如@Arulkumar所述,这是因为case语句返回一个整数。我简化了您的代码:

DECLARE @CODE    VARCHAR(10) = '09000:09502';
DECLARE @Split1  VARCHAR(10) = '';
DECLARE @Split2  VARCHAR(10) = '';

DECLARE @ColonIndex INT = CHARINDEX(':',@CODE)

SET @Split1      = CASE WHEN @ColonIndex > 0 THEN LEFT(@CODE, @ColonIndex-1)
                        ELSE '-1' END
SET @Split2      = LEFT(@CODE, 5);

PRINT(@Split1);
PRINT(@Split2);

结果:

enter image description here

答案 3 :(得分:0)

您可能应该只使转换不受数值影响,下面是一些测试用例:第二个查询是您可以将In [777]: timeit (x@x.transpose(0,2,1)).shape 18.4 µs ± 181 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) INSERT两列使用的查询适合

UPDATE