【发布时间】:2019-02-12 11:03:30
【问题描述】:
我必须将数字代码转换为字母代码,如下所示:
1234 -> ABCD
其中 0 = 0、1 = A、2 = b 等等。
这是我的功能和使用方法:
Create function dbo.DecodeNumToChar
(
@change varchar(10),
@foo varchar(10)
) returns varchar(10)
as
begin
DECLARE @II int = 1,
@result varchar(10)
;WITH x AS
(
SELECT @II as ii, STUFF(@foo,@II,1,SUBSTRING(@change,CAST(SUBSTRING(@foo,@II,1) AS INT)+1,1)) AS AA
UNION ALL
--SELECT @II+1
SELECT ii+1, STUFF(AA,ii+1,1,SUBSTRING(@change,CAST(SUBSTRING(@foo,ii+1,1) AS INT)+1,1)) AS AA
FROM x
where ii+1 <= LEN(@foo)
)
select top 1 @result = AA from x order by ii desc
return @result
end
--------------------------------------------
select brand_code, dbo.DecodeNumToChar('0ABCDEFGHI', brand_code)
from (VALUES('1234'),('5834'),('9905'),('0250')) as t(brand_code)
此函数运行良好,但在生产数据库中我们无权创建函数。
我试过把这个函数变成这样的 CTE
declare @change varchar(9) = 'ABCDEFGHI'
DECLARE @II int = 0
;WITH x AS
(
SELECT TOP (10) n = ROW_NUMBER() OVER (ORDER BY Number)
FROM master.dbo.spt_values ORDER BY Number
),
innerCTE as
(
SELECT x.n, SUBSTRING(t.brand_code, x.n, 1) chnum,
case SUBSTRING(t.brand_code, x.n, 1)
when '0' then '0'
else char(65-1+SUBSTRING(t.brand_code, x.n, 1))
end chalfa, t.brand_code
FROM x INNER JOIN (VALUES('1234'),('5834'),('9905'),('0250')) as t(brand_code)
ON x.n <= LEN(t.brand_code)
),
CTE as
(
select n, chnum, chalfa, brand_code, stuff(brand_code, n, 1, chalfa) as code
from innerCTE
union all
select n+1, chnum, chalfa, brand_code, STUFF(code, n+1, 1, chalfa) as code
from cte
where n+1 <= LEN(cte.brand_code)
)
--select * from innerCTE
select * from CTE;
或者像这个例子一样使用 CROSS APPLY:Example_1
或使用带有 PIVOT 的 CROSS APPLY,例如:Example_2
但是我的 SQL 经验很少,我无法得到正确的结果。
我想要这个:
brand_code decoded_code
1234 ABCD
5834 EHCD
9905 II0E
0250 0BE0
谢谢
【问题讨论】:
-
我只使用 10 个嵌套的
REPLACE假设您不在一个确实有DECODE的版本上 -
Martin 的提示是最简单直接的。
-
看起来是使用CLR Integration的好时机
-
@Jodrell 你绝对是对的,但我不知道我是否可以在 PROD 环境中使用
标签: sql-server tsql common-table-expression cross-apply