SHOW CREATE VIEW 可直接获取视图原始定义,返回含ALGORITHM、DEFINER、SQL SECURITY等完整CREATE VIEW语句;需有SELECT权限,结果第二列为所需脚本,注意库名、DEFINER及跨库依赖需手动适配。

怎么用 SHOW CREATE VIEW 拿到原始定义
MySQL 里最直接的方式就是查系统元数据,SHOW CREATE VIEW 能返回带 CREATE VIEW 语句的完整定义,包括字段别名、ALGORITHM、DEFINER 等细节。执行前确认你有对应视图的 SELECT 权限,否则会报 Access denied。
示例:
SHOW CREATE VIEW mydb.old_view;
结果第一列是 View(视图名),第二列 Create View 就是你要的脚本。注意:它默认输出的是当前库下的完整语句,比如开头可能是:
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `mydb`.`old_view` AS select ...
这里 `mydb`.`old_view` 是带库名的,后续要批量替换。
为什么不能直接改库名后 CREATE VIEW
因为 CREATE VIEW 语句里的 DEFINER 用户可能在新库所在实例上不存在,或者权限不足;另外视图中引用的表如果跨库(比如 SELECT * FROM otherdb.table1),光改视图名没用,得同步检查依赖是否可访问。
常见翻车点:
-
DEFINER=`admin`@`localhost`在目标实例没这个用户 → 执行失败 - 原视图里写了
FROM sales.orders,但新库没sales库 → 报错Table 'sales.orders' doesn't exist - 用了
SQL SECURITY DEFINER,但新库没开对应用户权限 → 视图能建成功,查询时报权限错误
安全替换库名的三步操作
拿到 SHOW CREATE VIEW 输出后,别手敲改——用文本工具或命令行做精准替换,避免漏掉反引号或大小写问题。
推荐步骤:
- 把输出粘贴进编辑器,全局替换
`原库名`.`→`新库名`.`(注意保留反引号和点) - 删掉或重写
DEFINER子句:改成当前登录用户,例如DEFINER=CURRENT_USER,或干脆删掉让 MySQL 自动填入 - 把
SQL SECURITY DEFINER改成SQL SECURITY INVOKER,这样执行时按调用者权限检查,更可控
改完后的典型语句长这样:
CREATE ALGORITHM=UNDEFINED SQL SECURITY INVOKER VIEW `newdb`.`old_view` AS select ...
PostgreSQL 怎么办:用 pg_get_viewdef() + 手动拼接
PG 没有类似 SHOW CREATE VIEW 的一键命令,得组合查系统表。核心是 pg_get_viewdef() 函数,它返回不含 CREATE VIEW 头部的纯查询体。
获取完整建视图语句的最小可行做法:
SELECT 'CREATE VIEW newdb.' || relname || ' AS ' || pg_get_viewdef(oid) FROM pg_class WHERE relname = 'old_view' AND relkind = 'v';
注意:pg_get_viewdef() 不自动处理跨 schema 引用,如果原视图里写了 SELECT * FROM public.users,你得自己判断要不要改成 new_schema.users;另外 PG 没 DEFINER 概念,但要注意 OWNER 和 search_path 对解析的影响。
真正麻烦的不是复制语句本身,而是视图背后嵌套的 CTE、函数调用、甚至物化视图依赖——这些不会出现在 pg_get_viewdef() 返回里,得额外查 pg_depend。

















