-1
ALTER TRIGGER t1
ON dbo.Customers

FOR INSERT
AS

BEGIN TRANSACTION

/* variables */

DECLARE
    @maxid bigint

SELECT @customerid = id FROM inserted

SET IDENTITY_INSERT dbo.new_table ON

DECLARE
    @maxid bigint

SELECT @maxid = MAX(ID) FROM new_table

INSERT INTO new_table (ID, ParentID, Foo, Bar, Buzz)
    SELECT ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz FROM initial_table

SET IDENTITY_INSERT dbo.new_tableOFF

/* execute */
COMMIT TRANSACTION

GO

次のエラーで失敗します:

SQL Server サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。

修正方法は?

私がやろうとしていることは

  • 挿入idparentid、それぞれ増加@maxid
  • からinitial_table
  • の中へnew_table

thnx

new_table

id (bigint) 
parentid (bigint - linked to id) 
foo | bar | buzz (others are nvarchar, not really important)

初期テーブル

id (bigint) 
parentid (bigint - linked to id)
foo | bar | buzz (others are nvarchar, not really important)
4

5 に答える 5

3

あなたは私が疑ういくつかのエラーと戦っています。

1. new_table の一意制約に違反する値を挿入しています。挿入先のテーブルに対して結合することにより、存在エラーを回避します。テーブルの制約に合わせて結合条件を調整します。

insert into new_table (ID, ParentID, Foo, Bar, Buzz)
    select  ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz 
    from    initial_table i
    left
    join    new_table N on 
            i.ID+@maxid = n.ID or 
            i.ParentID+@maxid = n.ParentId
    where   n.ID is null --make sure its not already there

2. どこかで、サブクエリが複数の行を予期していた場所に返しました。サブクエリ エラーは、dbo.Customer (t1 のトリガー) に挿入されるコード内か、または new_table で定義されたトリガー内にある可能性があります。サブクエリ例外をスローする投稿されたコードには何も表示されません。

トリガーが定義されているテーブルにトリガー (別名、地雷) を挿入することは、苦痛のレシピです。可能であれば、このロジックの一部をトリガーからリファクタリングして、論理的に従うことができるコードにします。

于 2012-05-18T18:50:49.160 に答える
2

まず、挿入または削除されたレコードが複数あると想定する必要があります。挿入または削除されたテーブルの値を、SQLサーバートリガーのスカラー変数に設定しないでください。挿入に複数のレコードが含まれている場合は問題が発生し、遅かれ早かれ問題が発生します。

次に、トリガーにID挿入を設定することを検討するべきではありません。何を考えていたのですか?IDフィールドがある場合はそれを使用し、手動で値を作成しようとしないでください。

次に、サブクエリの問題は、一度に1つのレコードのみが処理されると想定している他のトリガーに明らかに関連しています。データベース内のすべてのトリガーを調べて、この基本的な問題を修正する必要があると思います。

コードのこの部分を実行すると、次のようになります。

INSERT INTO new_table (ID, ParentID, Foo, Bar, Buzz) 
SELECT ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz FROM initial_table 

挿入されたレコードだけでなく、すべてのレコードをテーブルに挿入しようとしています。したがって、他のテーブルのトリガーが正しく書き込まれていないため、エラーが発生し、同じPKを持つ2000レコードを新しいテーブルに挿入しようとしたときに発生するエラーが実際に隠されています。 PK、それはあなたが1つのレコードを挿入するたびにそれらすべてを喜んで挿入します。

于 2012-05-18T19:55:09.573 に答える
1

次のステートメントを含むトリガーがあります。

SELECT @customerid = id FROM inserted

表には、挿入された (またはトリガーinsertedのために更新された) 行ごとに 1 行が含まれます。UPDATE複数の行を挿入するステートメントが実行され、トリガーが起動され、仮定が明らかになりました。

単一の行ではなく、行セットを操作するようにトリガーを再コーディングします。

于 2012-05-18T19:52:00.460 に答える
-1

任意の種類の選択でサブクエリを使用している場合は、サブクエリが複数ではなく 1 つの値のみを返すようにクエリを調整してください。

複数が必要な場合は、テーブルがメイン クエリの一部になるようにクエリを再構築します。

SQL の例を示しています。col2 が複数の行を返す場合、クエリは失敗し、次のように書き直します。

table1、table2 から col1、col2 を選択します。ここで、table2.col3=table1.col4;

要点を理解していただければ幸いです。

于 2012-05-18T18:51:08.457 に答える
-3

SELECT するのではなく、SET する必要があります。

SET @maxid = MAX(ID) FROM another_table 
于 2012-05-18T18:45:50.660 に答える