2012-04-16 36 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

沒有違法,但你怎麼看你自己的代碼?它會給你做惡夢嗎?縮進,回車,空白區和語句終止符都是一種LONG方式。 – 2012-04-16 22:22:33

+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 2012-04-16 22:22:54

+0

@xQbert:類似,但由於列方向而不同。 – RBarryYoung 2012-04-16 22:31:07

回答

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 2012-04-16 22:41:05

相關問題