我尝试收集一些字符串,例如' 1,2,3'到' a,b,c'与anwser:
charindex
create function [dbo].[fn_enum2str]
(
@enum as varchar(1000),
@table_name as varchar(100),
@origin_field as varchar(100),
@target_field as varchar(100)
)
as
begin
declare @result varchar(1000)
declare @sqlstr nvarchar(1000)
set @sqlstr = 'set @result = ('
set @sqlstr = @sqlstr + 'select stuff('
set @sqlstr = @sqlstr + '(select '','' + ' +@target_field+ ' from ' + @table_name
set @sqlstr = @sqlstr + ' where '','+@enum+','' like ''%,''+cast('+@origin_field+' as varchar)+'',%'' for xml path(''''))'
set @sqlstr = @sqlstr + ',1,1,''''))'
exec(@sqlstr)
return @result
end
做得好。但我想创建一个更常见的功能,这样我就可以转换成任何关系。
我尝试了一个功能:
select dbo.fn_enum2str(a.uids,'sys_user','u_id', 'realname') from my_table a
--output 'a,b,c'
如果你知道,它会错误地发生错误,它不允许在函数中执行动态sql。
我想
{
"type": "type-A",
"value": "{'propA': 'type-A specific element', 'propA2': 'another typeA specific element'}"
}
所以,在我的问题中,我如何创建一个函数或一个proc来处理它?
答案 0 :(得分:0)
假设你有SQL-SERVER2016,你可以像这样使用string_split:
测试数据
CREATE TABLE [dbo].[stringlist]([Numbers] [nvarchar](50) NULL)
Insert into dbo.Stringlist(numbers)
values('1,2,3,4,5,10')
SQL函数
alter function dbo.HinkyBase26( @Value as varchar(250) ) returns VarChar(250) as
begin
--declare @Value as varchar(50) = '13,14,1,2,5,14'
-- Notes: 'A' = 0. Negative numbers are not handled.
declare @Result as VarChar(250) = '';
declare @stringsplit table (numbers nvarchar(50),Letters varchar(1))
insert into @stringsplit(numbers,Letters)
select numbers = @Value ,CHAR(64 + value) as Letters from string_split(@Value,',')
select @Result = Letter from (
select numbers,Letter = STUFF((Select ', ' + Letters
from @stringsplit b
where b.numbers = a.numbers
FOR XML PATH('')),1,2,'')
from @stringsplit a
group by numbers
)z
return @Result
end
执行功能
SELECT TOP (1000) [Numbers],dbo.HinkyBase26(Numbers)
FROM [LegOgSpass].[dbo].[stringlist]
SQL存储过程
Create PROC dbo.usp_convertnumberstostring
@stringvalue nvarchar(250)
AS
BEGIN
Create table #stringsplit (numbers nvarchar(50),Letters varchar(1))
insert into #stringsplit(numbers,Letters)
SELECT Numbers = @stringvalue,CHAR(64 + value) as Letters
from string_split(@stringvalue,',')
select numbers,Letter = STUFF((Select DISTINCT ', ' + Letters
from #stringsplit b
where b.numbers = a.numbers
FOR XML PATH('')),1,2,'')
from #stringsplit a
group by numbers
drop table #stringsplit
END
执行SP
DECLARE @RC int
DECLARE @stringvalue nvarchar(250) = '1,5,6'
-- TODO: Set parameter values here.
EXECUTE @RC = [dbo].[usp_convertnumberstostring]
@stringvalue
GO
<强>结果强>
SQL脚本
Create table #stringsplit (numbers nvarchar(50),Letters varchar(1))
insert into #stringsplit(numbers,Letters)
SELECT Numbers,CHAR(64 + value) as Letters
FROM [LegOgSpass].[dbo].[stringlist] a
cross apply string_split(numbers,',')
select numbers,Letter = STUFF((Select DISTINCT ', ' + Letters
from #stringsplit b
where b.numbers = a.numbers
FOR XML PATH('')),1,2,'')
from #stringsplit a
group by numbers
Drop table #stringsplit
答案 1 :(得分:0)
CREATE function [dbo].[fn_enum2str]
(
@enum as varchar(1000),
@table_name as varchar(100)
)
returns varchar(1000)
as
begin
declare @result varchar(1000)
if @enum is null
return ''
if @table_name = 'sys_user'
set @result = (
select stuff(
(
select ',' + realname from sys_user
where ','+@enum+',' like '%,'+cast(u_id as varchar(10))+',%' for xml path('')
),1,1,''
)
)
if @table_name = 'sys_attachment'
set @result = (
select stuff(
(
select ',/' + filepath from sys_attachment
where ','+@enum+',' like '%,'+cast(aid as varchar(10))+',%' for xml path('')
),1,1,''
)
)
return @result
end
GO
只有办法处理它我能想到的,切换哪个sql将由一个标志执行。当其他关系出现时,将其添加到交换机列表中。
select
dbo.fn_enum2str(a.uids, 'sys_user') as names,
dbo.fn_enum2str(a.attachids, 'sys_attachment') as filepaths
from my_table a
以便它可以叠加。是的,很难记住stuff
或for xml path
或listagg(oracle)
,并导致长sql,我很懒。
如果你有更好的回答,请告诉我,谢谢。