Передача имени столбца в качестве параметра хранимой процедуре в mySQL - PullRequest
0 голосов
/ 15 февраля 2019

Я создаю некоторые хранимые процедуры для управления моей БД.В частности, я хочу создать хранимую процедуру для редактирования столбца определенной строки, но я хочу сделать это динамически, передавая имя столбца в качестве аргумента.

Это то, что я хочу сделать

CREATE PROCEDURE myDB.edit_myTable(
    IN key CHAR(16), 
    IN col VARCHAR(100), 
    new_value VARCHAR(200)
)
UPDATE myDB.myTable SET col = new_value

Используя параметр key я нахожу конкретную строку в myTable, которую я хочу редактировать, и я хочу использовать параметр col для редактирования только нужного мне столбца.

Я уже пытался использовать CONCATE() или определять локальные переменные, как я читал в другой теме, но я не нашел решения.

Любая помощь?

1 Ответ

0 голосов
/ 15 февраля 2019

Вам нужно будет использовать динамический SQL :

DELIMITER //
CREATE PROCEDURE myDB.edit_myTable(
    IN key CHAR(16), 
    IN col VARCHAR(100), 
    new_value  VARCHAR(200)
)
BEGIN
    SET @s = CONCAT(
        'UPDATE myDB.myTable SET `', 
         col, '` = ', QUOTE(new_value),
         ' WHERE key = ', QUOTE(key)
    );
    PREPARE stmt FROM @s;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END
//
DELIMITER;

Обратите внимание, что, как прокомментировал Пол Шпигель , использование переменной для имени столбца создаетриск внедрения SQL.Одним из решений для повышения безопасности было бы убедиться, что входные данные col действительно существуют в целевой таблице, используя информационную схему MySQL:

DELIMITER //
CREATE PROCEDURE myDB.edit_myTable(
    IN key CHAR(16), 
    IN col VARCHAR(100), 
    new_value  VARCHAR(200)
)
BEGIN
    DECLARE col_exists INT;

    SELECT COUNT(*) INTO col_exists 
    FROM  information_schema.COLUMNS
    WHERE TABLENAME = 'mytable' AND COLUMN_NAME = col;

    IF (col_exists != 1) THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = CONCAT('Column ', col, ' does not exist in table mytable');
    END IF;

    SET @s = CONCAT(
        'UPDATE myDB.myTable SET `', 
         col, '` = ', QUOTE(new_value),
         ' WHERE key = ', QUOTE(key)
    );
    PREPARE stmt FROM @s;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END
//
DELIMITER;
...