Во-первых, вот несколько таблиц и данных для теста:
CREATE TABLE [dbo].[MyOrders]
(
[ID] [int] NOT NULL,
[ref_type] [nchar](1) NOT NULL,
[ref_num] [nvarchar](15) NULL,
[req_cert] [nvarchar](255) NULL,
CONSTRAINT [PK_MyOrders] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[MyJobs]
(
[job_id] [nvarchar](15) NOT NULL,
[job_message] [nvarchar](255) NULL,
CONSTRAINT [PK_MyJobs] PRIMARY KEY CLUSTERED
(
[job_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[MyTypes]
(
[type] [nvarchar](255) NOT NULL,
[value] [nvarchar](255) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[MyOrders] ([ID], [ref_type], [ref_num], [req_cert])
VALUES (1, 'J', 'Job0001', 'Cert1')
GO
INSERT INTO [dbo].[MyJobs] ([job_id], [job_message])
VALUES ('Job0001', 'Accepted')
GO
INSERT INTO [dbo].[MyTypes] ([type], [value])
VALUES ('MyCerts', 'Cert1'),
('MyCerts', 'Cert2')
GO
Таблица MyOrders
содержит мои заказы, которые могут ссылаться на работу в таблице MyJobs
. MyOrder
может указывать req_cert
, который затем будет отображаться в поле job_message
. req_cert
будет иметь значения из таблицы MyTypes
, где type == 'MyCert'
Я пытаюсь создать триггер, который при обновлении таблицы req_cert
или ref_num
таблицы MyOrders
выполняет следующие действия:
Обновлено ли одно из этих 2 полей?
Это ref_type == J
и ref_num is not null
?
Выберите существующий job_message
и проверьте, нет ли значения в таблице MyTypes
.
Если есть, заменить его значением от req_cert
Если нет, добавьте req_cert
Я написал этот триггер для этого, но я не знаю, лучший ли это способ:
ALTER TRIGGER [dbo].[UpdateCert]
ON [dbo].[MyOrders]
FOR UPDATE
AS
SET NOCOUNT ON
IF (NOT UPDATE ([req_cert])
AND NOT UPDATE ([ref_num]))
RETURN
DECLARE @ID NVARCHAR(50)
DECLARE @Certificate NVARCHAR(255)
DECLARE @OldValue NVARCHAR(255)
DECLARE @Found TINYINT
DECLARE @JobMessage NVARCHAR(2000)
DECLARE InsertCursor CURSOR FAST_FORWARD FOR
SELECT ref_num, req_cert
FROM Inserted
OPEN InsertCursor
FETCH NEXT FROM InsertCursor INTO @ID, @Certificate
WHILE @@FETCH_STATUS = 0
BEGIN
IF (NOT EXISTS (SELECT ref_num
FROM MyOrders
WHERE ref_type = 'J'
AND ref_num = @ID))
BEGIN
FETCH NEXT FROM InsertCursor INTO @ID, @Certificate
CONTINUE
END
SELECT @JobMessage = job_message
FROM MyJobs
WHERE job_id = @ID
DECLARE CertCursor CURSOR FAST_FORWARD FOR
SELECT [Value]
FROM MyTypes
WHERE [Type] = 'MyCerts'
OPEN CertCursor
FETCH NEXT FROM CertCursor INTO @OldValue
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@JobMessage LIKE '%' + @OldValue + '%')
BEGIN
SET @Found = 1
BREAK
END
FETCH NEXT FROM CertCursor INTO @OldValue
END
CLOSE CertCursor
DEALLOCATE CertCursor
IF (@Found = 1)
BEGIN
SELECT @JobMessage = REPLACE(@JobMessage, @OldValue, '')
END
UPDATE MyJobs WITH (ROWLOCK)
SET job_message = ISNULL(@Certificate, '') + ISNULL(@JobMessage, '')
WHERE MyJobs.job_id = @ID
FETCH NEXT FROM InsertCursor INTO @ID, @Certificate
END
CLOSE InsertCursor
DEALLOCATE InsertCursor
УСКОРЕННЫЕ РЕЗУЛЬТАТЫ (при условии данных сверху):
UPDATE MyOrders
SET req_cert = 'Cert1'
WHERE ID = 1
job_message
должно быть Cert1 Accepted
UPDATE MyOrders
SET req_cert = 'Cert2'
WHERE ID = 1
job message
должно быть Cert2 Accepted
UPDATE MyOrders
SET ref_num = null
WHERE ID = 1
GO
UPDATE MyOrders
SET req_cert = 'Cert1'
WHERE ID = 1
GO
UPDATE MyOrders
SET ref_num = 'Job0001'
WHERE ID = 1
job message
должно быть Cert1 Accepted