MySQL сохраненная функция не будет компилироваться с MODIFIES SQL DATA - PullRequest
0 голосов
/ 28 марта 2020

Если я скомпилирую хранимую функцию ниже в MySQL (используя MySQL Workbench 8.0), я получу сообщение:

ОШИБКА 1418: Эта функция не имеет DETERMINISTI C , NO SQL или READS SQL DATA в своем объявлении и двоичное ведение журнала включено ...

Однако, если я изменю MODIFIES SQL DATA на READS SQL DATA, функция компилируется просто отлично , В MySQL руководстве говорится:

MODIFIES SQL DATA указывает, что подпрограмма содержит операторы, которые могут записывать данные (например, INSERT или DELETE).

Так почему MODIFIES SQL DATA не принят? Я понимаю, что эти характеристики являются «только рекомендательными», но я все же хотел бы использовать правильные характеристики c.

CREATE FUNCTION DoSomething(employeeName VARCHAR(30)) RETURNS int(11)
    MODIFIES SQL DATA
BEGIN
   DECLARE income INT;

   SELECT Salary
   INTO income
   FROM Employee
   WHERE Name = employeeName;

   UPDATE Employee
   SET Salary = 300
   WHERE Name = employeeName;

   IF income < 5000 THEN
      RETURN 0;
   ELSE
      RETURN (income - 5000) * 0.1;
   END IF;
END

1 Ответ

1 голос
/ 28 марта 2020

В MySQL 8.0.19 и Workbench достаточно использовать DETERMINISTI C

EDIT:

Чтобы уточнить, такие функции функции, как DETERMINISTI C, NO SQL или READS SQL DATA ничего не решает, а только указывает, что вы приняли решение о его безопасности. Функции с NO SQL или READS SQL DATA четко указывают MySQL, что внутри данных нет манипуляций с данными, и они безопасны.

Используя DETERMINISTI C, вы сообщаете mysql, что это безопасно запускать эту функцию, которая манипулирует данными внутри ..

См. объяснение mysql , которое гласит:

По умолчанию для CREATE Оператор FUNCTION, который должен быть принят, должен быть явно указан как минимум один из DETERMINISTI C, NO SQL или READS SQL DATA.

CREATE DEFINER=`root`@`localhost` FUNCTION `DoSomething`(employeeName VARCHAR(30)) RETURNS int
    DETERMINISTIC
BEGIN
   DECLARE income INT;

   SELECT Salary
   INTO income
   FROM Employee
   WHERE Name = employeeName;

   UPDATE Employee
   SET Salary = 300
   WHERE Name = employeeName;

   IF income < 5000 THEN
      RETURN 0;
   ELSE
      RETURN (income - 5000) * 0.1;
   END IF;
END

Обновляет сотрудника

...