SQL Server的示例表。
id, record
)mainRecords_id, record
)record1, record2
) MainRecords.id
是一个自我递增的主要身份密钥。
是否可以从SourceRecords
中选择并同时插入MainRecords
和AuxRecords
,以便MainRecords.record = record1
,AuxRecords.record = record2
和{{1所有在一个声明中?
编辑:
根据下面的提示,我试过了......
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
是这个问题的死胡同解决方案。
使用触发器创建视图或空表的其他建议不是问题的“单一语句”解决方案。此外,它们增加了默默无闻,而添加一些额外的列和使用存储过程同样复杂,但更明显和直接。
答案 0 :(得分: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)
答案 1 :(得分:0)
@DG您无法在单个语句中修改多个表。正如@RBarryYoung建议你应该使用存储过程和事务来做这种事情。另一个更极端的选择是在MainRecords和AuxRecords上创建一个将行连接在一起的视图,然后在视图上创建一个before触发器,将其分成两个插入,一个针对每个基表。然后,您的客户端可以对视图执行单个插入操作。总而言之,我认为存储过程/事务方法更加明显。
答案 2 :(得分:0)
从实际角度来看,@ BStateham和@RarryYoung为您提供了正确而完整的答案。但是,如果这是一个技术问题,你只想知道是否可能,我会说:是的。
引入一个包含两列的伪表:record1,record2。
然后在此表上创建一个INSTEAD OF INSERT触发器,它只是将信息添加到其他两个表中。
执行单个语句'INSERT INTO MyBogusTable(record1,record2)VALUES(1,2)'时,您实际上会使用一个语句将值插入两个不同的表中。
无论如何,这是丑陋的,不推荐。这是愚蠢和令人困惑的(必须使用translate.google这个词)。
但是:对于'是否可能'这个问题,回答“是”是一种可能性。 好的,调用存储过程也是“单一语句”,但是...... aehm ......好吧。