Есть ли лучший / альтернативный способ написания запроса, который принимает оператор арифметики c, чем использование Dynami c SQL? - PullRequest
0 голосов
/ 10 февраля 2020

Я пишу хранимую процедуру, в которой мне нужно обновить определенное количество продукта c (очевидно, я могу увеличить или уменьшить его). Поскольку единственное отличие - это значение оператора (+ или -), я бы хотел использовать одну и ту же процедуру в обоих случаях. Я знаю, что на этот вопрос уже был дан ответ - Выполните математическое выражение и установите значение переменной в SQL, но это мне не поможет, потому что они написали его в MS SQL. Кто-нибудь знает, как я могу сделать это в MYSQL? Правильно ли, следующий код - лучшее решение, если я напишу в MYSQL?

BEGIN

SET @foundID = -1,@name=name, @company=company;
SET @number=number, @action=plusMinus;
CALL spCheckIfProductExists(@name,@company,@foundID);

IF (@foundID != -1 AND (@action='+' OR @action='-'))
 THEN SET @sql = concat("UPDATE instock SET quantity = quantity",@action , " @number WHERE productid= @foundID");
 PREPARE update_statement FROM @sql;
 EXECUTE update_statement;
 DEALLOCATE PREPARE update_statement;
END IF;
END

Это рабочий код, но я знаю, что объединять строки при написании динамических файлов * 1012 - очень плохая практика. * хранимая процедура. Есть идеи как его улучшить?

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Вы можете изменить знак переменной @number на значение @action

BEGIN
  SET @foundID = -1, @name = name, @company = company;
  SET @action = plusMinus;

  CALL spCheckIfProductExists(@name, @company, @foundID);

  IF (@foundID != -1 AND (@action='+' OR @action='-')) THEN
    IF (@action='-') THEN
      SET @number = number;
    ELSE
      SET @number = -number;
    END IF;
    SET @sql = concat("UPDATE instock SET quantity = quantity + ? WHERE productid = ?");

   PREPARE update_statement FROM @sql;
   EXECUTE update_statement USING @number, @foundID;
   DEALLOCATE PREPARE update_statement;

  END IF;
END;
1 голос
/ 10 февраля 2020

Пока он контролируется белым списком и не используется для заполнения контекста значения (который лучше обрабатывается по-другому), он « хорошо »использовать динамически сгенерированный SQL , потому что результирующий оператор SQL контролируется.

Однако, Dynami c SQL - большой молот это добавляет ненужную сложность.

В случае действия «-» просто умножьте значение на -1 (читай: измените знак), прежде чем использовать его в качестве заполнителя или контекст переменной , а затем всегда используйте + в качестве действия: «количество + х» или «количество + (-х)» являются допустимыми. Этот особый случай не будет применяться к другим операторам, таким как «*».

SET @adjustment = CASE WHEN @action = '-' THEN -@number ELSE @number END

UPDATE instock SET quantity = quantity + @adjustment
WHERE productid = @foundID

Даже если разрешить другие операторы, это все равно можно сделать с помощью «CASE @action WHEN ..» и устранить динамику. Генерация c SQL, поскольку сама MySQL будет выполнять различную обработку в зависимости от действия, а само действие указывается только в том случае, если допустимо значение .

 UPDATE instock
 SET quantity = (CASE @action
     WHEN '*' THEN quantity * @number
     WHEN '-' THEN quantity - @number
     WHEN 'e' THEN 2.71828
     ELSE quantity + @number
   END)
 WHERE productid = @foundID

Динамическое построение SQL строк обычно требуется только тогда, когда форма запроса изменяется, и во многих случаях подход к запросу способом, определяющим проблему, c часто приводит к более чистым решениям.

...