背景:
サーバーで実行するSQLコマンドを作成しています。これには、ストアプロシージャへのアクセスと、他のストアードプロシージャへの入力として使用される変数の宣言が含まれます。これはすべてC#を使用してクライアント側で生成され、大きなパッケージとして送信されます。 pingの時間が非常に長いため、クライアントは非常に遠隔地にあり、接続が不良であり、多くのパッケージを送信したり、長い応答時間のためにバックログの作成を開始したりしたくないので、この方法で行う必要があります。
約200のストアプロシージャを使用した1つのトランザクションの転送速度は約35秒かかるため、現在、3つ以下のクライアントが並行して動作するか、またはバックログの構築を開始します。
質問:
変数がすでに存在する場合、現在はない変数をどのように宣言できますか? C#側で辞書を使用することもできますが、それは私にとっては間違った方法のように思えます。存在する場合、その変数の再宣言を受け入れる宣言が必要です。
変数を再宣言することはできません。また、変数が宣言されているかどうかをテストすることもできません(少なくとも、私がこれまで見つけられたことはありません)。しかし、とにかくこれを行う必要はありません。事前に変数名がわかっている場合は、プロセスの最初にそれらをすべて宣言してください。次に、スクリプト全体で使用します。
例えば:
--------------------------------
-- BEGIN script header
--------------------------------
DECLARE @SomeVariable1 INT,
@SomeVariable2 VARCHAR(50),
....;
SomeVariableN DATETIME;
--------------------------------
-- END script header
--------------------------------
次に、これらの変数を使用する1つ以上のスクリプトブロックを追加します。
---- Script Block 1 ---
EXEC dbo.MyProc @InputParam = 1, @OutputParam = @SomeVariable1 OUTPUT;
-----------------------
---- Script Block 2 ---
EXEC dbo.AnotherProc @InputParam = @SomeVariable1;
-----------------------
---- Script Block 3 ---
SET @SomeVariable2 = NULL; -- reset value if you don't want to carry over prior value
..do something here...
-----------------------
あなたの質問を読んでから、あなたはあなたのアプリケーションでSQLコードを構築し、それを複数のステートメントを持つ1つの長いスクリプトとしてサーバーに送信していると思います。
この場合は、ステートメントをGOで区切ってバッチを作成できます。以下は有効なSQLです。
DECLARE @a INT;
SET @a = 1;
SELECT @a;
GO
DECLARE @a INT;
SET @a = 1;
SELECT @a;
この問題は、ステートメントが別のバッチで宣言された変数を参照できなくなることです。
本当の答えは、アプリから呼び出されるストアドプロシージャを使用することだと思います。これにより、不良リンクを介して送信されるデータの量が減り、SQLが有効になります。