在客户表中更新它们时,我需要记录所有以前的地址和邮政编码。
业务要求:不更改邮政编码也不能更改地址,反之亦然。
需要一种防止这种情况的机制以及相应的错误消息。
我已经创建了表格:
create table tblCustomerAudit
(
CustomerID int identity(1,1) not null,
CustomerName nvarchar(255) null,
CustomerAddress nvarchar(255) null,
CustomerPostcode nvarchar(255) null,
CardNumber nvarchar(255) null,
)
go
alter table tblCustomerAudit
add constraint FK_CustomerAudit
foreign key(CustomerID)
references CstmrEng.tblCustomer(CustomerID)
什么会触发?请帮忙!
答案 0 :(得分:0)
也许您可以使用存储过程来做到这一点?请注意,存储过程不是魔术般的尘土,维护它们可能是一场噩梦。
您可以让触发器调用存储过程,该存储过程处理CustomerAddress和CustomerPostcode之间的特定约束。
此代码未经测试,可能无法正常工作。
CREATE PROCEDURE UpdateCustomerAddressAndPostcode @CustomerID INT, @CustomerAddress NVARCHAR(255), @CustomerPostcode NVARCHAR(255)
AS BEGIN
IF (@CustomerAddress IS NULL OR @CustomerAddress = '')
BEGIN
PRINT 'Customer address must be present to modify Customer table.';
THROW;
END
IF (@CustomerPostcode IS NULL OR @CustomerPostcode = '')
BEGIN
PRINT 'Customer postcode must be present to modify Customer table.';
THROW;
END
INSERT INTO tblCustomerAudit (CustomerID, CustomerName, CustomerAddress, CustomerPostcode, CardNumber)
SELECT CustomerID, CustomerName, CustomerAddress, CustomerPostcode, CardNumber FROM Customer where CustomerID = @CustomerID;
-- just printing the table for example
SELECT * FROM tblCustomerAudit
-- make the change to Customer here or in the trigger
END
GO
CREATE TRIGGER CustomerTrigger
ON [dbo].[Customer]
INSTEAD OF INSERT
AS
DECLARE @CustomerID int
DECLARE @CustomerAddress nvarchar(255)
DECLARE @CustomerPostcode nvarchar(255)
BEGIN
SET NOCOUNT ON;
-- verify the data
EXEC UpdateCustomerAddressAndPostcode @CustomerID, @CustomerAddress, @CustomerPostcode
-- do the Customer change here or in the stored procedure
END
答案 1 :(得分:0)
我真的建议使用存储过程来控制更新,插入和删除,因此您将使用存储过程将值传递到表之前。如果使用触发器,则将实际更改值,然后将触发该触发器,如果满足条件,则必须从触发器中使用旧值重新更新表。因此,这对我来说是一种冗余,这就是为什么我建议使用存储过程在更改表值之前处理所有问题的原因。
无论如何,您仍然可以使用具有删除和插入表功能的触发器:
CREATE TRIGGER CustomerUpdate ON tblCustomerAudit
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@CustomerID INT
, @New_CustomerAddress nvarchar(255)
, @New_CustomerPostcode nvarchar(255)
, @Old_CustomerAddress nvarchar(255)
, @Old_CustomerPostcode nvarchar(255)
SELECT
@CustomerID = CustomerID
, @Old_CustomerAddress = CustomerAddress
, @Old_CustomerPostcode = CustomerPostcode
FROM
deleted
SELECT
@New_CustomerAddress = CustomerAddress
, @New_CustomerPostcode = CustomerPostcode
FROM
tblCustomerAudit
WHERE
CustomerID = @CustomerID
IF @Old_CustomerAddress = @New_CustomerAddress OR @New_CustomerPostcode = @Old_CustomerPostcode
BEGIN
-- IF one of them matches return the old values
UPDATE tblCustomerAudit
SET
CustomerAddress = @Old_CustomerAddress
, CustomerPostcode = @Old_CustomerPostcode
WHERE
CustomerID = @CustomerID
-- display an error message
RAISERROR( 'You need to change both address and postcode to save the new values', 18 , 0);
END
END
答案 2 :(得分:0)
类似这样的东西:
CREATE TRIGGER foo.bar ON foo.mytable
AFTER UPDATE
AS
IF (@@ROWCOUNT_BIG = 0)
RETURN;
IF EXISTS (SELECT *
FROM foo.mytable AS t
JOIN inserted AS i
ON t.mykey = i.mykey
WHERE i.addr <> t.addr AND i.post = t.post -- address changes but post code doesn't
OR i.post <> t.post AND i.addr = t.addr -- post code changes by address doesn't
)
BEGIN
RAISERROR ('invalid changes', 16, 1);
ROLLBACK TRANSACTION;
RETURN
END;
GO