0

SQLServerのテーブルの例。

  • MainRecordsid, record
  • AuxRecordsmainRecords_id, record
  • SourceRecordsrecord1, record2

MainRecords.id自己増分型のプライマリIDキーです。

、、、およびすべてを1つのステートメントで選択し、同時にSourceRecords挿入することは可能ですか?MainRecordsAuxRecordsMainRecords.record = record1AuxRecords.record = record2AuxRecords.mainRecords_id = MainRecords.id

編集:

下からのヒントに基づいて、私はこれを試しました...

DECLARE @MainRecords table(id int PRIMARY KEY IDENTITY, record varchar(5))
DECLARE @AuxRecords table(mainRecords_id int, record varchar(5))
DECLARE @SourceRecords table(record1 varchar(5), record2 varchar(5))

INSERT @SourceRecords VALUES ('a', 'a')
INSERT @SourceRecords VALUES ('a', 'b')
INSERT @SourceRecords VALUES ('a', 'c')
INSERT @SourceRecords VALUES ('b', 'a')
INSERT @SourceRecords VALUES ('b', 'b')
INSERT @SourceRecords VALUES ('b', 'c')
INSERT @SourceRecords VALUES ('c', 'a')
INSERT @SourceRecords VALUES ('c', 'b')
INSERT @SourceRecords VALUES ('c', 'c')

INSERT INTO @MainRecords (record)
  OUTPUT inserted.id, @SourceRecords.record2
  INTO @AuxRecords (mainRecords_id, record)
SELECT record1 FROM @SourceRecords

select * from @MainRecords
select * from @AuxRecords

しかし、残念ながらエラーが発生します。

Msg 137, Level 16, State 1, Line 16
Must declare the scalar variable "@SourceRecords".

これらのテーブル型変数を実際のテーブルに変更すると、エラーが発生します。

Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "SourceRecords.record2" could not be bound.

以下は問題なく動作しますが、明らかに完全な解決策ではありません。構文が正しいことを示すために表示しています。

INSERT INTO @MainRecords (record)
  OUTPUT inserted.id --, @SourceRecords.record2
  INTO @AuxRecords (mainRecords_id) --, record)
SELECT record1 FROM @SourceRecords

だから...私が見逃しているトリックがない限りOUTPUT、この問題の行き止まりの解決策のようです。

トリガーを使用してビューまたは空のテーブルを作成する他の提案は、問題に対する「単一ステートメント」の解決策ではありません。さらに、それらはあいまいさを追加しますが、いくつかの余分な列を追加し、ストアドプロシージャを使用することも同様に複雑ですが、より明白で簡単です。

4

3 に答える 3

1

コミュニティウィキ

質問を解決するためのコードを書くのに十分な情報が質問にありません。したがって、これは「一般的な」出力句の例です。これは、OUTPUTの使用方法を示す以外は、この質問とはまったく関係ありません。

これにより、1つのステートメントで複数の行が削除、挿入、および返されます

DECLARE @OldTable table(col1 int, col2    varchar(5), col3 char(5), col4     datetime)
DECLARE @NewTable table(col1 int, column2 varchar(5), col3 int    , col_date char(23), extravalue int, othervalue varchar(5))
INSERT @OldTable VALUES (1 , 'AAA' ,'A'  ,'1/1/2010'           )
INSERT @OldTable VALUES (2 , 'BBB' ,'12' ,'2010-02-02 10:11:22')
INSERT @OldTable VALUES (3 , 'CCC' ,null ,null                 )
INSERT @OldTable VALUES (4 , 'B'   ,'bb' ,'2010-03-02'         )

DELETE @OldTable           --<<<alter table 1
    OUTPUT DELETED.col1    --<<<alter table 2
          ,DELETED.col2
          ,CASE
               WHEN ISNUMERIC(DELETED.col3)=1 THEN DELETED.col3 
               ELSE NULL END
          ,DELETED.col4
          ,CONVERT(varchar(5),DELETED.col1)+'!!'
        INTO @NewTable (col1, column2, col3, col_date, othervalue)
    OUTPUT 'Rows Deleted: ', DELETED.* --<<<returns a result set
    WHERE col1 IN (2,4)

SELECT * FROM @NewTable

出力:

               col1        col2  col3  col4
-------------- ----------- ----- ----- -----------------------
Rows Deleted:  2           BBB   12    2010-02-02 10:11:22.000
Rows Deleted:  4           B     bb    2010-03-02 00:00:00.000

(2 row(s) affected)

col1        column2 col3        col_date                extravalue  othervalue
----------- ------- ----------- ----------------------- ----------- ----------
2           BBB     12          Feb  2 2010 10:11AM     NULL        2!!
4           B       NULL        Mar  2 2010 12:00AM     NULL        4!!

(2 row(s) affected)
于 2012-12-10T18:46:00.117 に答える
0

実用的な観点から、@BStatehamと@RBarryYoungはあなたに正解と完全な答えを与えました。ただし、これが技術的な質問であり、それが可能かどうかだけを知りたい場合は、「はい」と言います。

record1、record2の2つの列を含む偽のテーブルを導入します。

次に、このテーブルにINSTEAD OF INSERTトリガーを作成します。これにより、他の2つのテーブルに情報が追加されます。

1つのステートメント'INSERTINTO MyBogusTable(record1、record2)VALUES(1,2)'を実行すると、実際には1つのステートメントを使用して2つの異なるテーブルに値が挿入されます。

とにかく、これは醜いのでお勧めできません。それは愚かで困惑しています(この単語にはtranslate.googleを使用する必要がありました)。

しかし:「それは可能ですか?」という質問に「はい」と答える可能性が1つあります。わかりました、ストアドプロシージャを呼び出すことも「単一のステートメント」ですが、...えーと...まあ。

于 2012-12-10T18:44:00.277 に答える
0

@DG1つのステートメントで複数のテーブルを変更することはできません。@RBarryYoungが示唆しているように、この種のことはストアドプロシージャとトランザクションを使用して行う必要があります。もう1つの極端なオプションは、行を結合するMainRecordsとAuxRecordsにビューを作成し、次にビューにbeforeトリガーを作成して、各ベーステーブルに対して1つずつ、2つの挿入に分割することです。その後、クライアントはビューに1回挿入することができます。全体として、ストアドプロシージャ/トランザクションのアプローチはより明白だと思います。

于 2012-12-10T18:14:02.103 に答える