我有一个像这样的变量
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 WHEN
和LEFT
函数时,如何保留前导零值?
谢谢。
答案 0 :(得分:1)
在您的CASE语句中,THEN
和ELSE
语句的结果数据类型应该相同。但是在您的查询中,ELSE块的返回结果为-1
,因此考虑到case语句的输出为INT
,因此从结果中删除前导零并返回为整数,这是您所期望的输出仅作为varchar。
因此,如果将ELSE
块修改为ELSE '' END
或ELSE '-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);
结果:
答案 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