2012-07-26 3 views
0

이름이 Variable[N] 인 테이블의 모든 열에 대한 업데이트 명령문으로 변환하려는 select 문이 있습니다.루프별로 여러 열을 업데이트 하시겠습니까?

예를 들어, 나는이 일을 할 :

  1. 내가 UPDATE 문에 아래의 SQL을 변환 할 수 있어야합니다.
  2. variable[N]이라는 이름의 n 열이 있습니다. 아래의 예는 열 variable63 만 업데이트하지만, 내가 미리 가지고있는 variable[N] 열을 모른 채 variable1에서 variableN까지의 모든 열에 대해 동적으로 업데이트를 실행하고 싶습니다. 또한 아래 예제에서 업데이트 된 결과는 NewCol입니다. 가능한 경우 각각의 변수 열을 결과로 업데이트하려고합니다. 아래 예제에서 variable63입니다.

나는 variableN을 통해 열 variable1을 통해 루프 래퍼를 가지고 모든 열을 같은 각각의 업데이트 작업을 수행 할 :

SELECT 
    projectid 
    ,documentid 
    ,revisionno 
    ,configurationid 
    ,variable63 
    ,ISNULL(Variable63, 
      (SELECT TOP 1 
      variable63 
      FROM table1 
      WHERE 
       documentid = t.documentid 
      and projectid=t.projectid 
      and configurationid=t.configurationid 
      and cast(revisionno as int) < cast(t.revisionno as int) 
      AND Variable63 is NOT NULL 
      ORDER BY 
       projectid desc 
      ,documentid desc 
      ,revisionno desc 
      ,configurationid desc 
      )) as NewCol 
FROM table1 t; 
+0

동적 SQL을 사용해야합니다. 당신이 빨리 그것을 기대하지 않기를 바랍니다. – Hogan

+0

적어도 variable1과 variable2에 대한 update 문은 다음과 같을 것입니다. 여기에 대해 정확히 알기는 어렵습니다. – Hogan

+0

어떤 데이터베이스를 사용하고 있습니까? –

답변

0

더 일반적인 방법은 SQL 당신, 변수를 통해 루프 없다 정확히 무엇을 수정하고 싶은지 알고 있어야합니다. 일부 데이터베이스에서는 시스템 테이블을 쿼리하여 업데이트 문을 동적으로 작성할 수 있습니다 (InterBase 및 Firebird의 방법을 알고 있습니다).하지만 사용중인 데이터베이스 엔진에 대해서는 알려주지 않았습니다.

다음은 LEFT JOIN 또는 NOT EXISTS를 사용하는 것과 같은 일을하는 두 가지 방법 인 COALESCE와 CASE가 null 인 여러 필드를 업데이트하는 방법입니다. 당신과 당신의 데이터베이스 엔진이 가장 편한 것을 사용하십시오. 모든 레코드가 업데이트되므로 데이터베이스에 수백만 개의 레코드가 포함되어 있고 각 레코드가 크기 때문에이 쿼리를 여러 번 실행하려는 경우에는 좋은 해결책이 아닙니다.

UPDATE table1 t 
SET t.VARIABLE63 = 
    COALESCE(t.VARIABLE63, 
      (SELECT VARIABLE63 
      FROM table1 t0 
      LEFT JOIN table1 tNot 
        ON tNot.documentid = t.documentid 
        AND tNot.projectid=t.projectid   
        AND tNot.configurationid=t.configurationid 
        AND cast(tNot.revisionno as int) > cast(t0.revisionno as int) 
        AND cast(tNot.revisionno as int) < cast(t.revisionno as int) 
        AND tNot.Variable63 is NOT NULL 
      WHERE t0.documentid = t.documentid 
       AND t0.projectid=t.projectid   
       AND t0.configurationid=t.configurationid 
       AND cast(t0.revisionno as int) < cast(t.revisionno as int) 
       AND t0.Variable63 is NOT NULL 
       AND tNot.Variable63 is NULL)), 
    t.VARIABLE64 = CASE WHEN t.VARIABLE64 IS NOT NULL then t.VARIABLE64 
         ELSE (SELECT VARIABLE64 
           FROM table1 t0 
           WHERE t0.documentid = t.documentid 
           AND t0.projectid=t.projectid   
           AND t0.configurationid=t.configurationid 
           AND cast(t0.revisionno as int) < cast(t.revisionno as int) 
           AND t0.Variable64 is NOT NULL 
           AND NOT EXISTS(SELECT 1 
               FROM table1 tNot 
               WHERE tNot.documentid = t.documentid 
               AND tNot.projectid=t.projectid   
               AND tNot.configurationid=t.configurationid 
               AND cast(tNot.revisionno as int) > cast(t0.revisionno as int) 
               AND cast(tNot.revisionno as int) < cast(t.revisionno as int) 
               AND tNot.Variable64 is NOT NULL)) END 
+0

DB는 SQL Server 2008입니다. – user1491749

0

괜찮아요. 열을 반복하고 열마다 업데이트 명령을 실행하는 기능입니다.

DECLARE @sql NVARCHAR(1000), 
@cn NVARCHAR(1000)--, 
[email protected] NVARCHAR(1000), 
[email protected] INT 

DECLARE col_names CURSOR FOR 
SELECT column_name 
FROM information_schema.columns 
WHERE table_name = 'PIVOT_TABLE' 
ORDER BY ordinal_position 

--SET @start = 0 
DECLARE @op VARCHAR(max) 
SET @op='' 

OPEN col_names FETCH next FROM col_names INTO @cn 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    --print @cn 
    IF UPPER(@cn)<> 'DOCUMENTID' and UPPER(@cn)<> 'CONFIGURATIONID' and UPPER(@cn)<> 'PROJECTID' and UPPER(@cn)<> 'REVISIONNO' 
    BEGIN 
     SET @sql = 'UPdate pt 
     set pt.' + @cn + ' = ((SELECT TOP 1 t.' + @cn + ' FROM pivot_table t WHERE t.documentid = pt.documentid and t.projectid=pt.projectid 
     and t.configurationid=pt.configurationid and cast(t.revisionno as int) < cast(pt.revisionno as int) AND t.' + @cn + ' is NOT NULL 
     ORDER BY revisionno desc)) from PIVOT_TABLE pt where pt.' + @cn + ' is NULL;' 
     EXEC Sp_executesql 
     @sql 
     --print @cn 
    END 
    FETCH next FROM col_names INTO @cn 
END 

CLOSE col_names 
DEALLOCATE col_names; 
관련 문제