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

합니다 (deliminated 문자열 spliting 후 새로운 테이블 600 정도 레코드 발생한다 원래 테이블에서 170 정도에서 단지 1 개 레코드) 삽입 된 데이터는 정확. 나는 위의 샘플 데이터를 사용하여 볼 기대하고 무엇

은 다음과 같습니다

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

은 모든 자원을 지적하거나 식별 할 수있는 사람이 내가 잘못가는 방법이 쿼리를 작동하게하는 방법입니다 어디?

데이터베이스는 당신이 제공 할 수있는 모든 도움에 미리 감사 MS SQL 서버 2000

입니다.

매트 WHERE 조항이없는 "다음"사람을 얻는다, 그래서 SQL Server가 다음 사람에게 이동하는 알 방법을 잘 모르겠어요

+0

DDL 및 샘플 데이터를 제공해 주셔서 감사합니다. 이는 매우 유용하며 문제를 재현하려는 것이 아니라 솔루션에 집중할 수있게 해줍니다. –

+1

의견을 보내 주셔서 감사합니다. 나는 최선의 결과를 얻기 위해 최선의 질문을 만드는 방법을 천천히 배우고 있으며, 앞으로의 문제에 대해 DDL을 염두에 두겠습니다. – Lima

답변

1

당신의 SELECT 문. 일회성 작업 인 경우 왜 커서를 사용하지 않습니까?

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

관련 문제