4

Web アプリから SQLBulkCopy を実行し、レコードをステージング テーブルに挿入しています。ステージング テーブルを扱うのはこれが初めてです。データを受け入れるライブ テーブルには約 200 のフィールドがあり、将来変更される可能性があります。この変更が発生したときに、merge ステートメントを書き直す必要はありませんでした。

マージ機能を模倣するこの SQL を思いつきましたが、テーブルの列を綴る必要はありません。私は SQL の専門家ではありませんが、この SQL を使用することで問題が発生する可能性がある場合は、この SQL の例を見たことがなく、多くの人が検索しているため、誰かに見てもらいたいと思っています。

null id フィールドを持つステージング テーブルのレコードが挿入されることに注意してください。

-- set the table names, primary key field & vars to hold query parts
DECLARE @LiveTable varchar(20) = 'Test'
DECLARE @StagingTable varchar(20) = 'TestStaging'
DECLARE @PKField varchar(20) = 'TestPK'
DECLARE @SQLSet nvarchar(MAX) = ''
DECLARE @SQLInsertFields nvarchar(MAX) = ''

-- get comma delimited field names
DECLARE @Fields nvarchar(MAX) = (SELECT dbo.fn_GetCommaDelimitedFieldNames(@LiveTable))

-- loop through fields generating set clause of query to execute
WHILE LEN(@Fields) > 0
BEGIN
    DECLARE @Field varchar(50) = left(@Fields, CHARINDEX(',', @Fields+',')-1)
    IF @Field <> @PKField -- the primary key field cannot be updated
        BEGIN
            SET @SQLSet += ', ' + @LiveTable + '.' + @Field + ' = ' + @StagingTable + '.' + @Field
            SET @SQLInsertFields += ', ' + @Field
        END
    SET @Fields = STUFF(@Fields, 1, CHARINDEX(',', @Fields+','), '')
END

-- remove the leading comma
SET @SQLSet = SUBSTRING(@SQLSet,3,LEN(@SQLSet))
SET @SQLInsertFields = SUBSTRING(@SQLInsertFields,3,LEN(@SQLInsertFields))

-- update records from staging table where primary key is provided
DECLARE @SQL nvarchar(MAX) = N'UPDATE ' + @LiveTable + 
                             ' SET ' + @SQLSet + 
                             ' FROM ' + @LiveTable + 
                             ' INNER JOIN ' + @StagingTable + 
                             ' ON ' + @LiveTable + '.' + @PKField + ' = ' + @StagingTable + '.' + @PKField

-- insert records from staging table where primary key is null
SET @SQL += '; INSERT INTO ' + @LiveTable + ' (' + @SQLInsertFields + ') SELECT ' + @SQLInsertFields + ' FROM ' + @StagingTable + ' WHERE ' + @PKField + ' IS NULL'

-- delete the records from the staging table
SET @SQL += '; DELETE FROM ' + @StagingTable

-- execute the sql statement to update existing records and insert new records
exec sp_executesql @SQL;

誰かがパフォーマンスやその他の問題に気付いた場合は、洞察に感謝します。

4

1 に答える 1

0

これをしないでください。本当に。あなたは、時が来たときにおそらく正しく処理できないというまれな問題を回避するために非常に一生懸命働いています。

ターゲットテーブルが変更された場合、ファンシーな動的SQLが正しく機能するように変更されることをどのように知っていますか?それが機能していないように見える(つまり、構文的には機能する)が、実際には間違ったことをしていることをどのように確認できますか?ターゲットテーブルが変更された場合、アプリケーションとステージングテーブルも変更する必要はありませんか?SETこれらすべてが空中にある中で、もう1つの句 を追加するものは何ですか?

その間、誰もがそのgobbledygookを読むことをどのように期待できますか(あなたのせいではなく、実際には、それはSQLの構文です)?ボグ標準の挿入ステートメントは非常に明確で信頼できます。

そして速い。SQLServerは動的クエリを最適化できません。あなたは効率のためにbcpを使用しましたが、今では将来性を意味する意味でbcpを打ち負かしています。

于 2013-03-14T03:52:53.377 に答える