Ошибка вставки нескольких строк в представление с помощью триггера INSTEAD OF
У меня есть таблица карт, которая хранит местоположение с помощью GEOGRAPHY
тип. Поскольку Entity Framework Core не поддерживает пространственные типы, я должен отобразить MapView
смотреть вместо Lat
а также Long
столбцы в моем приложении. Затем я преобразую эти Lat
а также Long
значения в geography::Point
при вставке или обновлении в представлении с помощью INSTEAD OF
триггеры.
Пример:
CREATE TRIGGER [dbo].[MapViewInsertInstead] ON [dbo].[MapView]
INSTEAD OF INSERT
AS
IF ((SELECT Lat FROM inserted) IS NOT NULL AND (SELECT Long FROM inserted) IS NOT NULL)
BEGIN
INSERT INTO [dbo].[Map] (HouseId, HousePoint)
SELECT HouseId
geography::Point(Lat, Long, 4326)
FROM inserted
END
Некоторое время это работало нормально, но я всегда вставлял строки по одной за раз. Сейчас я выполняю задачу массового импорта данных, которая включает данные карты. При одновременной вставке нескольких строк в представление, например:
INSERT INTO MapView (HouseId, Lat, Long)
VALUES(0x1, 10, 10), (0x2, 10, 10);
Я получаю эту ошибку:
Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.
Так что этот триггер работает только при одновременной вставке одной строки карты. Есть ли что-то, что я могу изменить внутри триггера, чтобы можно было вставлять несколько строк?
2 ответа
Это потому, что это утверждение:
(SELECT Lat FROM inserted) IS NOT NULL
Ожидается одно значение для сравнения с условием.
Что вы могли бы сделать, это переписать логику, избавившись от IF
заявление и вместо этого включить проверку в INSERT
Само заявление:
CREATE TRIGGER [dbo].[MapViewInsertInstead] ON [dbo].[MapView]
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO [dbo].[Map] (HouseId, HousePoint)
SELECT HouseId
geography::Point(Lat, Long, 4326)
FROM inserted
WHERE Lat IS NOT NULL
AND Long IS NOT NULL
END
Вы, вероятно, не хотите, чтобы неверный INSERT молча потерпел неудачу. Так что просто пропустите нулевую проверку и geography::Point
Функция выдаст ошибку, если кто-то попытается вставить NULL. НАПРИМЕР
CREATE OR ALTER TRIGGER [dbo].[MapViewInsertInstead] ON [dbo].[MapView]
INSTEAD OF INSERT
AS
BEGIN
set nocount on;
INSERT INTO [dbo].[Map] (HouseId, HousePoint)
SELECT HouseId, geography::Point(Lat, Long, 4326)
FROM inserted;
END