Как вставить данные во временную таблицу с использованием уникального выбора stamente для каждого столбца? - PullRequest
1 голос
/ 30 апреля 2019

Я встраиваю отчет в SSRS, где пользователь вручную добавляет некоторые данные к 4 текстовым параметрам, которые отправляются в хранимую процедуру, которая должна использовать их для создания временной таблицы.

I 'В настоящее время я тестирую сценарий sql перед созданием хранимой процедуры, но я не могу понять, как поместить все данные во временную таблицу, поскольку каждое значение хранится в отдельной переменной

, которую я создалфункция для анализа значений в каждой переменной и использования их в качестве таблицы, затем я делаю оператор вставки для каждой переменной в одну и ту же временную таблицу, но данные не добавляются в одну строку, например, строка 1 ввременная таблица должна быть 80605166, 190411-001751, Email1, CC1, но не

Declare 
@TID varchar(max) = '80605166,80414297,80410854'
,@Incident varchar(max) = '190411-001751,190411-001829,190228-000928'
,@Email varchar(max) =  'Email1,Email2,Email3'
,@CC varchar(max) = 'CC1,CC2,CC3'

--Create temp table to storage user input data into paramaters
IF OBJECT_ID ('tempdb..#Paramaters') IS NOT NULL DROP TABLE #Paramaters

CREATE TABLE #Paramaters ( TID INT  null , [Incident Number] nvarchar(14)null , Email varchar(500) null , CC varchar(500)null)

INSERT #Paramaters (TID)
select value from RPT.TVF_TextToTable (@TID,',')

INSERT #Paramaters ([Incident Number])
select value from RPT.TVF_TextToTable (@Incident,',')

INSERT #Paramaters (Email)
select value from RPT.TVF_TextToTable (@Email,',')

INSERT #Paramaters (CC)
select value from RPT.TVF_TextToTable (@CC,',')

Select * from #Paramaters

Текущий вывод (это то, что я получаю, но это неправильно) enter image description here

Ожидаемый результат

enter image description here

Первый TID относится к первому инциденту, первому электронному письму и первому CC

Ниже приведен код дляфункция TVF:

ALTER function [RPT].[TVF_TextToTable]
(
    @Text varchar(max),
    @Delimiter char(1) = ','
)
RETURNS @table TABLE (Value varchar(256))
AS
BEGIN
    declare @Length integer
    declare @Begin integer
    declare @End integer

    set @Length = datalength(@Text)
    set @Begin = 1
    set @End = patindex('%' + @Delimiter + '%', @Text)

    while @End <> 0
    begin
        insert into @table
        select substring(@Text, @Begin, @End - 1)

        set @Begin = @Begin + @End
        set @End = patindex('%' + @Delimiter + '%', substring(@Text, @Begin, @Length - @Begin + 1))
    end

    -- Now Catch any End Piece when it doesn't end with a comma
    if (@Length >= @Begin)
    begin
        insert into @table
        select substring(@Text, @Begin, @Length - @Begin + 1)
    end

    RETURN
end

1 Ответ

0 голосов
/ 30 апреля 2019

Как указывалось в комментариях, вам нужно добавить индексный номер к значениям, которые вы разделяете, используя которые вы можете join выводить различные переменные вместе. Этот запрос выполняет то, что вам нужно, с функцией разделения строк, которая также должна выполняться намного быстрее, чем ваша while основанная на цикле:

Запрос

Declare 
@TID varchar(max) = '80605166,80414297,80410854'
,@Incident varchar(max) = '190411-001751,190411-001829,190228-000928'
,@Email varchar(max) =  'Email1,Email2,Email3'
,@CC varchar(max) = 'CC1,CC2,CC3';

select s1.item as TID
        ,s2.item as Incident
        ,s3.item as Email
        ,s4.item as CC
from dbo.fn_StringSplit4k(@TID,',',null) as s1
    join dbo.fn_StringSplit4k(@Incident,',',null) as s2
        on s1.rn = s2.rn
    join dbo.fn_StringSplit4k(@Email,',',null) as s3
        on s1.rn = s3.rn
    join dbo.fn_StringSplit4k(@CC,',',null) as s4
        on s1.rn = s4.rn;

выход

+----------+---------------+--------+-----+
|   TID    |   Incident    | Email  | CC  |
+----------+---------------+--------+-----+
| 80605166 | 190411-001751 | Email1 | CC1 |
| 80414297 | 190411-001829 | Email2 | CC2 |
| 80410854 | 190228-000928 | Email3 | CC3 |
+----------+---------------+--------+-----+

Разветвитель строки

create function dbo.fn_StringSplit4k
(
     @str nvarchar(4000) = ' '              -- String to split.
    ,@delimiter as nvarchar(1) = ','        -- Delimiting value to split on.
    ,@num as int = null                     -- Which value to return.
)
returns table
as
return
                    -- Start tally table with 10 rows.
    with n(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)

                    -- Select the same number of rows as characters in @str as incremental row numbers.
                    -- Cross joins increase exponentially to a max possible 10,000 rows to cover largest @str length.
        ,t(t)   as (select top (select len(isnull(@str,'')) a) row_number() over (order by (select null)) from n n1,n n2,n n3,n n4)

                    -- Return the position of every value that follows the specified delimiter.
        ,s(s)   as (select 1 union all select t+1 from t where substring(isnull(@str,''),t,1) = @delimiter)

                    -- Return the start and length of every value, to use in the SUBSTRING function.
                    -- ISNULL/NULLIF combo handles the last value where there is no delimiter at the end of the string.
        ,l(s,l) as (select s,isnull(nullif(charindex(@delimiter,isnull(@str,''),s),0)-s,4000) from s)

    select rn
          ,item
    from(select row_number() over(order by s) as rn
                ,substring(@str,s,l) as item
        from l
        ) a
    where rn = @num
        or @num is null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...