我如何弄清楚为什么MySQL不让我查询视图?

时间:2017-03-08 14:46:52

标签: mysql view mysql-5.6

我正在使用MySql 5.6。我正在查询视图并收到此错误

mysql> select * FROM report_toc_item;
ERROR 1356 (HY000): View 'my_db.report_toc_item' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
mysql>

我可以看到视图定义,看起来没有任何错误

mysql>  SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE table_schema = 'my_db' and TABLE_NAME = 'report_toc_item';
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| VIEW_DEFINITION                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| select `ti`.`ID` AS `ID`,`ti`.`PARENT_ID` AS `PARENT_ID`,`ti`.`TOC_ID` AS `TOC_ID`,`ti`.`TITLE` AS `TITLE`,`ti`.`DESCRIPTION` AS `DESCRIPTION`,`ti`.`TYPE_ID` AS `TYPE_ID`,`ti`.`ORDER_NUM` AS `ORDER_NUM`,`ti`.`MY_OBJECT_SEGMENT_ID` AS `MY_OBJECT_SEGMENT_ID`,`ti`.`MY_OBJECT_SEGMENT_ORDER_NUM` AS `MY_OBJECT_SEGMENT_ORDER_NUM`,`ti`.`ELEMENT_ID` AS `ELEMENT_ID`,`ti`.`UNIT_TOC_ITEM_ID` AS `UNIT_TOC_ITEM_ID`,`ti`.`SHORT_NAME` AS `SHORT_NAME`,`ti`.`THIRD_PARTY_PROMPT_ID` AS `THIRD_PARTY_PROMPT_ID`,`pti`.`TYPE_ID` AS `PARENT_TYPE_ID` from (`my_db`.`toc_item` `ti` join `my_db`.`toc_item` `pti` on((`pti`.`ID` = `ti`.`PARENT_ID`))) where ((`ti`.`TYPE_ID` = 'sub_segment') and ((`pti`.`TYPE_ID` = 'lesson') or (`pti`.`TYPE_ID` = 'activity') or (`pti`.`TYPE_ID` = 'activity_practice') or (`pti`.`TYPE_ID` = 'unit_opener'))) |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

如何确定哪些列和表无效?请注意,我在运行这两个命令时以root用户身份登录。

编辑:以下是“SHOW CREATE VIEW report_toc_item”的结果。

mysql> show create view report_toc_item;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View               | Create View                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | character_set_client | collation_connection |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| report_toc_item | CREATE ALGORITHM=UNDEFINED DEFINER=`myuser`@`localhost` SQL SECURITY DEFINER VIEW `report_toc_item` AS select `ti`.`ID` AS `ID`,`ti`.`PARENT_ID` AS `PARENT_ID`,`ti`.`TOC_ID` AS `TOC_ID`,`ti`.`TITLE` AS `TITLE`,`ti`.`DESCRIPTION` AS `DESCRIPTION`,`ti`.`TYPE_ID` AS `TYPE_ID`,`ti`.`ORDER_NUM` AS `ORDER_NUM`,`ti`.`MY_OBJECT_SEGMENT_ID` AS `MY_OBJECT_SEGMENT_ID`,`ti`.`MY_OBJECT_SEGMENT_ORDER_NUM` AS `MY_OBJECT_SEGMENT_ORDER_NUM`,`ti`.`ELEMENT_ID` AS `ELEMENT_ID`,`ti`.`UNIT_TOC_ITEM_ID` AS `UNIT_TOC_ITEM_ID`,`ti`.`SHORT_NAME` AS `SHORT_NAME`,`ti`.`THIRD_PARTY_PROMPT_ID` AS `THIRD_PARTY_PROMPT_ID`,`pti`.`TYPE_ID` AS `PARENT_TYPE_ID` from (`toc_item` `ti` join `toc_item` `pti` on((`pti`.`ID` = `ti`.`PARENT_ID`))) where ((`ti`.`TYPE_ID` = 'sub_segment') and ((`pti`.`TYPE_ID` = 'lesson') or (`pti`.`TYPE_ID` = 'activity') or (`pti`.`TYPE_ID` = 'activity_practice') or (`pti`.`TYPE_ID` = 'unit_opener'))) | utf8                 | utf8_general_ci      |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+

编辑2:

以下是为相关用户分配的拨款

mysql> show grants for 'myuser'@'localhost';
+-------------------------------------------------+
| Grants for myuser@localhost                |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO 'myuser'@'localhost' |
+-------------------------------------------------+
1 row in set (0.00 sec)

5 个答案:

答案 0 :(得分:3)

完整的错误消息是:

... or definer/invoker of view lack rights to use them

检查视图定义器,如果有,请检查定义者帐户是否可以执行选择。

要查看定义者,请使用:

SHOW CREATE VIEW

SELECT DEFINER FROM INFORMATION_SCHEMA.VIEWS WHERE ...

答案 1 :(得分:1)

DEFINER=myuser@localhost SQL SECURITY DEFINER表示视图将以myuser@localhost的权限执行(而不是您当前的root登录信息),请参阅documentation

  
      
  • 在定义安全上下文中执行的存储程序或视图使用其DEFINER属性指定的帐户的权限执行。这些权限可能与调用用户的权限完全不同。调用者必须具有引用对象的适当权限(例如,EXECUTE用于调用存储过程或SELECT用于从视图中进行选择),但是当对象执行时,调用者的权限将被忽略,只有DEFINER帐户权限才重要。如果此帐户具有很少的权限,则该对象在其可执行的操作中相应地受到限制。如果DEFINER帐户具有高权限(例如root帐户),则无论谁调用它,该对象都可以执行强大的操作。
  •   
  • 在调用程序安全上下文中执行的存储例程或视图只能执行调用者具有特权的操作。可以指定DEFINER属性,但对在调用程序上下文中执行的对象无效。
  •   

因此,根据您要实现的目标,要么授予myuser@localhost所需的权限,请将definer更改为拥有这些权限的用户,或将sql security更改为{{1} }}。通常情况下,将使用第二个选项,除非您有理由不这样做。

要更改invokerdefiner,您必须sql security(或删除并重新创建)视图,包括整个alter部分。您可以使用as select ...的输出,只需在开头更改它。 show create view report_toc_itemdefiner的默认值将是当前用户和sql security

答案 2 :(得分:1)

  

如果视图引用了无效列,则show create view将不起作用。

因此,请检查以下查询,以正确定义视图。因为如果从toc_item表中删除任何列,则该视图将不起作用。

select `ti`.`ID` AS `ID`,`ti`.`PARENT_ID` AS `PARENT_ID`,`ti`.`TOC_ID` AS TOC_ID\,`ti`.`TITLE` AS `TITLE`,`ti`.`DESCRIPTION` AS `DESCRIPTION`,`ti`.`TYPE_ID` AS `TYPE_ID`,`ti`.`ORDER_NUM` AS `ORDER_NUM`,`ti`.`MY_OBJECT_SEGMENT_ID` AS `MY_OBJECT_SEGMENT_ID`,`ti`.`MY_OBJECT_SEGMENT_ORDER_NUM` AS `MY_OBJECT_SEGMENT_ORDER_NUM`, `ti`.`ELEMENT_ID` AS `ELEMENT_ID`, `ti`.`UNIT_TOC_ITEM_ID` AS `UNIT_TOC_ITEM_ID`,`ti`.`SHORT_NAME` AS `SHORT_NAME`,`ti`.`THIRD_PARTY_PROMPT_ID` AS `THIRD_PARTY_PROMPT_ID`, `pti`.`TYPE_ID` AS `PARENT_TYPE_ID` from (`my_db`.`toc_item` `ti` join `my_db`.`toc_item` `pti` on((`pti`.`ID` = `ti`.`PARENT_ID`))) where ((`ti`.`TYPE_ID` = 'sub_segment') and ((`pti`.`TYPE_ID` = 'lesson') or (`pti`.`TYPE_ID` = 'activity') or (`pti`.`TYPE_ID` = 'activity_practice') or (`pti`.`TYPE_ID` = 'unit_opener')));

请参阅以下示例:

TOC_ID\

正如所料,这不起作用。

 create table test
 (
    x integer not null,
    y integer not null
 );

 create or replace view test_view as select * from test;

 alter table test drop column y;

但这也不起作用。

 select * from test_view;

正如预期的那样,这仍然无效。

 show create view test_view;

 drop table test;

但奇怪的是,这现在确实有效!

 select * from test_view;

来源here

答案 3 :(得分:0)

myuser 登录,而不是 root ,因为定义者是 myuser

答案 4 :(得分:0)

确保您从localhost以MySQL身份验证MySQL。确保在运行任何测试之前刷新了权限。

从MySQL手册:“要告诉服务器重新加载授权表,执行flush-privileges操作。这可以通过发出FLUSH PRIVILEGES语句或执行mysqladmin flush-privileges或mysqladmin reload命令来完成。”

不是授予USAGE,而是授予ALL并删除“ALGORITHM = UNDEFINED DEFINER = myuser @ localhost SQL安全定义器”。

将条件DROP TABLE IF EXISTS放在详尽的实验文件的顶部(汇总所有设置和测试)

运行测试并使其在最简单的情况下工作,然后逐步向表中添加限制和功能以找到断点。获取其他所有功能,但功能会破坏访问权限。

然后,您可以研究破坏访问权限的功能或决定不使用它。