0

SQL Server 的示例表。

  • 主要记录( id, record)
  • 辅助记录( mainRecords_id, record)
  • 源记录( record1, record2)

MainRecords.id是一个自增主标识键。

是否可以在单个语句中同时选择SourceRecords并插入MainRecordsAuxRecords,这样MainRecords.record = record1,AuxRecords.record = record2和all ?AuxRecords.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:

这将在单个语句中删除、插入和返回多行

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

@DG 您不能在单个语句中修改多个表。正如@RBarryYoung 建议的那样,您应该使用存储过程和事务来做这种事情。另一个更极端的选择是在 MainRecords 和 AuxRecords 上创建一个视图,将行连接在一起,然后在视图上创建一个 before 触发器,将其拆分为两个插入,一个针对每个基表。然后,您的客户可以对视图进行一次插入。总而言之,我认为存储过程/事务的方式比较明显。

于 2012-12-10T18:14:02.103 回答
0

从实用的角度来看,@BStateham 和@RBarryYoung 给了你正确和完整的答案。但是,如果这是一个您只想知道是否可行的技术问题,我会说:是的。

引入一个包含两列的伪造表:record1,record2。

然后在这个表上创建一个 INSTEAD OF INSERT 触发器,它只是将信息添加到其他两个表中。

当您执行一条语句“INSERT INTO MyBogusTable (record1,record2) VALUES (1,2)”时,您实际上将使用一条语句将值插入到两个不同的表中。

无论如何,这很丑陋,不推荐。这是愚蠢和莫名其妙的(不得不使用 translate.google 这个词)。

但是:对“可能吗?”这个问题回答“是”是一种可能性。好的,调用存储过程也是“一条语句”,但是……嗯……嗯。

于 2012-12-10T18:44:00.277 回答