前言: 在实际工作中mysql数据库的迁移、备份恢复、数据库重命名等一系列涉及到视图和存储过程定义者问题都会需要修改,每次都要从基础表获取数据,然后手工整理做脚本,十分麻烦,所以简单写了个过程,以后可以更加方便的迁移后更新定义者问题了,下面是解决过程~

-- 失败第一个版本 及失败原因

CREATE DEFINER = CURRENT_USER()
PROCEDURE CHANGE_DEFINER(
`pr_database_name` VARCHAR(500), -- 数据库名称
`pr_definer_name` VARCHAR(500), -- 定义者名称
`pr_definer_ip_name` VARCHAR(500)-- 定义者绑定的ip,默认为 % ,任意ip
)
BEGIN DECLARE SQL_CHANGE_DEFINER longtext;
DECLARE DATABASE_NAME VARCHAR(500);
DECLARE DEFINER_NAME VARCHAR(500) DEFAULT CURRENT_USER();
DECLARE DEFINER_IP_NAME VARCHAR (500) DEFAULT '%'; SET DATABASE_NAME = TRIM(pr_database_name); IF pr_definer_name IS NOT NULL AND LENGTH(pr_definer_name)>0 THEN
SET DEFINER_NAME = TRIM(pr_definer_name);
END IF;
IF pr_definer_ip_name IS NOT NULL AND LENGTH(pr_definer_ip_name) > 0 THEN
SET DEFINER_IP_NAME = pr_definer_ip_name;
END IF; -- 组装修改视图定义者语句
IF DATABASE_NAME IS NOT NULL AND LENGTH(DATABASE_NAME)>0 THEN
-- group_concat默认查询结果长度1024,长度不足,设置成足够长度如下
SET GLOBAL group_concat_max_len=1024000;
SET SESSION group_concat_max_len=1024000; SELECT
GROUP_CONCAT(
' alter definer = `',
DEFINER_NAME,
'`@`' ,DEFINER_IP_NAME, '` view ',
TABLE_NAME,
' as ',
VIEW_DEFINITION,
';' SEPARATOR ''
) INTO SQL_CHANGE_DEFINER
FROM
information_schema.VIEWS
WHERE
TABLE_SCHEMA = DATABASE_NAME
GROUP BY
TABLE_SCHEMA; -- 执行修改视图定义者
SET @VALUE = CONCAT(SQL_CHANGE_DEFINER);
PREPARE stmt FROM @VALUE;
EXECUTE stmt; -- 修改存储过程定义者 UPDATE mysql.proc set DEFINER = CONCAT(DEFINER_NAME,'@',DEFINER_IP_NAME) WHERE db = DATABASE_NAME; ELSE
SELECT '数据库名称不允许为空';
END IF; END

mysql不支持问题代码

对于这个版本是由于prepare stmt from 语句,这个语句只能是单独的语句,而我却 alter ...; alter ...; 肯定不行了,改成每一个单独就好了吧,继续改

-- 失败第二个版本 及失败原因

CREATE DEFINER = 'harri'@'%'
PROCEDURE my_apm.CHANGE_DEFINER(
`pr_database_name` VARCHAR(500), -- 数据库名称
`pr_definer_name` VARCHAR(500), -- 定义者名称
`pr_definer_ip_name` VARCHAR(500)-- 定义者绑定的ip,默认为 % ,任意ip
)
BEGIN DECLARE SQL_CHANGE_DEFINER longtext;
DECLARE DATABASE_NAME VARCHAR(500);
DECLARE DEFINER_NAME VARCHAR(500) DEFAULT CURRENT_USER();
DECLARE DEFINER_IP_NAME VARCHAR (500) DEFAULT '%'; DECLARE flag boolean DEFAULT 1;
DECLARE cur CURSOR FOR SELECT value_ FROM sql_value;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = 0; DROP TEMPORARY TABLE IF EXISTS sql_value;
CREATE TEMPORARY TABLE sql_value(value_ varchar(15000)); SET DATABASE_NAME = TRIM(pr_database_name); IF pr_definer_name IS NOT NULL AND LENGTH(pr_definer_name)>0 THEN
SET DEFINER_NAME = TRIM(pr_definer_name);
END IF;
IF pr_definer_ip_name IS NOT NULL AND LENGTH(pr_definer_ip_name) > 0 THEN
SET DEFINER_IP_NAME = pr_definer_ip_name;
END IF; -- 组装修改视图定义者语句
IF DATABASE_NAME IS NOT NULL AND LENGTH(DATABASE_NAME)>0 THEN
INSERT INTO sql_value(value_)
SELECT
GROUP_CONCAT(
' alter definer = `',
DEFINER_NAME,
'`@`' ,DEFINER_IP_NAME, '` view ',
TABLE_NAME,
' as ',
VIEW_DEFINITION,
';' SEPARATOR ''
)
FROM
information_schema.VIEWS
WHERE
TABLE_SCHEMA = DATABASE_NAME
GROUP BY
TABLE_NAME; -- 执行修改视图定义者
OPEN cur; rep:LOOP FETCH cur INTO SQL_CHANGE_DEFINER;
set @VALUE = SQL_CHANGE_DEFINER;
IF flag = 0 THEN
LEAVE rep;
END IF; PREPARE stmt FROM @VALUE;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP; CLOSE cur;
-- 修改存储过程定义者 UPDATE mysql.proc set DEFINER = CONCAT(DEFINER_NAME,'@',DEFINER_IP_NAME) WHERE db = DATABASE_NAME; ELSE
SELECT '数据库名称不允许为空';
END IF; END

还是mysql不支持问题

感觉稳稳的了,结果出乎意料,看来prepare 支持的语句掌握不牢靠,竟然不支持 alter view, 为什么alter table都支持还差view了吗,于是乎去查mysql 5.6官方手册,支持的语句如下:

ALTER TABLE
ALTER USER (as of MySQL 5.6.8)
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
| LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE | QUERY CACHE}
REVOKE
SELECT
SET
SHOW {AUTHORS | CONTRIBUTORS | WARNINGS | ERRORS}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE

这里还有一句话,Other statements are not supported in MySQL 5.6. 擦汗啊,这么简单个脚本一波三折,万幸看到了drop view,和 create view 这不就直接等于alter view了吗?

就这么改,于是乎终于成功了,如下:

CREATE DEFINER = CURRENT_USER()
PROCEDURE my_apm.CHANGE_DEFINER(
`pr_database_name` VARCHAR(500), -- 数据库名称
`pr_definer_name` VARCHAR(500), -- 定义者名称
`pr_definer_ip_name` VARCHAR(500)-- 定义者绑定的ip,默认为 % ,任意ip
)
BEGIN DECLARE drop_view_ varchar(500);
DECLARE create_view_ varchar(15000);
DECLARE DATABASE_NAME VARCHAR(500);
DECLARE DEFINER_NAME VARCHAR(500) DEFAULT CURRENT_USER();
DECLARE DEFINER_IP_NAME VARCHAR (500) DEFAULT '%'; DECLARE flag boolean DEFAULT 1;
DECLARE cur CURSOR FOR SELECT drop_view,create_view FROM sql_value;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = 0; DROP TEMPORARY TABLE IF EXISTS sql_value;
CREATE TEMPORARY TABLE sql_value(drop_view varchar(500),create_view varchar(15000)); SET DATABASE_NAME = TRIM(pr_database_name); IF pr_definer_name IS NOT NULL AND LENGTH(pr_definer_name)>0 THEN
SET DEFINER_NAME = TRIM(pr_definer_name);
END IF;
IF pr_definer_ip_name IS NOT NULL AND LENGTH(pr_definer_ip_name) > 0 THEN
SET DEFINER_IP_NAME = pr_definer_ip_name;
END IF; -- 组装修改视图定义者语句
IF DATABASE_NAME IS NOT NULL AND LENGTH(DATABASE_NAME)>0 THEN
INSERT INTO sql_value(drop_view,create_view)
SELECT
GROUP_CONCAT('drop view if exists ',TABLE_NAME,';'),
GROUP_CONCAT('create definer = `',
DEFINER_NAME,
'`@`' ,DEFINER_IP_NAME, '` view ',
TABLE_NAME,
' as ',
VIEW_DEFINITION,
';' SEPARATOR ''
)
FROM
information_schema.VIEWS
WHERE
TABLE_SCHEMA = DATABASE_NAME
GROUP BY
TABLE_NAME; -- 执行修改视图定义者
OPEN cur; rep:LOOP FETCH cur INTO drop_view_,create_view_;
set @drop_view_ = drop_view_;
set @create_view_ = create_view_;
IF flag = 0 THEN
LEAVE rep;
END IF; PREPARE stmt FROM @drop_view_;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM @create_view_;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP; CLOSE cur; -- 修改存储过程定义者
UPDATE mysql.proc set DEFINER = CONCAT(DEFINER_NAME,'@',DEFINER_IP_NAME) WHERE db = DATABASE_NAME AND NAME != 'CHANGE_DEFINER'; ELSE
SELECT '数据库名称不允许为空';
END IF; END

上面过程可能有哪里不合理的地方,欢迎指正

mysql视图和存储过程定义者修改脚本(懒人专用)的更多相关文章

  1. mysql 视图 触发器 存储过程 函数事务 索引

    mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...

  2. mysql 视图,存储过程,游标,触发器,用户管理简单应用

    mysql视图——是一个虚拟的表,只包含使用时动态查询的数据 优点:重用sql语句,简化复杂的SQL操作,保护数据,可以给用户看到表的部分字段而不是全部,更改数据格式和表现形式 规则: 名称唯一,必须 ...

  3. 2020重新出发,MySql基础,MySql视图&索引&存储过程&触发器

    @ 目录 视图是什么 视图的优点 1) 定制用户数据,聚焦特定的数据 2) 简化数据操作 3) 提高数据的安全性 4) 共享所需数据 5) 更改数据格式 6) 重用 SQL 语句 MySQL创建视图 ...

  4. mysql视图、存储过程等

    视图: 需求: 创建的临时表(select * from tb1)被反复使用,这时可以为该临时表创建视图.视图相当于为某个查询创建了别名. 1.创建视图 create view v1 as selec ...

  5. MySQL 数据库的tab 补全功能 (懒人必备)

    MySQL 数据库的tab补全功能                      跟着步骤走~~ 懒人养成第一步 不仅帮你补全 甚至预判你的预判,就问你可怕不可怕 1.安装相关依赖软件(需要配置yum官方 ...

  6. Mysql 视图,触发器,存储过程,函数,事务

    视图 视图虚拟表,是一个我们真实查询结果表,我们希望将某次查询出来的结果作为单独的一个表,就叫视图,无法对图字段内容进行增删改. --格式: CREATE VIEW 视图名字 AS 操作; --比如: ...

  7. MySql视图、存储过程、函数、索引

    一.视图 视图是查询命令结果构成的一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集合,并可以当作表来查询使用. 1创建视图 - ...

  8. 八、mysql视图、存储过程、函数以及时间调度器

    .create or replace view emp_view as select * from t4 ;给t4表创建一个名为emp_view的视图 .drop view emp_view 删除视图 ...

  9. MySQL视图 索引 存储过程 触发器 函数

       视图: 也就是一个虚拟表(不是真实存在的),它的本质就是根据SQL语句获取动态的数据集,并为其命名.用户使用时只需要使用命名的视图即可获取结果集,并可以当做表来使用.它的作用就是方便查询操作,减 ...

随机推荐

  1. !! Scrum之 流程和术语

    !!Scrum之 流程和术语 http://www.cnblogs.com/zhoujg/archive/2009/07/15/1523680.html 以下将对一些术语进行简单介绍,以便大家现在开始 ...

  2. web.xml的说明

    <!--DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. Copyright 2000-2007 Sun Microsystems ...

  3. 【HDOJ】4412 Sky Soldiers

    1. 题目描述有$k$个伞兵跳伞,有$m$个汇点.当伞兵着陆后,需要走向离他最近的汇点.如何选择这$m$个结点,可以使得士兵最终行走的距离的期望最小.求这个最小的期望. 2. 基本思路假设已经选好了这 ...

  4. 从Excel表格导入数据到数据库

    数据库:SQL 1.小数据直接粘贴 2.用导入向导 3.用SSIS包 4.用SQL语句 现在详细说一下第4种方法,以.xlsx文件为例 .xlsx文件需要用provider“Microsoft.ACE ...

  5. BZOJ_1018_[SHOI2008]_交通堵塞traffic_(线段树)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1018 \(2*n\)的距形,起初没有边相连,之后有三种操作: 1.加边. 2.删边. 3.询问 ...

  6. (转载)关于gcd的8题

    发现其实有关gcd的题目还是挺多的,这里根据做题顺序写出8题. [bzoj2818: Gcd] gcd(x,y)=质数, 1<=x,y<=n的对数 做这题的时候,懂得了一个非常重要的转化: ...

  7. chromium的部署工具depot_tools和gclient

    depot_tools是个工具包,里面包含gclient.gcl.gn和ninja等工具.其中gclient是代码获取工具,它其实是利用了svn和git.主要涉及的depot_tools文件夹下的文件 ...

  8. 建立自己的bin目录,在当前路径运行shell脚本

    Shell脚本nusers cat nusers #! /bin/sh - who | wc -l 如果你要编写自己的脚本,最好准备自己的bin目录来存放它们,并且让Shell能够自动找到它们.这不难 ...

  9. Entity Framework 数据生成选项DatabaseGenerated

    在EF中,我们建立数据模型的时候,可以给属性配置数据生成选项DatabaseGenerated,它后有三个枚举值:Identity.None和Computed. Identity:自增长 None:不 ...

  10. 【Python】使用python的tornado配合html页面示例

    背景:java写的非标加密算法,测试时执行java工程进行解密测试,很不方便. 目的:想写个web页面,使得任何测试人员都可以在输入加密串时得到解密后字段,方便日志查询及字段核对.(额,算法部分就不写 ...