映射sqlserver中的字符串列表,如listagg

时间:2018-04-12 08:02:42

标签: sql sql-server

我尝试收集一些字符串,例如' 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来处理它?

2 个答案:

答案 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]

enter image description here

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

<强>结果

enter image description here

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

以便它可以叠加。是的,很难记住stufffor xml pathlistagg(oracle),并导致长sql,我很懒。

如果你有更好的回答,请告诉我,谢谢。