2015-11-19 2 views
1

У пользователя есть доступ к определенным событиям. У меня есть строка в Users, называемая EventAccessIds. Я хочу иметь все идентификаторы, которые пользователь может получить здесь каким-то образом. Если пользователь A должен получить доступ к событиям 1,4 и 8, то EventAccessIds должен быть 1 + 4 + 8 или что-то в этом роде.Как разбить EventAccessIds = 1 + 4 + 8 на EventId = 1, EventId = 4 и EventId = 8 в хранимых процедурах?

Затем я хочу вытащить эти идентификаторы и использовать оператор Select для заполнения данных в разных областях (dropdownlists, gridviews и т. Д.). По сути, он заполняет данные для идентификаторов событий 1, 4 и 8 для пользователя A.

Проблема в том, что я новичок в базах данных и sql, поэтому я не уверен, как кодировать все это , Я использую хранимые процедуры. Я думал, может быть что-то вроде этого, чтобы отправить EventAccessIds на события:

WITH first AS 
    (
    SELECT EventAccessIds 
    FROM Users 
    WHERE UserName = @UserName 
    ), second AS 
    (
    SELECT * 
    FROM Event 
    WHERE EventId = EventAccessIds 
    ) 

Но как же я разбить EventAccessIds = 1 + 4 + 8 до EventId = 1, EventId = 4, и EventId = 8?

EDIT spGetAllEvents

USE [Events2] 
GO 
/****** Object: StoredProcedure [dbo].[spGetAllEvents] Script Date: 11/19/2015 9:03:42 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[spGetAllEvents] 
    @UserName nVarChar(80) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for procedure here 
WITH first 
AS 
( 
    SELECT EventAccessIds 
    FROM Users 
    WHERE UserName = @UserName 
), second AS 
(
    SELECT e.* FROM [Event] as e 
    WHERE e.EventId in 
    (
     SELECT convert(int, s.Data) 
     FROM [first] as f 
     CROSS APPLY 
     (SELECT * FROM dbo.Split(f.EventAccessIds, '+')) as s 
    ) 
) 
END 

пользователей (первое изображение) и событие (второе изображение) Users

Event

ответ

1

Прежде всего, вы должны разделить EventAccessIds с вашей собственной функции, так как SQL Server не имеет функции Split.

Один из хороших примеров был опубликован в Ole Michelsen's blog.

CREATE FUNCTION [dbo].[Split] 
(
    @String NVARCHAR(4000), 
    @Delimiter NCHAR(1) 
) 
RETURNS TABLE 
AS 
RETURN 
(
    WITH Split(stpos,endpos) 
    AS(
     SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos 
     UNION ALL 
     SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1) 
      FROM Split 
      WHERE endpos > 0 
    ) 
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)), 
     'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos) 
    FROM Split 
) 
GO 

Затем вы можете использовать расщепляется таблицу как целочисленный массив:

WITH first AS 
(
    SELECT EventAccessIds 
    FROM Users 
    WHERE UserName = @UserName 
), second AS 
(
    SELECT * 
    FROM Event 
    WHERE EventId IN (SELECT CONVERT(int, Data) FROM dbo.Split(EventAccessIds, '+') 
) 

ОБНОВЛЕНО

Так как ваш [второй] запрос, кажется, относится EventAccessIds выбран в [первой] запросе , это должно быть примерно так:

WITH first 
AS 
( 
    SELECT EventAccessIds 
    FROM Users 
    WHERE UserName = @UserName 
), second AS 
(
    SELECT e.* FROM [Event] as e 
    WHERE e.EventId in 
    (
     SELECT convert(int, s.Data) 
     FROM [first] as f 
     CROSS APPLY 
     (SELECT * FROM dbo.Split(f.EventAccessIds, '+')) as s 
    ) 
) 
+0

Благодаря это здорово. Хорошо, я получаю сообщение об ошибке «Msg 207, уровень 16, состояние 1, процедура spGetAllEvents, строка 31 Недопустимое имя столбца« EventAccessIds ». но столбец существует. С кодом 'С первым AS ( SELECT, EventAccessIds FROM Users WHERE UserName = @Username ), второй AS ( SELECT * FROM Event WHERE EventId IN (SELECT CONVERT (INT, данные) FROM dbo.Split (EventAccessIds, '+') ) ) SELECT * FROM первого F РЕГИСТРИРУЙТЕСЬ второго s ON f.EventAccessIds = s.EventId' – RockOn

+1

@RockOn Я обновил свой ответ, попробуйте после ** оБНОВЛЕНО **. Однако 'f.EventAccessIds' и' s.EventId' не может сравниться, потому что это строка и int. Я думаю, вы можете просто сделать 'select * from [first], [second]' – jhmt

+0

Hm okay Я попробовал, и теперь я получаю: Msg 156, Level 15, State 1, Procedure spGetAllEvents, строка 39 Неправильный синтаксис рядом с ключевым словом 'END ». – RockOn

2

Если я правильно понимаю, что вы спрашиваете, это что-то вроде этого? SQL Fiddle demo

declare @input varchar(max) 
DECLARE @SQLString nvarchar(500) 
DECLARE @ParmDefinition nvarchar(500) 
DECLARE @result varchar(max) 

set @input = '1+4+8' 

SET @SQLString = N'SELECT @result = ' + @input 

SET @ParmDefinition = N'@result varchar(max) OUTPUT' 

EXECUTE sp_executesql @SQLString, @ParmDefinition, @[email protected] OUTPUT 
SELECT @result 

declare @eventTable table (id int, data varchar(max)) 
insert into @eventTable select 1, 'Event id 1' 
insert into @eventTable select 2, 'Event id 2' 
insert into @eventTable select 4, 'Event id 4' 
insert into @eventTable select 8, 'Event id 8' 

select * 
from @eventTable et 
where (id & @result) = id 
+0

Спасибо за этот ответ! – RockOn

Смежные вопросы