I have a table named ORDERITEMS
.
CREATE TABLE DB2ADMIN.ORDERITEMS (
ORDERITEMS_ID BIGINT NOT NULL,
STOREENT_ID INTEGER NOT NULL,
ORDERS_ID BIGINT NOT NULL,
TERMCOND_ID BIGINT,
TRADING_ID BIGINT,
ITEMSPC_ID BIGINT,
CATENTRY_ID BIGINT,
PARTNUM VARCHAR(64)
);
I need to create a new table named ORDERITEM_LOG
that looks basically the same, but with two additional columns:
CREATE TABLE DB2ADMIN.ORDERITEM_LOG (
ORDERITEMS_ID BIGINT NOT NULL,
STOREENT_ID INTEGER NOT NULL,
ORDERS_ID BIGINT NOT NULL,
TERMCOND_ID BIGINT,
TRADING_ID BIGINT,
ITEMSPC_ID BIGINT,
CATENTRY_ID BIGINT,
PARTNUM VARCHAR(64),
LOG_ACTION_DATE VARCHAR(254),
LOG_ACTION_TYPE VARCHAR(1)
);
I need to make a trigger that watches the ORDERITEMS
table. Whenever a row is inserted, deleted, or updated in the ORDERITEMS
table, the identical operation needs to be done to the ORDERITEM_LOG
table, with the additional two columns being populated with CURRENT TIMESTAMP
, and a 'U'
, 'D'
, or 'I'
(depending on the action taken), respectively.
For example, if I insert a row into the ORDERITEMS
table, I would expect to see a duplicate row inserted into the ORDERITEM_LOG
table, timestamped in LOG_ACTION_DATE
, and an 'I'
in the LOG_ACTION_TYPE
. Then, if I were to delete the row in ORDERITEMS
, I would expect to see the 'I'
updated to a 'D'
in the ORDERITEM_LOG
table, and see the timestamp updated. I'm looking to have the ORDERITEM_LOG
table updated before the ORDERITEMS
table;
How do I write a trigger that would do what I'm looking for?
答案 0 :(得分:0)
触发器的类型 触发器有两种类型。之后和而不是触发器。你必须使用After triggers
1)触发后
执行插入,更新或删除等操作后执行这些触发器。
你必须在触发后使用,如下面
插入后
CREATE TRIGGER [dbo].[Customer_INSERT]
ON [dbo].[Customers]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @OrderItemsID;
DECLARE @StroreentID;
DECLARE @OrdersID;
DECLARE @TermCondID;
DECLARE @TradingID ;
DECLARE @ItemSPCID;
DECLARE @CatentryID;
DECLARE @Partnum;
DECLARE @SysDateTime datetime = SYSDATETIME();
DECLARE @LogActionType VARCHAR(1);
SELECT @OrderItemsID = INSERTED.ORDERITEMS_ID;
SELECT @StroreentID = INSERTED.STOREENT_ID;
SELECT @OrdersID = INSERTED.ORDERS_ID;
SELECT @TermCondID = INSERTED.TERMCOND_ID;
SELECT @TradingID = INSERTED.TRADING_ID;
SELECT @ItemSPCID = INSERTED.ITEMSPC_ID;
SELECT @CatentryID = INSERTED.CATENTRY_ID;
SELECT @Partnum = INSERTED.PARTNUM;
@LogActionType = "1";
FROM INSERTED
INSERT INTO ORDERITEM_LOG
VALUES (@OrderItemsID, @StroreentID, @OrdersID, @TermCondID, @TradingID, @ItemSPCID, @CatentryID, Partnum, LogActionType, @LogActionType)
END
更新后
CREATE TRIGGER [dbo].[Customer_INSERT]
ON [dbo].[Customers]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @OrderItemsID;
DECLARE @StroreentID;
DECLARE @OrdersID;
DECLARE @TermCondID;
DECLARE @TradingID ;
DECLARE @ItemSPCID;
DECLARE @CatentryID;
DECLARE @Partnum;
DECLARE @SysDateTime datetime = SYSDATETIME();
DECLARE @LogActionType VARCHAR(1);
SELECT @OrderItemsID = INSERTED.ORDERITEMS_ID;
SELECT @StroreentID = INSERTED.STOREENT_ID;
SELECT @OrdersID = INSERTED.ORDERS_ID;
SELECT @TermCondID = INSERTED.TERMCOND_ID;
SELECT @TradingID = INSERTED.TRADING_ID;
SELECT @ItemSPCID = INSERTED.ITEMSPC_ID;
SELECT @CatentryID = INSERTED.CATENTRY_ID;
SELECT @Partnum = INSERTED.PARTNUM;
@LogActionType = "1";
FROM INSERTED
INSERT INTO ORDERITEM_LOG
VALUES(@OrderItemsID, @StroreentID,@OrdersID,@TermCondID,@TradingID,@ItemSPCID,@CatentryID,Partnum,LogActionType, @LogActionType)
END
删除后
CREATE TRIGGER [dbo].[Customer_INSERT]
ON [dbo].[Customers]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @OrderItemsID;
DECLARE @StroreentID;
DECLARE @OrdersID;
DECLARE @TermCondID;
DECLARE @TradingID ;
DECLARE @ItemSPCID;
DECLARE @CatentryID;
DECLARE @Partnum;
DECLARE @SysDateTime datetime = SYSDATETIME();
DECLARE @LogActionType VARCHAR(1);
SET @LogActionType = "1";
SELECT @OrderItemsID = DELETED.ORDERITEMS_ID;
SELECT @StroreentID = DELETED.STOREENT_ID;
SELECT @OrdersID = DELETED.ORDERS_ID;
SELECT @TermCondID = DELETED.TERMCOND_ID;
SELECT @TradingID = DELETED.TRADING_ID;
SELECT @ItemSPCID = DELETED.ITEMSPC_ID;
SELECT @CatentryID = DELETED.CATENTRY_ID;
SELECT @Partnum = DELETED.PARTNUM;
INSERT INTO ORDERITEM_LOG
VALUES(@OrderItemsID, @StroreentID,@OrdersID,@TermCondID,@TradingID,@ItemSPCID,@CatentryID,Partnum,LogActionType, @LogActionType)
END
答案 1 :(得分:-1)
If I understand you want to snapshot your changes to table2. Good tactic by the time amount of data will create you a big headache. The sql code you need as below. You may create one trigger for all jobs with tag INSERT,DELETE,UPDATE or you may create seperate 3 triggers. Just pay attention that SQL UPDATE command triggers delete and insert statement in same time.
Below example is using BulkInsert and assume that you log tables exists. If you are updating a few rows at a time there is no problem,but if you are manipulating so many rows at same time probably you will timeout or have so long response time. To prevent that you may prefer to write same statement with where clause targeting primary key ( as where id=XXX) within a WHILE statement.
CREATE TRIGGER [ORDERITEMTRIGGER] ON [ORDERITEMS]
FOR INSERT, UPDATE, DELETE
AS
-- INSERT
set nocount on
insert into ORDERITEM_LOG(
ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
LOG_ACTION_DATE,
LOG_ACTION_TYPE)
select ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
getdate(),'I' from inserted
-- DELETE (this triggers on delete and update because sql update has 2 phase delete and insert)
insert into ORDERITEM_LOG(
ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
LOG_ACTION_DATE,
LOG_ACTION_TYPE)
select ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
getdate(),'D' from deleted
-- UPDATE
set nocount on
insert into ORDERITEM_LOG(
ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
LOG_ACTION_DATE,
LOG_ACTION_TYPE)
select ORDERITEMS_ID,
STOREENT_ID,
ORDERS_ID,
TERMCOND_ID,
TRADING_ID,
ITEMSPC_ID,
CATENTRY_ID,
PARTNUM,
getdate(),'U' from inserted
set nocount off