SQL Server 存储过程循环通过逗号分隔的单元格 [英] SQL Server stored procedure looping through a comma delimited cell

查看:35
本文介绍了SQL Server 存储过程循环通过逗号分隔的单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如何获取我的一个单元格中存在的逗号分隔字符串的值.

I am trying to figure out how to go about getting the values of a comma separated string that's present in one of my cells.

这是我当前试图在我的存储过程中找出的查询:

This is the query I current am trying to figure out in my stored procedure:

SELECT 
   uT.id, 
   uT.permissions
FROM 
   usersTbl AS uT
INNER JOIN 
   usersPermissions AS uP 
   /*Need to loop here I think?*/
WHERE 
   uT.active = 'true'
AND 
   uT.email = 'bbarker@thepriceisright.com'

usersPermissions 表如下所示:

因此 usersTbl 表中的一行对于 permissions 来说如下所示:

And so a row in the usersTbl table looks like this for permissions:

1,3

我需要找到一种方法来遍历该单元格并获取每个数字并将名称 **** 放在我为 usersTbl.permissions 返回的结果中.

I need to find a way to loop through that cell and get each number and place the name ****, in my returned results for the usersTbl.permissions.

所以不要返回这个:

Name    | id   | permissions | age |
------------------------------------
Bbarker | 5987 | 1,3         | 87  |

它需要返回:

Name    | id   | permissions | age |
------------------------------------
Bbarker | 5987 | Read,Upload | 87  |

实际上只是将 1,3 替换为 Read,Upload.

Really just replacing 1,3 with Read,Upload.

SQL 专家的任何帮助都会很棒!

Any help would be great from a SQL GURU!

重新设计的查询

 SELECT 
     * 
 FROM
     usersTbl AS uT 
 INNER JOIN 
     usersPermissionsTbl AS uPT 
 ON 
     uPT.userId = uT.id 
 INNER JOIN 
     usersPermissions AS uP 
 ON 
     uPT.permissionId = uP.id 
 WHERE 
     uT.active='true'
 AND 
     uT.email='bBarker@thepriceisright.com'

推荐答案

我同意所有的评论......但严格按照你的意愿去做,这里有一个带有分割器功能的方法

I agree with all of the comments... but strictly trying to do what you want, here's a way with a splitter function

declare @usersTbl table ([Name] varchar(64), id int, [permissions] varchar(64), age int)
insert into @usersTbl
values

('Bbarker',5987,'1,3',87)

declare @usersTblpermissions table (id int, [type] varchar(64))
insert into @usersTblpermissions
values
(1,'Read'),
(2,'Write'),
(3,'Upload'),
(4,'Admin')

;with cte as(
    select
        u.[Name]
        ,u.id as UID
        ,p.id
        ,p.type
        ,u.age
    from @usersTbl u
    cross apply dbo.DelimitedSplit8K([permissions],',') x
    inner join @usersTblpermissions p on p.id = x.Item)

select distinct
    [Name]
    ,UID
    ,age
    ,STUFF((
          SELECT ',' + t2.type
          FROM cte t2
          WHERE t.UID = t2.UID
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
from cte t

Jeff Moden Splitter

CREATE FUNCTION [dbo].[DelimitedSplit8K] (@pString VARCHAR(8000), @pDelimiter CHAR(1))
--WARNING!!! DO NOT USE MAX DATA-TYPES HERE!  IT WILL KILL PERFORMANCE!

RETURNS TABLE WITH SCHEMABINDING AS
RETURN

/* "Inline" CTE Driven "Tally Table" produces values from 1 up to 10,000...
enough to cover VARCHAR(8000)*/

  WITH E1(N) AS (
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
                ),                          --10E+1 or 10 rows
       E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
       E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
 cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
                     -- for both a performance gain and prevention of accidental "overruns"
                 SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
                ),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
                 SELECT 1 UNION ALL
                 SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
                ),
cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
                 SELECT s.N1,
                        ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                   FROM cteStart s
                )
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
        Item       = SUBSTRING(@pString, l.N1, l.L1)
   FROM cteLen l
;
GO

这篇关于SQL Server 存储过程循环通过逗号分隔的单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆