2011-08-24 79 views
1

我有一個表結構,其中包含標識符列和包含已刪除字符串的列。我想實現的是將分隔字符串插入到一個新表中,作爲拆分分隔字符串中每個值的單獨記錄。插入帶有已刪除字符串的表中的記錄

我對源表的表結構如下:

CREATE TABLE tablea(personID VARCHAR(8), delimStr VARCHAR(100)) 

一些樣本數據:

INSERT INTO tablea (personID, delimStr) VALUES ('A001','Monday, Tuesday') 
INSERT INTO tablea (personID, delimStr) VALUES ('A002','Monday, Tuesday, Wednesday') 
INSERT INTO tablea (personID, delimStr) VALUES ('A003','Monday') 

我的目標表如下:

CREATE TABLE tableb(personID VARCHAR(8), dayName VARCHAR(10)) 

我試圖創建一個存儲過程來進行插入,我的SP至今看起來像:

CREATE PROCEDURE getTKWorkingDays 
    @pos integer = 1 
    , @previous_pos integer = 0 
    AS 
    BEGIN 
    DECLARE @value varchar(50) 
      , @string varchar(100) 
      , @ttk varchar(8) 
    WHILE @pos > 0 
     BEGIN 
     SELECT @ttk = personID 
       , @string = delimStr 
       FROM dbo.tablea 
     SET @pos = CHARINDEX(',', @string, @previous_pos + 1) 
      IF @pos > 0 
      BEGIN  
       SET @value = SUBSTRING(@string, @previous_pos + 1, @pos - @previous_pos - 1) 
       INSERT INTO dbo.tableb (personID, dayName) VALUES (@ttk, @value)   
       SET @previous_pos = @pos 
      END  
     END 
     IF @previous_pos < LEN(@string) 
     BEGIN 
      SET @value = SUBSTRING(@string, @previous_pos + 1, LEN(@string)) 
      INSERT INTO dbo.tableb (tkinit, dayName) VALUES (@ttk, @value) 
     END 
END 

已插入(僅1只記錄了170個左右的原始表,其劈裂的deliminated串後應導致在新表格約600左右的記錄)中的數據,是不正確的。

我所期待看到使用上面的樣本數據是:

personID dayName 
A001  Monday 
A001  Tuesday 
A002  Monday 
A002  Tuesday 
A002  Wednesday 
A003  Monday 

有沒有人能夠指出任何資源或識別我要去的地方錯了,如何使這項工作查詢?

數據庫是MS SQL Server 2000中

我感謝你在你能夠提供的任何援助。

馬特

+0

感謝您使用DDL和示例數據!這非常有用,可以讓人們專注於解決方案,而不是試圖重現問題。 –

+1

感謝您的反饋意見,我正在慢慢學習如何創建最佳問題以獲得最快和最好的結果,我將爲未來的問題記住DDL。 – Lima

回答

1

嗯,你SELECT聲明,得到「未來」的人沒有一個WHERE條款,所以我不知道SQL Server將如何知道移動到下一個人。如果這是一次性任務,爲什麼不使用遊標?

CREATE TABLE #n(n INT PRIMARY KEY); 

INSERT #n(n) SELECT TOP 100 number  FROM [master].dbo.spt_values 
WHERE number > 0 GROUP BY number ORDER BY number; 

DECLARE 
    @PersonID VARCHAR(8), @delimStr VARCHAR(100), 
    @str VARCHAR(100),  @c CHAR(1); 

DECLARE c CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY 
    FOR SELECT PersonID, delimStr FROM dbo.tablea; 

OPEN c; 

FETCH NEXT FROM c INTO @PersonID, @delimStr; 

SET @c = ','; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @delimStr = @c + @delimStr + @c; 

    -- INSERT dbo.tableb(tkinit, [dayName]) 
    SELECT @PersonID, LTRIM(SUBSTRING(@delimStr, n+1, CHARINDEX(@c, @delimStr, n+1)-n-1)) 
     FROM #n AS n 
     WHERE n.n <= LEN(@delimStr) - 1 
     AND SUBSTRING(@delimStr, n.n, 1) = @c; 

    FETCH NEXT FROM c INTO @PersonID, @delimStr; 
END 

CLOSE c; 
DEALLOCATE c; 

DROP TABLE #n; 

如果你create a permanent numbers table(顯然有超過100行),你可以將它用於很多目的。你可以創建一個拆分函數,允許你在沒有遊標的情況下完成上述操作(沒有明確的遊標)。但是,當你最終離開SQL Server 2000時,這可能會最好。最新版本的SQL Server有更多的靈活和可擴展的方式來執行拆分和連接。

+0

謝謝Aaron,我設法通過插入部分工作,但是我會重新查看代碼,因爲我的代碼要比您的代碼長得多。我們是通過系統升級的一部分,並且應該在10月份轉向SQL 2005,然後再看看數字表。 – Lima