如何使用过程更改列的默认值

How to alter the default value of a column using a procedure

这是我当前的 SQL 的样子:

DELIMITER $$
CREATE PROCEDURE updateDefaultUserRole(
    IN rid_in INT
) BEGIN
    ALTER TABLE _users
    MODIFY rid INT(255) NOT NULL DEFAULT rid_in; -- Modify the columns default value
    UPDATE _users SET rid = rid_in WHERE rid < rid_in; -- Update all entries lower than the role ID.
END $$
DELIMITER ;

这是我的数据库 _users table 的样子:

CREATE TABLE `_users` (
  `uid` int(255) NOT NULL,
  `forname` varchar(40) NOT NULL,
  `surname` varchar(40) NOT NULL,
  `email` varchar(120) NOT NULL,
  `hash` varchar(60) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `rid` int(255) NOT NULL DEFAULT '2'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `_users`
  ADD PRIMARY KEY (`uid`),
  ADD KEY `rid` (`rid`);
  MODIFY `uid` int(255) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

我收到这个错误:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'rid_in; -- Modify the columns default value

链接到这一行:

ALTER TABLE _users
MODIFY rid INT(255) NOT NULL DEFAULT rid_in;

如果我更改它,忽略 rid_in 值:

ALTER TABLE _users
MODIFY rid INT(255) NOT NULL DEFAULT '1';

它工作正常,我如何将 rid_in 输入绑定到查询?

我的预期输出是能够用于更改默认用户角色值并将具有旧用户值的所有行更新为新用户值:

CALL updateDefaultUserRole(@someInt)

能够为每个用户更新默认值。

你需要在这里使用Dynamic SQL,因为Alter Table中的Default子句将无法解析变量值:

DELIMITER $$
CREATE PROCEDURE updateDefaultUserRole(
    IN rid_in INT
) BEGIN

    -- generate the query string for Alter Table
    SET @alter_query_str = CONCAT('ALTER TABLE _users
                                   MODIFY rid INT(255) NOT NULL 
                                   DEFAULT ', 
                                  rid_in); -- Modify the columns default value
    -- prepare the query
    PREPARE stmt FROM @alter_query_str;
    -- execute the query
    EXECUTE stmt;
    -- deallocate the query
    DEALLOCATE PREPARE stmt;

    UPDATE _users SET rid = rid_in 
    WHERE rid < rid_in; -- Update all entries lower than the role ID.

END $$
DELIMITER ;