0

。という名前のテーブル内のすべての列の更新ステートメントに変換するselectステートメントがありますVariable[N]

たとえば、私はこれらのことをしたいと思います:

  1. 以下のSQLを更新ステートメントに変換できるようにしたいと思います。
  2. n。という名前の列がありますvariable[N]。以下の例では列のみを更新しますが、事前に列の数を知らなくても、variable63名前が付いたすべての列に対して動的に更新を実行したいと思います。また、以下の例では、更新された結果をに取得します。以下の例では、可能であれば、それぞれの変数列を結果で更新したいと思います。variable1variableNvariable[N]NewColvariable63

variable1列をループしてvariableN、それらすべての列に対して同じそれぞれの更新操作を実行するラッパーが必要です。

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;
4

2 に答える 2

0

わかりました。わかったと思います。列をループし、列ごとに更新コマンドを実行する関数。

DECLARE @sql NVARCHAR(1000),
@cn NVARCHAR(1000)--,
--@r NVARCHAR(1000),
--@start 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;
于 2012-08-13T21:13:49.357 に答える
0

SQL で変数をループする一般的な方法はありません。何を変更したいかを正確に知っている必要があります。一部のデータベースでは、システム テーブルにクエリを実行して更新ステートメントを動的に作成することができます (InterBase でその方法を知っており、その前身である Firebird です)。

以下は、NULL であるいくつかのフィールドを更新する方法です。COALESCE と CASE は、LEFT JOIN または NOT EXISTS を使用する場合と同様に、同じことを行う 2 つの方法です。あなたとあなたのデータベースエンジンが最も使いやすいものを使用してください。すべてのレコードが更新されることに注意してください。データベースに何百万ものレコードが含まれていて、各レコードが大きく、このクエリを何度も実行したい場合、これは良い解決策ではありません。

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
于 2012-07-26T20:59:11.140 に答える