前言: 在实际工作中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. Android 常用UI控件之TabHost(5)Tab栏在底部且在最上层也不盖tab页

    tab栏在底部 <TabHost android:id="@android:id/tabhost" android:layout_width="match_pare ...

  2. chrome渲染hover状态tranform相邻元素抖动bug

    最近同事在使用 css3 的 transition + tranform 的时候影响了相邻的元素出现bug.或者说相邻的元素出现抖动bug. 然而把 hover 状态的 tranform 属性删了后, ...

  3. 解决windows下vim方向键变成 ABCD 的问题

    一.问题描述: windows下面要安装git --> 安装了 msys2 -->安装并更新了 vim(7.4),然后在使用过程中发现vim不能使用  BACKSPACE 键,按方向键会打 ...

  4. 谈谈数据库中MyISAM与InnoDB区别

    MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与 ...

  5. Application Pool Identities

    Whether you are running your site on your own server or in the cloud, security must be at the top of ...

  6. 使用Busybox-1.2.0制作根文件系统

    使用Busybox-1.2.0制作根文件系统 cross-3.3.2 make-3.8.1 STEP 1: 创建根文件系统目录,主要包括以下目录/bin,/etc,/dev,/mnt,/sbin,/u ...

  7. HDU 3007 Buried memory & ZOJ 1450 Minimal Circle

    题意:给出n个点,求最小包围圆. 解法:这两天一直在学这个神奇的随机增量算法……看了这个http://soft.cs.tsinghua.edu.cn/blog/?q=node/1066之后自己写了好久 ...

  8. dephi WaitForMultipleObjects 用法

    在Delphi中WaitForMultipleObjects的使用   procedure ThreadTest;stdcall; var Handles:TWOHandleArray; //Hand ...

  9. UVAlive3662 Another Minimum Spanning Tree 莫队算法

    就是莫队的模板题 /* Memory: 0 KB Time: 1663 MS Language: C++11 4.8.2 Result: Accepted */ #include<cstdio& ...

  10. NOIP2012 同余方程

    1同余方程 题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行 ...