2011-01-26 16 views
0

を助けてください、私はDBのテーブルに存在しないランダムな値を選択するには、次のSQL文をしました:このT-SQLクエリ:無効な列名、

select CONVERT(INT, 1 + 999999999 * rand()) as NEW_DVAL 
WHERE NEW_DVAL NOT IN (SELECT FIELD_DVAL FROM dbo.MASTER_REF) 

それはで完了エラー:列名が無効です。

私はそれをやり遂げる方法が見つからないので、お手数をお掛けしてください。

ありがとうございます! ウィリアム

答えて

1

残念ながら、where句に別名( "NEW_DVAL")を使用することはできません。私はあなたのクエリはあなたがとにかくやりたいことではないだろうと思われること、しかし

select NEW_DVAL from (
    select CONVERT(INT, 1 + 999999999 * rand()) as NEW_DVAL 
) a 
WHERE NEW_DVAL NOT IN (SELECT FIELD_DVAL FROM dbo.MASTER_REF) 

:あなたはこれを行うことができます。 "select convert(...)"ビットは、 "where"ビットがフィルタリングされるかどうかを示す1つの行を与えます。

ランダムに選択された新しいdvalがすでに存在する場合、クエリは行を返しません。未使用のものが見つかるまで自動的にループしません。

これを解決するにはK Ivanov's answerをご覧ください。

+0

あなたが得るときに問題がありますコリジョンは空のレコードセットを返し、値が返されるまで呼び出し元に繰り返し実行されます。 –

+0

Blorgbeardありがとう!それは素晴らしい。 –

+0

@ウィリアム問題はありませんが、Kイワノフの答えも見てください。私のソリューションは、衝突が発生したときに失敗します。 – Blorgbeard

2

あなたは保証の戻り値をしたい場合、テーブルはすべての可能な値が含まれていない限り、あなたが勝つ衝突に新しいrandomsを生成し続ける必要があり、そのようなこと:

DECLARE @NEW_DVAL AS INT; 

WHILE 1=1 
BEGIN 
    SET @NEW_DVAL = CONVERT(INT, 1 + 999999999 * RAND()); 

    IF NOT EXISTS(SELECT * FROM dbo.MASTER_REF WHERE @NEW_DVAL = FIELD_DVAL) 
     BREAK; 
END; 

SELECT @NEW_DVAL; 
+0

もちろん、その値をMASTER_REFの 'INSERT'に使うつもりなら、この' SELECT'ループと 'INSERT'を適切な分離(ロックヒント)を持つトランザクションの中に入れたほうがよいでしょう。さもなければ、INSERTが試みられるまでに、未使用のID値が別の接続によって挿入された可能性があります。 –