前言: 在实际工作中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. POJ3608(旋转卡壳--求两凸包的最近点对距离)

    题目:Bridge Across Islands 分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696 考虑如下的算法, 算法的 ...

  2. Git教程(3)命令行使用git简单示例

    基础 Git系统下的的文件有3种状态: 已修改(modified):已修改表示修改了文件,但还没保存到数据库中. 已暂存(staged) : 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下 ...

  3. Zookeeper基本知识

    Zookeeper的Session: (1)客户端和server间采用长连接 (2)连接建立后,server产生session ID(64位)返还给客户端 (3)客户端定期发送ping包来检查和保持和 ...

  4. 1106. Two Teams(dfs 染色)

    1106 结点染色 当前结点染为黑 朋友染为白  依次染下去 这题是为二分图打基础吧 #include <iostream> #include<cstdio> #include ...

  5. 函数fsp_seg_inode_page_get_nth_inode

    #define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE) #define FSEG_PAGE_DATA FIL_PAGE_DATA #defi ...

  6. TRSWCM学习问题总结

    1,置标属性"id"是用来制定调用那个栏目的数据(全字配备,可以文字匹配好奇怪,好不专业.所以建议创建栏目或者站点的时候,将唯一标识设置成英文,这样才符合程序比对习惯) 2,需要添 ...

  7. HNOI2004打鼹鼠(LIS)

    大水题…… 不过通过这题我们应该养成一个好习惯:好好看清题…… 竟然没有看到时限 10sec…… var i,j,n,m,ans:longint; f,time,x,y:..] of longint; ...

  8. [POJ 2461] Billiard

    同swustoj 11 Billiard Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1362   Accepted: 8 ...

  9. [2015编程之美] 第一场C

    题目3 : 质数相关 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数.一个集合S被 ...

  10. Spring depends-on介绍

    <!-- redis配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.Jedis ...