前言: 在实际工作中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. 使用SecureCRT上传和下载文件

    SecureCR 下的文件传输协议有ASCII .Xmodem .Ymodem .Zmodem.ASCII:这是最快的传输协议,但只能传送文本文件.Xmodem:这种传输协议速度较慢,但由于使用了CR ...

  2. 1414. Astronomical Database(STL)

    1414 破题 又逼着用stl 卡内存 trie树太耗了 水不过去 用set存字符串 set可以自己按一定顺序存 且没有重复的 再用lower_bound二分查找字符串的第一次出现 接着往后找就行了 ...

  3. bzoj2245

    这道题还是比较简单的费用流,由于w是递增的 实际上,这题数据还可以强一点,比如说分段函数不保证费用递增, 就要加一点技巧了(要保证函数的顺序) ; type node=record        ne ...

  4. RMAN 备份与恢复深入解析(二)

    RMAN 备份与恢复深入解析(一)  http://space.itpub.net/26686207/viewspace-760869 更多精彩内容尽在 www.leonarding.com < ...

  5. 【转】photoshop CS2安装激活破解教程

    原文网址:http://www.16xx8.com/photoshop/jiaocheng/109348_all.html photoshop CS2安装教程:(本页介绍如何安装CS2软件,如果你安装 ...

  6. linq里面似in的查询

    1.linq里面似in的查询 List<string> source = new List<string>{ "aaa", "bbb" ...

  7. 在ASP.NET中各种跳转控制

    在ASP.NET中各种跳转控制 分类: 我的资料2012-03-16 15:01 76人阅读 评论(0) 收藏 举报 asp.netjavascripturlmenu Respose.Write(&q ...

  8. ADO.NET - 全面梳理

    转自:http://www.cnblogs.com/yangcaogui/archive/2012/06/09/2537086.html 目录: 简单的介绍下ADO.NET SqlConnection ...

  9. jsp、js、html等

    1.一个button标签怎么触发事件: 一般触发事件有两种方式,要么是在html直接绑定,即button标签中不只有class.type和id,还要写onclick=... 还有一种,就是在js代码部 ...

  10. Python脚本控制的WebDriver 常用操作 <二十一> 执行JS

    测试用例场景 如果你熟悉js的话,那么使用webdriver执行js就是一件很高效的事情了.在webdriver脚本中直接执行js的好处很多,这里就不一一枚举了. webdriver提供了execut ...