選択したフィールド値をクエリから変数に保存し、更新ステートメントで使用するにはどうすればよいですか?
私の手順は次のとおりです。
次のことを行うSQL Server 2005 T-SQLストアドプロシージャを作成しています。
ここに私のコードがあります:
DECLARE @tmp_key int
DECLARE @get_invckey cursor
set @get_invckey = CURSOR FOR
select invckey from tarinvoice where confirmtocntctkey is null and tranno like '%115876'
OPEN @get_invckey
FETCH NEXT FROM @get_invckey into @tmp_key
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT c.PrimaryCntctKey as PrimaryContactKey
from tarcustomer c, tarinvoice i
where i.custkey = c.custkey and i.invckey = @tmp_key
UPDATE tarinvoice set confirmtocntctkey = PrimaryContactKey where invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key
END
CLOSE @get_invckey
DEALLOCATE @get_invckey
PrimaryContactKeyを保存し、次の更新ステートメントのset句で再度使用するにはどうすればよいですか?カーソル変数を作成するのですか、それともint型の別のローカル変数を作成するのですか?
DECLARE @tmp_key int
DECLARE @get_invckey cursor
SET @get_invckey = CURSOR FOR
SELECT invckey FROM tarinvoice WHERE confirmtocntctkey IS NULL AND tranno LIKE '%115876'
OPEN @get_invckey
FETCH NEXT FROM @get_invckey INTO @tmp_key
DECLARE @PrimaryContactKey int --or whatever datatype it is
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @PrimaryContactKey=c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey AND i.invckey = @tmp_key
UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey WHERE invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key
END
CLOSE @get_invckey
DEALLOCATE @get_invckey
編集:
この質問は、私が予想していたよりもはるかに多くの関心を集めています。回答でカーソルを使用することを推奨しているのではなく、質問に基づいて値を割り当てる方法を示していることに注意してください。
私はちょうど同じ問題を抱えていました...
declare @userId uniqueidentifier
set @userId = (select top 1 UserId from aspnet_Users)
またはさらに短い:
declare @userId uniqueidentifier
SELECT TOP 1 @userId = UserId FROM aspnet_Users
これを試して
SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey
AND i.invckey = @tmp_key
UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey
WHERE invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key
この変数は、ループの外側で標準のTSQL変数として宣言します。
また、これは、カーソルを処理するときだけでなく、変数へのあらゆるタイプの選択に対してこれを行う方法であることに注意する必要があります。
なぜカーソルが必要なのですか?コードのセグメント全体をこれに置き換えることができます。これにより、多数の行ではるかに高速に実行されます。
UPDATE tarinvoice set confirmtocntctkey = PrimaryCntctKey
FROM tarinvoice INNER JOIN tarcustomer ON tarinvoice.custkey = tarcustomer.custkey
WHERE confirmtocntctkey is null and tranno like '%115876'
変数を安全に割り当てるには、SET-SELECTステートメントを使用する必要があります。
SET @PrimaryContactKey = (SELECT c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey
AND i.invckey = @tmp_key)
開始括弧と終了括弧の両方があることを確認してください!
SET-SELECTバージョンが変数を設定する最も安全な方法である理由は2つあります。
1。 SELECTはいくつかの投稿を返します
次の選択の結果、複数の投稿が発生した場合はどうなりますか?
SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey
AND i.invckey = @tmp_key
@PrimaryContactKey
には、結果のlast postの値が割り当てられます。
実際、@PrimaryContactKey
には結果の投稿ごとに1つの値が割り当てられるため、結果としてSELECTコマンドが処理していた最後の投稿の値が含まれます。
どのポストが「最後」であるかは、クラスター化インデックスによって決定されます。クラスター化インデックスが使用されていない場合、または主キーがクラスター化されている場合、「最後」のポストは最後に追加されたポストになります。この動作は、最悪の場合、テーブルのインデックスが変更されるたびに変更される可能性があります。
SET-SELECTステートメントを使用すると、変数はnull
に設定されます。
2。 SELECTは投稿を返しません
選択が結果をまったく返さない場合、コードの2番目のバージョンを使用するとどうなりますか?
変数の値がnullにならないと思われるものとは反対に-以前の値を保持します!
これは、上記のように、SQLが投稿ごとに変数に値を割り当てるためです-結果に投稿が含まれていない場合、変数を使用して何もしません。したがって、変数は、ステートメントを実行する前の値のままです。
SET-SELECTステートメントを使用すると、値はnull
になります。