0

一般的な更新手順を作成しようとしています。この手順のポイントは、テーブルで発生するすべてを追跡できるようにすることです。レコードが更新された場合、誰がそのレコードを変更したか、元は何であったか、変更後の内容は何か、いつ変更が発生したかを知る必要があります。これは、説明責任が必須である最も重要なテーブルでのみ行います。

現時点では、Web サーバー プログラミングと SQL Server コマンドを組み合わせてこれを行っています。

現在持っているものを使用して、SQL のみのバージョンを作成する必要があります。

だから、ここに私が必要とするものの要件があります:

元の sp は UpdateWithHistory と呼ばれます。現在、すべて varchar の 4 つのパラメーターを使用します (または、nvarchar でもかまいません)。これらは、テーブル名、主キー フィールド、主キー値、および field='value',field1='value1'... などの形式のフィールドと値のコンマ区切りリストです。

バックグラウンドで、文字列テーブル名を実際のテーブルにマップするために使用するマッピング テーブルがあります。

ストアド プロシージャでは、OPENROWSET、exec()、select into、xml、およびその他のメソッドのさまざまな組み合わせを試しました。どれも機能していないようです。

したがって、基本的には、提供された 4 つのパラメーターから単純な select ステートメント (結合やその他の複雑な select を使用しない) を動的に生成し、そのクエリの結果をテーブルに格納できる必要があります。動的であるため、クエリされるフィールドの数や、それらがどのようなデータ型になるかはわかりません。

適切なフィールドとデータ型を持つテーブルが自動的に作成されるため、select into を試しましたが、exec コマンドと組み合わせて使用​​すると機能しません。私も試してみました

exec sp_executeSQL @SQL, N'@output xml output', @resultXML output

@resultXML は XML データ型で、@SQL は sql コマンドです。@resultXML は、何をしても常に null になります。「FOR XML Path」は常に1つの列を返すことがわかっているため、xmlルートも試しましたが、ステートメントへの挿入では使用できません....

そのステートメント出力は、更新前の元の値を決定するために使用されます。

このハードルを乗り越えたら、あとは簡単だと思います。誰でもアイデアはありますか?

グローバルテーブルを使用したくないのですが、最終的に機能するようになったコードは次のとおりです。別の答えを喜んで受け入れます...

DECLARE @curRecordString varchar(max) = 'SELECT * into ##TEMP_TABLE FROM SOMEDB.dbo.' + @tbl + ' WHERE ' + @prikey + ' = ''' + @prival + ''' '
exec(@curRecordString)

基本的に、前に述べたように、SQL クエリを動的に構築し、後でアクセスできるようにクエリの実行結果を保存する必要があります。後で XQuery を使用してノードを解析および比較するため、XML データ型として保存することをお勧めします。上記のコードでは、グローバル一時テーブル (理想的ではないことはわかっています) を使用してクエリの結果を格納し、残りの手順でデータにアクセスできるようにしています。

私が言ったように、私はこのアプローチが好きではありませんが、他の誰かが SQL クエリを動的に作成して実行し、結果を保存して、後でストアド プロシージャで結果にアクセスできるようにするより良い方法を考え出すことができれば幸いです。 .

4

1 に答える 1

0

これは間違いなくハックですが...

DECLARE @s VARCHAR(MAX)
SET @s = 'SELECT (SELECT 1 as splat FOR XML PATH) a'

CREATE TABLE #save (x XML)

INSERT INTO #save
        ( x )
EXEC (@s)


SELECT  * FROM #save s

DROP TABLE #save
于 2013-06-06T20:02:07.063 に答える