У вас должна быть настроена функция разделения, но как только она у вас появится, попробуйте это решение без курсора:
Я предпочитаю подход таблицы чисел для разделения строки в TSQL
Для того, чтобы этот метод работал, вам нужно выполнить настройку единовременной таблицы:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
После настройки таблицы Numbers создайте функцию разделения, которая будет возвращать пустые строки и номера строк:
CREATE FUNCTION [dbo].[FN_ListToTableRows]
(
@SplitOn char(1) --REQUIRED, the character to split the @List string on
,@List varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN
(
----------------
--SINGLE QUERY-- --this WILL return empty rows
----------------
SELECT
ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(@SplitOn, ListValue, number+1)-number - 1))) AS ListValue
FROM (
SELECT @SplitOn + @List + @SplitOn AS ListValue
) AS InnerQuery
INNER JOIN Numbers n ON n.Number < LEN(InnerQuery.ListValue)
WHERE SUBSTRING(ListValue, number, 1) = @SplitOn
);
GO
Теперь вы можете легко разбить строку CSV на таблицу и объединить ее, ПРИМЕЧАНИЕ. Эта функция разделения возвращает пустые строки и номера строк:
select * from dbo.FN_ListToTableRows(',','1,2,3,,,4,5,6777,,,')
ВЫВОД:
RowNumber ListValue
-------------------- ------------
1 1
2 2
3 3
4
5
6 4
7 5
8 6777
9
10
11
(11 row(s) affected)
Теперь вы можете использовать CROSS APPLY для разделения каждой строки в вашей таблице, например:
DECLARE @YourTable table (RowID int, RowValue varchar(8000))
INSERT INTO @YourTable VALUES (1,'1. Our function has defined how Availability is measured the hardware/software in Production;#3#2. Availability threshold levels exist for our function (e.g., SLA''s);#3#3. Our function follows a defined process when there are threshold breaches;#4#4. Our function collects and maintains Availability data;#4#5. Comparative analysis helps identify trending with the Availability data;#4#6. Operating Level Agreements (OLA''s) guide our interaction with other internal teams;#4#')
INSERT INTO @YourTable VALUES (2,'1. one;#1#2. two;#2#3. three;#3#')
INSERT INTO @YourTable VALUES (3,'1. aaa;#1#2. bbb;#2#3. ccc;#3#')
;WITH AllRows As
(
SELECT
o.RowID,st.RowNumber,st.ListValue AS RowValue
FROM @YourTable o
CROSS APPLY dbo.FN_ListToTableRows('#',LEFT(o.RowValue,LEN(o.RowValue)-1)) AS st
)
SELECT
a.RowID,a.RowValue AS Question, b.RowValue AS Answer
FROM AllRows a
LEFT OUTER JOIN AllRows b ON a.RowID=b.RowID AND a.RowNumber+1=b.RowNumber
WHERE a.RowNumber % 2 = 1
ВЫХОД:
RowID Question Answer
----------- ----------------------------------------------------------------------------------------------- -------
1 1. Our function has defined how Availability is measured the hardware/software in Production; 3
1 2. Availability threshold levels exist for our function (e.g., SLA's); 3
1 3. Our function follows a defined process when there are threshold breaches; 4
1 4. Our function collects and maintains Availability data; 4
1 5. Comparative analysis helps identify trending with the Availability data; 4
1 6. Operating Level Agreements (OLA's) guide our interaction with other internal teams; 4
2 1. one; 1
2 2. two; 2
2 3. three; 3
3 1. aaa; 1
3 2. bbb; 2
3 3. ccc; 3
(12 row(s) affected)