2013-07-17 3 views
1

У меня есть следующие ОТВ:создание TSQL КТР для автоматического приращения с VARCHAR (макс)

;WITH combo (id, [program_name]) AS 
(
    SELECT 
    1 
    , CAST('' AS VARCHAR(MAX)) 
    UNION ALL 
    SELECT 
     cte.id + 1 
     ,(cte.[program_name] + pl.[program_name] + '; ') 
    FROM (
     SELECT 
     RowNum = ROW_NUMBER() OVER (ORDER BY people_id) 
     --people_id 
     ,p.[program_name] 
     FROM event_log_Rv E 
     JOIN PROgrams_view p on p.program_info_id = e.program_providing_service 
where people_id = 'DFA3AFE5-F681-4B1B-89F0-31D04FA6BF7D' 
    ) pl 
    JOIN combo cte ON pl.RowNum = cte.id 
) 
SELECT TOP 1 id, [program_name] FROM combo ORDER BY id DESC 

Когда я запускаю этот КТР я получаю эту ошибку:

Msg 530, Level 16, State 1, Line 1
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

people_id и program_providing_service являются uniqueidentifier типы данных.

Как добавить в столбец к этому CTE, который будет отображать номер строки? В конечном итоге я хочу, чтобы этот CTE отображал все программы/клиент.

Я пытался заставить это работать, добавив номер строки, чтобы присоединиться к CTE и комбо в этом CTE, но если вы можете думать о другом способе отображения всех программ/клиентов всего за одну строку, я могу принять это ,

Например, я хочу:

people_id        Programs 
DFA3AFE5-F681-4B1B-89F0-31D04FA6BF7D IHS; MCP; DCS 
+0

Вы также можете увидеть ['ОПЦИЯ (МАКСИРОВАНИЕ 0)'] (http://msdn.microsoft.com/en-us/library/ms181714.aspx).FYI: помогает, если вы помечаете вопросы базы данных продуктом и версией базы данных, например. 'SQL-сервер-2008'. – HABO

ответ

1

Comma отделено список один ко многим отношений положить в одну колонку, где он принимает множество строк и положить их в «(полукокс)» разделенного список? Я использую для этого тип xml, так как у вас могут быть сложные структуры, которые со временем могут меняться. Рекурсия довольно интенсивна для такого рода ИМХО.

Вот это самораспаковывающийся пример и ниже я объясню:

declare @Person Table (personID int identity, person varchar(8)); 

insert into @Person values ('Brett'),('Sean'),('Chad'),('Michael'),('Ray'),('Erik'),('Queyn'); 

declare @Orders table (OrderID int identity, PersonID int, Desciption varchar(32), Amount int); 

insert into @Orders values (1, 'Shirt', 20),(1, 'Shoes', 50),(2, 'Shirt', 22),(2, 'Shoes', 52),(3, 'Shirt', 20),(3, 'Shoes', 50),(3, 'Hat', 20),(4, 'Shirt', 20),(5, 'Shirt', 20),(5, 'Pants', 30), 
(6, 'Shirt', 20),(6, 'RunningShoes', 70),(7, 'Shirt', 22),(7, 'Shoes', 40),(7, 'Coat', 80) 

Select top 100 
    p.person 
, o.Desciption 
from @Person p 
    join @Orders o on p.personID = o.PersonID 
order by p.person 

Select 
    p.person 
, replace(
     replace(
      replace(
      (
       select 
        o.Desciption as d 
       from @Orders o 
       where o.PersonID = p.personID 
       for xml auto 
      ), '"/><o d="', ', ') 
     , '<o d="', '') 
    , '"/>', '') as SeperatedList 
from @Person p 
order by p.person 
  1. Я делаю вложенный выберите, чтобы получить все дочерние элементы (в моем примере заказах) родительский объект (человек в моем примере).
  2. Вы не можете вернуть массив в TSQL в качестве столбца .... если он не хранится как xml, который может быть его собственной структурой с несколькими элементарными древовидными структурами в виде одного столбца.
  3. По характеру 'for xml auto' вернет мне текст вместо xml-типа (классный). Есть много, что я оставляю, и есть целый раздел белых работ только для использования «FOR XML (что-то)». Auto предполагает, что имя элемента - это мой псевдоним «o», хотя мой столбец называется «d», который становится атрибутом.
    1. Поскольку бросок делается по умолчанию, чтобы текст не придется беспокоиться о выпуске литья, потому что мне нужно сделать некоторые находки и заменяет
    2. Я в принципе найти метки я примененную для моих элементов и столбцов и ' замените() их разделителем столбцов. Я выбрал «,», вы можете использовать все, что захотите.
    3. Я заменяю элементы конца и начала еще двумя. У Voila теперь есть отдельный список (char).

Этот метод хорошо работает, как он отделяет ребенок группировки в его собственном наборе данных и от того, что я видел, как правило, довольно быстро по сравнению с строковыми операциями приклеивая к существующей строке из-за вас должно сделать метод, один раз плюс память, один раз плюс память плюс память, один раз плюс память плюс память ... Вы получаете идею. Этот метод получает все сразу для набора данных, а затем просто оценивает презентацию для конечного пользователя. Если у вас есть миллионы дочерних строк, и он медленный, я бы сначала подумал о том, чтобы сбрасывать в CTE, таблицу или временную таблицу, а затем сначала использовать их как столбцы XML.

+0

Большое вам спасибо! Это сделал трюк! – salvationishere

+0

Прохладный, рад, что помог вам. – djangojazz