在MySQL 5.7上无效的存储过程语法,但在MariaDB上有效

问题描述 投票:0回答:1

我正在尝试编写一个MySQL脚本,以将管理员用户添加到服务器上的每个WordPress数据库,并更新用户名中已存在的用户信息。

[我做了以下脚本,它在具有innodb_version 5.7.29的MariaDB 10.2.31的服务器上工作,但是在运行MySQL Community Server 5.7.29的服务器上不能工作,我收到一条错误消息:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS (SELECT * FROM cpaneluser_wp.wp_users WHERE user_login = 'newwpuser') THEN' at line 1

这里是创建存储过程的脚本:

-- Create and update a WordPress administrator across all databases
USE mysql;

delimiter $$

DROP PROCEDURE IF EXISTS ensure_global_wp_user $$

CREATE PROCEDURE ensure_global_wp_user(
  IN username VARCHAR(255),
  IN email VARCHAR(255),
  IN password VARCHAR(255),
  IN nicename VARCHAR(255),
  IN displayname VARCHAR(255)
)
BEGIN

DECLARE current_schema VARCHAR(255);
DECLARE finished INTEGER DEFAULT 0;

DECLARE wp_schemas CURSOR FOR
  SELECT DISTINCT table_schema
    FROM INFORMATION_SCHEMA.tables
    WHERE table_name = 'wp_users';

DECLARE CONTINUE HANDLER
  FOR NOT FOUND
  SET finished = 1;

OPEN wp_schemas;

DROP TEMPORARY TABLE IF EXISTS exec_results;
CREATE TEMPORARY TABLE IF NOT EXISTS exec_results (
  username VARCHAR(255),
  dbname VARCHAR(255),
  action VARCHAR(255)
);

loopSchemas: LOOP
  FETCH wp_schemas INTO current_schema;
  IF finished = 1 THEN
    LEAVE loopSchemas;
  END IF;

  SET @expression = CONCAT("
    IF EXISTS (SELECT * FROM ",current_schema,".wp_users WHERE user_login = '",username,"') THEN
      UPDATE ",current_schema,".wp_users
        SET
          user_pass = MD5('",password,"'),
          user_email = '",email,"',
          user_nicename = '",nicename,"',
          display_name = '",displayname,"'
        WHERE user_login = '",username,"';
      INSERT INTO exec_results VALUES ('",username,"','",current_schema,"','updated');
    ELSE
      INSERT INTO ",current_schema,".wp_users (user_login, user_pass, user_nicename, user_email, user_status, display_name, user_registered) VALUES
        ('",username,"', MD5('",password,"'), '",nicename,"', '",email,"', '0', '",displayname,"', NOW());
      SET @user_insert_id = LAST_INSERT_ID();
      INSERT INTO ",current_schema,".wp_usermeta (user_id, meta_key, meta_value) VALUES
        (@user_insert_id, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}');
      INSERT INTO ",current_schema,".wp_usermeta (user_id, meta_key, meta_value) VALUES
        (@user_insert_id, 'wp_user_level', '10');
      INSERT INTO exec_results VALUES ('",username,"','",current_schema,"','added');
    END IF;
  ");
  PREPARE stmt FROM @expression;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

END LOOP loopSchemas;

CLOSE wp_schemas;

SELECT * FROM exec_results;

END $$

delimiter ;

您可以这样称呼它:

-- Create or update the newwpuser user on all wordpress databases
call ensure_global_wp_user('newwpuser', '[email protected]', 'newpassword', 'newwpuser', 'newwpuser');

是否有其他语法可以实现这一目标?我也尝试将sql_mode设置为'',但没有任何区别。

mysql sql stored-procedures mysql-5.7
1个回答
0
投票

您的@expression在mysql中不是有效的代码。

尝试一下,当然如果没有您的表,我将无法完全对其进行测试

现在,我首先通过另一个准备好的语句来确定,如果用户存在,则返回1表示存在,否则返回0。

并使用该ti来确定我应该使用和更新的方式,当现有ot插入时不使用它。

Thbis也应该在mariadb中工作。

DROP procedure IF EXISTS `ensure_global_wp_user`;

DELIMITER $$
USE `testdb`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `ensure_global_wp_user`(
  IN username VARCHAR(255),
  IN email VARCHAR(255),
  IN password VARCHAR(255),
  IN nicename VARCHAR(255),
  IN displayname VARCHAR(255)
)
BEGIN

DECLARE current_schema VARCHAR(255);
DECLARE finished INTEGER DEFAULT 0;

DECLARE wp_schemas CURSOR FOR
  SELECT DISTINCT table_schema
    FROM INFORMATION_SCHEMA.tables
    WHERE table_name = 'wp_users';

DECLARE CONTINUE HANDLER
  FOR NOT FOUND
  SET finished = 1;

OPEN wp_schemas;

DROP TEMPORARY TABLE IF EXISTS exec_results;
CREATE TEMPORARY TABLE IF NOT EXISTS exec_results (
  username VARCHAR(255),
  dbname VARCHAR(255),
  action VARCHAR(255)
);

loopSchemas: LOOP
  FETCH wp_schemas INTO current_schema;
  IF finished = 1 THEN
    LEAVE loopSchemas;
  END IF;
SET @sql = CONCAT("SELECT  EXISTS (SELECT * FROM ",current_schema,".wp_users WHERE user_login = '",username,"') INTO @res;");
  PREPARE stmt FROM @sql;
  EXECUTE stmt;

    IF @res = 1 THEN
      SET @expression = CONCAT("UPDATE ",current_schema,".wp_users
        SET
          user_pass = MD5('",password,"'),
          user_email = '",email,"',
          user_nicename = '",nicename,"',
          display_name = '",displayname,"'
        WHERE user_login = '",username,"';
      INSERT INTO exec_results VALUES ('",username,"','",current_schema,"','updated');");
    ELSE
      SET @expression = CONCAT("INSERT INTO ",current_schema,".wp_users (user_login, user_pass, user_nicename, user_email, user_status, display_name, user_registered) VALUES
        ('",username,"', MD5('",password,"'), '",nicename,"', '",email,"', '0', '",displayname,"', NOW());
      SET @user_insert_id = LAST_INSERT_ID();
      INSERT INTO ",current_schema,".wp_usermeta (user_id, meta_key, meta_value) VALUES
        (@user_insert_id, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}');
      INSERT INTO ",current_schema,".wp_usermeta (user_id, meta_key, meta_value) VALUES
        (@user_insert_id, 'wp_user_level', '10');
      INSERT INTO exec_results VALUES ('",username,"','",current_schema,"','added');");
    END IF;

  PREPARE stmt FROM @expression;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

END LOOP loopSchemas;

CLOSE wp_schemas; 

SELECT * FROM exec_results;

END$$

DELIMITER ;
© www.soinside.com 2019 - 2024. All rights reserved.