MYSQL 存储过程 - 如果满足某些条件,则更新多个列

Posted

技术标签:

【中文标题】MYSQL 存储过程 - 如果满足某些条件,则更新多个列【英文标题】:MYSQL Stored Procedure - Update multiple columns if certain conditions are met 【发布时间】:2019-09-26 15:39:52 【问题描述】:

我的 mysql 相当有限,我已经搜索了很多,但我想确认到目前为止我做了什么。

我正在尝试在 MySQL 中编写一个接受 5 个参数的存储过程。 4 个参数将包含将用于更新的列的值,以及将用于选择要更新的行的第 5 个值。

参数名称:p_name1、p_name2、p_name3、p_name4、p_parentId 列名:NAME_1、NAME_2、NAME_3、NAME_4、PARENT_ID

如果为 p_name1 设置了值,请使用参数值更新列 NAME_1,其中该行的 PARENT_ID = p_parentId AND p_name1 不为空。 对所有列执行此操作。在某些情况下,可能只需要更新几列,因此不会为其他列传递任何内容。 到目前为止,这是我想出的:

BEGIN
    UPDATE `NAMES_TABLE` SET `NAME_1` = p_name1 WHERE `PARENT_ID` = p_parentId AND p_name1 IS NOT NULL;
    UPDATE `NAMES_TABLE` SET `NAME_2` = p_name2 WHERE `PARENT_ID` = p_parentId AND p_name2 IS NOT NULL;
    UPDATE `NAMES_TABLE` SET `NAME_3` = p_name3 WHERE `PARENT_ID` = p_parentId AND p_name3 IS NOT NULL;
    UPDATE `NAMES_TABLE` SET `NAME_4` = p_name4 WHERE `PARENT_ID` = p_parentId AND p_name4 IS NOT NULL;
END

但是,也存在需要将列设置为 null 的情况。也许为此我可以使用某种 If 语句进行更新,如果参数设置为关键字(即“null”作为文本),将列设置为 null,否则如果参数 IS NOT NULL 使用参数值更新,否则不要'根本不更新列。

有没有办法做到这一点?也许在更新中带有 if 或 case 语句?

感谢您能给我的任何帮助。

示例:

带有值的原始表格

+------+-----------+-----------+-----------+----------+--------+
|   ID |  PARENT_ID| NAME_1    | NAME_2    | NAME_3   | NAME_4 | 
+------+-----------+-----------+-----------+----------+--------+
|  1   |  NULL     | APRIL     | AMBER     | ALFRED   | ALEX   |
|  2   | 1         | BOB       | BILL      | BURT     | BELINDA|
|  3   | 1         | BOB       | BILL      | BURT     | BELINDA|
|  4   | NULL      | CHARLES   | CASPER    | CONNOR   | CARL   |
+------+-----------+-----------+-----------+----------+--------+

传入参数:

p_name1 = JAMES, p_name2 = null, p_name3 = JEN, p_name4 = "null", p_parentId = 1

结果:

+------+-----------+-----------+-----------+----------+--------+
|   ID |  PARENT_ID| NAME_1    | NAME_2    | NAME_3   | NAME_4 | 
+------+-----------+-----------+-----------+----------+--------+
|  1   |  NULL     | APRIL     | AMBER     | ALFRED   | ALEX   |
|  2   | 1         | JAMES     | BILL      | JEN      | null   |
|  3   | 1         | JAMES     | BILL      | JEN      | null   |
|  4   | NULL      | CHARLES   | CASPER    | CONNOR   | CARL   |
+------+-----------+-----------+-----------+----------+--------+

【问题讨论】:

@GordonLinoff 更新了原帖 【参考方案1】:

试试这个:


DELIMITER //
CREATE PROCEDURE usp_name (IN @p_name1 varchar(20)) NULL, 
                            IN @p_name2 varchar(20) NULL, 
                            IN @p_name3 varchar(20) NULL, 
                            IN @p_name4 varchar(20) NULL, 
                            IN @p_parentId varchar(20) NULL)
AS
BEGIN

UPDATE NAMES_TABLE 
SET Name_1 = IFNULL(@p_name1, Name_1 ),
    Name_2 = IFNULL(@p_name2, Name_2 ),
    Name_3 = IFNULL(@p_name3, Name_3 ),
    Name_4 = IFNULL(@p_name4, Name_4 )
WHERE 'PARENT_ID' = @p_parentId; 

结束//

分隔符;

【讨论】:

【参考方案2】:

使用ifnull-函数:

BEGIN
  UPDATE NAMES_TABLE SET 
    NAME_1 = ifnull( p_name1, NAME_1),
    NAME_2 = ifnull( p_name2, NAME_2),
    NAME_3 = ifnull( p_name3, NAME_3),
    NAME_4 = ifnull( p_name4, NAME_4)
  WHERE PARENT_ID = p_parentId;
END

【讨论】:

【参考方案3】:

如果需要处理特殊的“null”值,则需要CASE逻辑或多个函数调用:

UPDATE NAMES_TABLE 
    SET Name_1 = (CASE WHEN @p_name1 = '<null>' THEN NULL
                       WHEN @p_name1 IS NOT NULL THEN @p_name1
                       ELSE Name_1
                  END),
        Name_2 = (CASE WHEN @p_name2 = '<null>' THEN NULL
                       WHEN @p_name2 IS NOT NULL THEN @p_name2
                       ELSE Name_2
                  END),
        Name_3 = (CASE WHEN @p_name3 = '<null>' THEN NULL
                       WHEN @p_name3 IS NOT NULL THEN @p_name3
                       ELSE Name_3
                  END),
        Name_4 = (CASE WHEN @p_name4 = '<null>' THEN NULL
                       WHEN @p_name4 IS NOT NULL THEN @p_name4
                       ELSE Name_4
                  END)
WHERE PARENT_ID = @p_parentId; 

如果你愿意,你可以缩短它:

UPDATE NAMES_TABLE 
    SET Name_1 = NULLIF(COALESCE(@p_name1, Name_1), '<null>'),
        Name_2 = NULLIF(COALESCE(@p_name2, Name_2), '<null>'),
        Name_3 = NULLIF(COALESCE(@p_name3, Name_3), '<null>'),
        Name_4 = NULLIF(COALESCE(@p_name4, Name_4), '<null>')
WHERE PARENT_ID = @p_parentId; 

我向刚接触 SQL 的人推荐第一个版本。逻辑很明确。

【讨论】:

这看起来很完美,非常感谢,我会试试这个。我对存储过程完全陌生,是否需要在其中添加任何内容才能在存储过程中使用它?

以上是关于MYSQL 存储过程 - 如果满足某些条件,则更新多个列的主要内容,如果未能解决你的问题,请参考以下文章

mysql 存储过程 若主键冲突则更新,不冲突则插入数据

MySql 条件停止脚本执行

如果在 R 中满足某些行和列之间的条件,则确定一个值

请教一个mysql 存储过程的问题?

pandas:如果满足 3 列中的条件,则更新值

mysql如果条件满足则执行join否则不