我有一个与数据库中几乎每个表相关的转换表。我每次都需要填充这个表。我在其中一个表中插入一个插入。在ORACLE中我这样做了:
INSERT INTO M_ANYTABLE
( ID_ANYTABLE ,
TEXT ,
DATE ,
TRANS_ID
)
VALUES ( 'PEPE' ,
'PEPE' ,
SYSDATE ,
FN_TRD_NOCOMMIT('TEXT TRANSLATE')
);
函数FN_TRD_NOCOMMIT在转换表中进行插入。
我无法在SQLServer中复制它,因为函数无法以任何方式更改数据库。我修复了这个制作触发器(每个表一个)。虽然我知道这不是一个优雅的解决方案。
我要问的是,是否有人可以通过原始插入语句(上面)或通过函数进行插入所部署的任何其他解决方案或任何其他不暗示使用一个触发器的方法来更好地进行插入对于每个表。有什么想法吗?
我希望我正确地指出了我的观点。对不起,英语不好。提前谢谢。
答案 0 :(得分:2)
我不确定我是否理解你,但你可以使用OUTPUT:
CREATE TABLE #test
(
ID_ANYTABLE VARCHAR(123),
TEXT VARCHAR(123) ,
DATE DATETIME
);
CREATE TABLE #test2
(
ID_ANYTABLE VARCHAR(123),
TEXT VARCHAR(123) ,
DATE DATETIME
)
INSERT INTO #test
( ID_ANYTABLE ,
TEXT ,
DATE
)
OUTPUT INSERTED.ID_ANYTABLE, INSERTED.TEXT, INSERTED.DATE INTO #test2
VALUES ( 'PEPE' ,
'PEPE' ,
GETDATE()
);
SELECT * FROM #test
SELECT * FROM #test2
答案 1 :(得分:0)
使用SQL Server stored procedure而不是函数。存储过程可以根据需要插入和更新任意数量的表:
create procedure dbo.SpInsertStuff(@par1 varchar(max))
as
insert into table1 (col1) values (@par1);
insert into table2 (col1) values (@par1);
insert into table3 (col1) values (@par1);
go
exec dbo.SpInsertStuff('Hello World!');
触发器增加了隐含的复杂性:它们以通常不可见和意想不到的方式执行操作。我会远离触发器。
答案 2 :(得分:0)
因此,无论何时您想要插入主子关系并作为单个工作单元工作,首先您需要使用transaction
并使用indentity
选项。
有@@identity
和Scope_identity
。两者都用于捕获最后插入的pk-id,只有差异在事务级别中使用。
所以你的查询就是。无论何时出现错误,它都会回滚其他提交并给出结果。
create procedure procedurename
(
--parmater list
)
as
begin
declare @getmasterid int
begin tran
BEGIN TRY
insert into tblMaster
(
)
values
()
select @getmasterid = SCOPE_IDENTITY
insert into tblchildtable
(
..,masterid,..
)
values
(
..,@getmasterid,..
)
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
end