2012-04-16 4 views
2

У меня есть некоторые данные, содержащие столбец с разделителями. Есть несколько записей в том же столбце по существу:Эффективный запрос для разделения столбца с разделителями на отдельную таблицу

A0434168.A2367943.A18456972.A0135374.A0080362.A0084546.A0100991.A0064071.A0100858 

Значение имеют переменную длину, и ограничены периодами. Я пытаюсь создать таблицу поиска для этих данных с помощью курсора. Из-за объема данных курсор необоснованно медленный.

Мой курсор выглядит следующим образом:

DECLARE @ptr nvarchar(160) 
DECLARE @aui nvarchar(15) 
DECLARE @getmrhier3 CURSOR 

SET @getmrhier3 = CURSOR FOR 
    SELECT cast(ptr as nvarchar(160)),aui 
    FROM mrhier3 
    FORWARD_ONLY 
OPEN @getmrhier3 
FETCH NEXT 
    FROM @getmrhier3 INTO @ptr, @aui 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    if(len(@ptr) > 0) 
    begin 
     if(charindex('.',@ptr) > 0) 
     begin 
      insert into mrhierlookup(hieraui,aui) 
      values  (substring(@ptr,0,charindex('.',@ptr)),@aui) 

      update mrhier3 
      set  ptr = substring(@ptr,charindex('.',@ptr)+1,LEN(@ptr)) 
      where aui = @aui 
       and ptr = @ptr 
     end 
     else 
     begin 
      insert into mrhierlookup(hieraui,aui) 
      values  (@ptr,@aui) 

      update mrhier3 
      set  ptr = '' 
      where aui = @aui 
       and ptr = @ptr 
     end 
    end 
    FETCH NEXT 
     FROM @getmrhier3 INTO @ptr, @aui 
END 

CLOSE  @getmrhier3 
DEALLOCATE @getmrhier3 

Текущая версия курсора просто работает на ведущем значении столбца. Все длины произвольны. Длина столбца не более ~ 150 символов.

С текущим набором данных построение таблицы поиска, вероятно, займет несколько дней. У него будет несколько миллионов записей.

Есть ли лучший способ эффективно (быстро) проанализировать эти данные в отдельной таблице для более быстрого выполнения операций объединения?

+4

Без обид, но как вы читаете свой код? Это дает вам кошмары? Отступы, возврат каретки, пробел и терминаторы утверждений идут ДОЛГО. –

+0

Похоже на http://stackoverflow.com/questions/314824/t-sql-opposite-to-string-concatenation-how-to-split-string-into-multiple-reco или http://stackoverflow.com/ вопросы/2647/split-string-in-sql – xQbert

+0

@xQbert: похоже, но все еще отличается из-за ориентации столбца. – RBarryYoung

ответ

2

Разбить функцию:

CREATE FUNCTION dbo.SplitStrings(@List NVARCHAR(MAX)) 
RETURNS TABLE 
AS 
    RETURN (SELECT Item FROM 
     (SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)') 
     FROM (SELECT [XML] = CONVERT(XML, '<i>' 
     + REPLACE(@List, '.', '</i><i>') + '</i>').query('.') 
      ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y 
     WHERE Item IS NOT NULL 
    ); 
GO 

Тогда избавиться от всего курсора и зацикливание нонсенс и не делать этого:

INSERT dbo.mrhierlookup 
(
    heiraui, 
    aui 
) 
SELECT s.Item, m.aui 
    FROM dbo.mrhier3 AS m 
    CROSS APPLY dbo.SplitStrings(m.ptr) AS s 
GROUP BY s.Item, m.aui; 
+0

Это сработало и создало таблицу с несколькими миллионами строк за 5 секунд! – user1003221

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