1

そのため、次のトリガーを使用して、テーブルの行が更新されたときに、特定の列を 8 つのランダムな英数字の文字列に設定しようとしています。結果が一意でなければならないことを除いて、トリガーは正常に機能します。トリガーの前は空白になるため、この一意性はサーバーで強制されません。アイデアは、顧客がプロセスで十分に進んだら、この文字列を取得しますが、そこまで到達していない顧客がたくさんいるため、それ以前ではありません.

引き金:

CREATE TRIGGER test_rand
ON test_trigger
AFTER UPDATE 
AS
    UPDATE test_trigger set col2=(select
    Random_String =
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)+
    substring(x,(abs(checksum(newid()))%36)+1,1)

from
          (select x='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') a) WHERE col2=''; 
GO

このトリガーは、2 つの列しかない単純なテーブルで実行しているテストcol1ですcol2col1私は一連の行を更新しcol2、一見ランダムな値を取得しますが、2 つの行が同じ数になる可能性があることを知っているので、可能であればそれを防ぎたいと思います。

その文字列が存在しないselectステートメント自体でチェックを行うことを考えていましたが、それを行う良い方法を思いつくことができませんでした。

私はトリガーに慣れていないので、単純な何かが欠けていたり、検索されるべきだった場合は、時間を無駄にして申し訳ありません. これは私が知っている限りでは不可能かもしれませんが、あきらめて何か他のことを試す前に質問する必要があると考えました.

また、これが更新を行うスクリプトで行われていない理由は、どのスクリプトが実際にそれを行うかについて、クライアントから直接の回答を得られないためです。これが不可能な場合は、Windows タスク スケジューラで実行するタスクを作成するだけですが、代わりにこれを実行したいと考えていました。

私の解決策

usr が私に言ったことに基づいて、私が望んでいたことを行う次のコードを作成しました。

CREATE TRIGGER test_rand
ON test_trigger
AFTER UPDATE 
AS
    DECLARE @Ins_Col3 int;
    DECLARE Ins_Curs CURSOR FOR SELECT col3 FROM inserted;
    DECLARE @Ref char(8);

    OPEN Ins_Curs

    FETCH NEXT FROM Ins_Curs
    INTO @Ins_Col3;

    WHILE @@FETCH_STATUS = 0
    BEGIN;
        SET @Ref = LEFT(NEWID(), 8);

        WHILE(EXISTS(SELECT col2 from test_trigger WHERE col2=@Ref))
        BEGIN;
            SET @Ref = LEFT(NEWID(), 8);
        END;

        UPDATE test_trigger SET test_trigger.col2=@Ref FROM inserted WHERE test_trigger.col3=@Ins_Col3;
            FETCH NEXT FROM Ins_Curs
        INTO @Ins_Col3;
    END;

col3各行を識別できるように、自動インクリメントされた id 値として 追加する必要がありました。col1したがって、更新ステートメントで何かを変更するためだけに存在します。

4

2 に答える 2

2

8 文字の文字列を無視する代わりに、GUID を使用する必要があります。SQL Server では UniqueIdentifier 列タイプです。これに関する記事は次のとおりです。 http://msdn.microsoft.com/en-us/library/ms190215(v=sql.105).aspx

于 2012-08-28T15:00:04.977 に答える
0

それが起こらないようにしたい場合はWHILE、トリガーにループを含め、生成された文字列が一意性条件に違反するために有効でない限りループします。

WHILE 0=0
BEGIN
 SET_TO_NEW_VALUE
 IF(NEW_VALUE_IS_UNIQUE)
  BREAK
END

ROLLBACKまた、RAISEERROR値が一意でない場合も可能です。何をしたいかによります。

于 2012-08-28T15:00:03.917 に答える