У меня есть следующий код триггера, который хорошо работает при обновлении одной строки, но не работает при обновлении нескольких строк. Я хотел бы исправить это и искал решения.
Я рассматривал использование курсоров как простой способ решения проблемы, но я знаю, что они являются плохой идеей в триггерах.
Я хочу переписать это «правильным» способом , но я не эксперт в этой области и был бы признателен за некоторую помощь и совет, чтобы правильно переписать его.
Кто-нибудь может помочь?
Это код для текущего триггера:
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Entity_Class_ID as int,
@Entity_Identifier as varchar(50),
@Postcode as varchar(100),
@Latitude as numeric(18,9),
@Longitude as numeric(18,9)
IF EXISTS (SELECT * FROM DELETED) -- Check if an Update and use postcode from inserted
BEGIN
IF (SELECT Postal_Code from INSERTED) != (SELECT Postal_Code from DELETED)
BEGIN
SET @Entity_Class_ID = (SELECT top 1 Entity_Class_ID from INSERTED order by Mailing_Address_ID desc)
SET @Entity_Identifier = (SELECT top 1 Entity_Identifier from INSERTED order by Entity_Identifier desc)
IF @Entity_Class_ID = 3 BEGIN
SET @Postcode = (SELECT top 1 Postal_Code from INSERTED order by Mailing_Address_ID desc)
IF @Postcode is not null BEGIN
DECLARE @URL varchar(MAX)
SET @URL = 'http://dev.virtualearth.net/REST/v1/Locations/UK/' +
@Postcode +
'?o=xml&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
DECLARE @Response varchar(8000)
DECLARE @XML xml
DECLARE @obj int
DECLARE @Result int
DECLARE @HTTPStatus int
DECLARE @ErrorMsg varchar(MAX)
EXEC @Result = sp_OACreate 'MSXML2.ServerXMLHttp', @Obj OUT
BEGIN TRY
EXEC @Result = sp_OAMethod @Obj, 'open', NULL, 'GET', @URL, false
EXEC @Result = sp_OAMethod @Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
EXEC @Result = sp_OAMethod @obj, send, NULL, ''
EXEC @Result = sp_OAGetProperty @Obj, 'status', @HTTPStatus OUT
EXEC @Result = sp_OAGetProperty @Obj, 'responseXML.xml', @Response OUT
END TRY
BEGIN CATCH
SET @ErrorMsg = ERROR_MESSAGE()
END CATCH
EXEC @Result = sp_OADestroy @Obj
IF (@ErrorMsg IS NOT NULL) OR (@HTTPStatus <> 200)
BEGIN
SET @ErrorMsg = 'Error in spGeocode: ' + ISNULL(@ErrorMsg, 'HTTP result is: ' + CAST(@HTTPStatus AS varchar(10)))
RAISERROR(@ErrorMsg, 16, 1, @HTTPStatus)
RETURN
END
SET @XML = CAST(@Response AS XML)
SET @Latitude = @XML.value('
declare namespace BM="http://schemas.microsoft.com/search/local/ws/rest/v1";
(/BM:Response/BM:ResourceSets/BM:ResourceSet/BM:Resources/BM:Location/BM:Point/BM:Latitude)[1]', 'numeric(18,9)')
SET @Longitude = @XML.value('
declare namespace BM="http://schemas.microsoft.com/search/local/ws/rest/v1";
(/BM:Response/BM:ResourceSets/BM:ResourceSet/BM:Resources/BM:Location/BM:Point/BM:Longitude)[1]', 'numeric(18,9)')
END
IF EXISTS (SELECT * FROM EXT_BI_Additional_Fields WHERE Project_ID = @Entity_Identifier)
UPDATE EXT_BI_Additional_Fields SET Latitude = @Latitude, Longitude = @Longitude
WHERE Project_ID = @Entity_Identifier
ELSE
INSERT INTO EXT_BI_Additional_Fields (Project_ID, Latitude, Longitude, Project_Number, Project_Code)
select TOP (1) Project_ID, @Latitude, @Longitude, null as Project_Number, Project_Code
from dbo.Project
WHERE Project_ID = @Entity_Identifier
order by Project_ID DESC
END
END
END
END
Это таблица, в которой находится триггер (Mailing_Address):
Эта таблица обновляется с помощью результаты триггера (EXT_BI_Additional_Fields):
Project_ID Latitude Longitude Project_Number Project_Code
44 51.540180 -0.302364 12255 NULL
46 51.585091 -0.337701 12247 NULL
В настоящее время этот триггер работает так, что при обновлении Postal_Code в таблице «mailing_address» он отправляет обновленное значение Postal_Code в службу REST Bing Maps для геокодирования. Возвращенные значения широты и долготы затем либо вставляются, либо обновляются в таблицу «EXT_BI_Additional_Fields».
Для простоты обслуживания / читабельности человеком, указанная выше вставка также извлекает значения Project_Number и Project_Code из таблицы «Project»