将列名作为参数传递给 mySQL 中的存储过程
Passing a column name as parameter to a stored procedure in mySQL
我正在创建一些存储过程来管理我的数据库。
特别是,我想创建一个存储过程来编辑特定行的列,但我想以动态方式进行,将列名作为参数传递。
这就是我想做的
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()
或定义局部变量,正如我在其他主题上阅读的那样,但我还没有找到解决方案。
有什么帮助吗?
您需要使用 动态 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;
请注意,正如 Paul Spiegel 评论的那样,使用变量作为列名会产生 SQL 注入风险。提高安全性的一种解决方案是使用 MySQL 信息模式确保输入 col
确实存在于目标 table 中:
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;
我正在创建一些存储过程来管理我的数据库。 特别是,我想创建一个存储过程来编辑特定行的列,但我想以动态方式进行,将列名作为参数传递。
这就是我想做的
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()
或定义局部变量,正如我在其他主题上阅读的那样,但我还没有找到解决方案。
有什么帮助吗?
您需要使用 动态 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;
请注意,正如 Paul Spiegel 评论的那样,使用变量作为列名会产生 SQL 注入风险。提高安全性的一种解决方案是使用 MySQL 信息模式确保输入 col
确实存在于目标 table 中:
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;