us_ateneo 2024-06-25 13:30 采纳率: 0%
浏览 5

mysql 编程 高精端问题

mysql 创建 触发器在 50个(数据库)dbname 下

我现在自己编写一个自动化脚本,在50个数据库下 自动创建触发器对某几张表,但是开发过程遇到一些问题,请帮我看看 感谢

DELIMITER //
CREATE PROCEDURE prc_ctl_tables(IN tablename VARCHAR(255))
 BEGIN
  declare v_table_name varchar(100);
  declare v_db_name varchar(100);
  declare EmptyData int default 0;
  declare v_cnt int default 0;
  declare v_done int default 0;
  declare v_i int default 0;
  declare tab_name varchar(200) default '';
    declare tab_name_1 varchar(200) default '';
  declare v_message varchar(200);
  declare v_cursor cursor for (select distinct table_name,table_schema from information_schema.columns where table_name = tablename );
  declare CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;
  open v_cursor;
  # 循环
  repeat
  # 获取游标中值并赋值给变量
       fetch v_cursor into v_table_name,v_db_name;
       # 判断游标是否到底,若到底则退出游标
       # 需要注意这个判断
        if v_db_name is not null  and  not v_done then
          #set tab_name = concat('create table  v_newtable',' as select * from `tg_table` where 1=2;');
          
          set tab_name_1 = concat( 'use ', v_db_name,';');
          #set tab_name_1 = concat('select * from tg_table;');
          SET @SQL_1 = concat(tab_name_1);
          select @SQL_1;
          prepare  schema_stmt_1 from @SQL_1;
          EXECUTE schema_stmt_1;
          deallocate prepare schema_stmt_1;
          
          #set tab_name = concat('insert into ',v_db_name,'.','tg_table select', ' 444',',',' 444',',',' 444',';');
          set tab_name = concat('select * from',v_db_name,'.',tg_table,';');
          SET @SQL = CONCAT(tab_name);
          select @SQL;
          prepare  schema_stmt from @sql;
          EXECUTE schema_stmt;
          deallocate prepare schema_stmt; 
       end if;
       until v_done end REPEAT;
       fetch v_cursor into v_table_name,v_db_name;
       if v_db_name is null then
           set v_message=concat('not exists table  ',':',tablename);
           select v_message;
      end if;
  close v_cursor;
 END//
DELIMITER ;
/* 主要问题 在这里,我一定要切换到对应的数据库才能执行我创建触发器的脚本,这里报错 不识别我的命令语法,set tab_name_1 = concat( 'use ', v_db_name,';');

感谢感谢

  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-06-25 13:37
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    您好!很高兴您在尝试自动化MySQL数据库操作时想到了我。针对您提出的问题,我会尽量提供一些帮助。

    首先,关于在游标循环中动态切换到不同的数据库并执行SQL语句的问题,USE语句实际上是用来切换当前会话的数据库上下文的,它不是一条可以被PREPAREEXECUTE执行的动态SQL语句。在存储过程中,您不需要使用USE语句来切换数据库,因为您的存储过程是在一个会话中执行的,只需要在执行SQL语句之前指定完整的数据库和表名即可。

    其次,关于您提到的报错问题,这可能是因为USE语句不能被预处理和执行。在MySQL中,USE语句是用来改变当前的数据库上下文,而不是用来执行SQL语句。在存储过程中,您应该直接使用完整的数据库名和表名来构造SQL语句。

    这里是一些修改建议:

    1. 直接在SQL语句中使用数据库名和表名,而不是使用USE语句。
    2. 确保您的触发器创建语句是正确的,并且可以在指定的数据库和表上执行。
    3. 使用异常处理来捕获并处理可能出现的错误。

    下面是一个修改后的示例代码,展示了如何在存储过程中动态创建触发器:

    DELIMITER //
    
    CREATE PROCEDURE prc_create_trigger(IN db_name VARCHAR(255), IN tbl_name VARCHAR(255), IN trigger_sql TEXT)
    BEGIN
      -- 动态构建并执行创建触发器的SQL语句
      SET @sql_stmt = CONCAT('USE ', db_name, '; ', trigger_sql);
      PREPARE stmt FROM @sql_stmt;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
    END //
    
    DELIMITER ;
    

    在这个示例中,trigger_sql是一个包含创建触发器的SQL语句的参数,您可以根据需要传递不同的触发器定义。然后,通过CONCAT函数动态构建完整的SQL语句,并使用PREPAREEXECUTEDEALLOCATE PREPARE来执行。

    请注意,这个示例只是一个基本的框架,您可能需要根据您的具体需求进行调整。例如,您可能需要在循环中调用这个存储过程,为每个数据库和表创建触发器。

    至于参考链接,由于我的知识截止日期是2023年,我无法提供最新的链接,但通常MySQL的官方文档是一个很好的资源,您可以在MySQL官方文档中找到有关存储过程、触发器和动态SQL的详细信息。

    希望这些信息对您有所帮助!如果您有其他问题或需要进一步的帮助,请随时告诉我。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月25日