«ВМЕСТО» в триггере MySQL, преобразованном из SQL Server

avatar
Shafique
1 июля 2021 в 20:27
72
2
1

Я занимаюсь преобразованием некоторых триггеров SQL Server в MySQL и столкнулся с некоторыми проблемами синтаксиса. Остальная часть схемы базы данных и объекты были преобразованы с помощью AWS Schema Conversion Tool, поскольку я переношу базу данных SQL Server на Aurora RDS MySQL. Вот пример триггера, который мне не удается преобразовать:

.
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER [dbo].[UpdateAUD] ON [dbo].[AUD]
INSTEAD OF UPDATE
AS
BEGIN
  IF @@ROWCOUNT > 0
  BEGIN
    RAISERROR( 'Audit rows for AUD cannot be updated!', -1, 0 );
    ROLLBACK;
  END
END;

Код, который я пробовал, выглядит так:

DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD 
AFTER UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
    set msg = ('Audit rows for AUD cannot be updated!');
    signal sqlstate '45000' set message_text = msg;
    ROLLBACK;
END$$

Во-первых, AFTER подходит для замены INSTEAD OF? Во-вторых, у MySQL Workbench есть проблема с RAISERROR, для которой я искал обходные пути. Однако ошибка, которую я получаю, связана с переменной msg, где написано Unknown system variable 'msg'

Есть идеи?

Источник
Dale K
1 июля 2021 в 20:30
0

Я предлагаю прочитать документацию по каждому продукту, чтобы определить, как работают части синтаксиса. И не помечайте SQL Server, поскольку вы ищете кого-то с опытом работы с MySQL.

Alejandro
1 июля 2021 в 20:33
0

Это то, с чем вы можете лучше справиться, отказав разрешениям UPDATE для выбранных пользователей, что намного лучше, чем триггеры. Как в SQL Server, так и в MySQL.

Shafique
1 июля 2021 в 20:42
0

Я также пометил там SQL, поскольку исходный синтаксис исходит из базы данных SQL Server, и его функциональность должна быть продублирована в MySQL.

Bill Karwin
1 июля 2021 в 20:55
0

Пожалуйста, используйте тег sql для языка SQL, независимо от какой-либо реализации, и тег sql-server для Microsoft SQL Server.

Dale K
1 июля 2021 в 20:58
0

Не помечайте SQL Server, потому что эксперт по SQL Server не обязательно является экспертом по MySQL. И вместо того, чтобы говорить, что мне нужна эта функциональность, реализованная в SQL Server, объясните свои фактические требования независимо от RBDMS.

Ответы (2)

avatar
nbk
1 июля 2021 в 20:45
1

Это должен быть ТРИГГЕР ПЕРЕД ОБНОВЛЕНИЕМ, чтобы ОБНОВЛЕНИЕ было прервано

Вы также можете

REVOKE UPDATE ON AUD FROM '*'@'localhost';

поэтому никто больше не мог ОБНОВИТЬ таблицу

CREATE TABLE AUD (id int)
INSERT INTO AUD VALUES(1)
CREATE TRIGGER UpdateAUD 
BEFORE UPDATE
ON AUD FOR EACH ROW
BEGIN
    set @msg := 'Audit rows for AUD cannot be updated!';
    signal sqlstate '45000' set message_text = @msg;
END
UPDATE AUD SET  id = 1 WHERE id = 1
Audit rows for AUD cannot be updated!

дб<>скрипка здесь

avatar
Shafique
1 июля 2021 в 20:53
0

В итоге я перешел на

DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD  
BEFORE UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
    signal sqlstate '45000' set message_text = 'Audit rows for AUD cannot be updated!';
END$$

Согласно документации, нет необходимости в ROWCOUNT, так как с этим должен справиться FOR EACH ROW. Что касается ROLLBACK, я проверил https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html и увидел, что его тоже следует обрабатывать.

Похоже ли это на хорошее преобразование оригинального MS-SQL, размещенного вверху?

nbk
1 июля 2021 в 20:56
0

это моя копия, как видите работает

Shafique
5 июля 2021 в 16:01
0

Да, я отметил ваш ответ как ответ и проголосовал за