2011-08-24 77 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