Как мне понять, почему MySQL не позволяет мне запрашивать представление?

Вопрос:Я использую 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

Вопрос:

Я использую 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) Лучший ответ:

Полное сообщение об ошибке:

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

Проверьте определитель вида, и если он есть, убедитесь, что учетная запись определителя может выполнить выбор.

Чтобы увидеть определитель, используйте:

SHOW CREATE VIEW SELECT DEFINER FROM INFORMATION_SCHEMA.VIEWS WHERE … Ответ №1

DEFINER=myuser@localhost SQL SECURITY DEFINER означает, что представление будет выполнено с правами myuser@localhost (а не как ваш текущий вход в корневой каталог), см. документация:

  • Сохраненная программа или представление, которое выполняется в определенном контексте безопасности, выполняется с привилегиями учетной записи, названной ее атрибутом DEFINER. Эти привилегии могут полностью отличаться от прав доступа вызывающего пользователя. Вызывающий должен иметь соответствующие права для ссылки на объект (например, EXECUTE для вызова хранимой процедуры или SELECT для выбора из представления), но когда объект выполняется, привилегии вызывающего объекта игнорируются и имеют значение только привилегии учетной записи DEFINER. Если эта учетная запись имеет несколько привилегий, объект соответственно ограничен в операциях, которые он может выполнять. Если учетная запись DEFINER имеет высокую привилегию (например, учетную запись root), объект может выполнять мощные операции независимо от того, кто его вызывает.
  • Сохраненная процедура или представление, которое выполняется в контексте безопасности вызывающего, может выполнять только операции, для которых у invoker есть привилегии. Атрибут DEFINER может быть указан, но не влияет на объекты, которые выполняются в контексте invoker.

Итак, в зависимости от того, чего вы хотите достичь, либо предоставите требуемые права на myuser@localhost, измените definer на пользователя, который имеет эти права, либо измените sql security на invoker. Обычно используется второй вариант, если у вас нет причин для этого.

Чтобы изменить definer или sql security, вам нужно будет alter (или отбросить и воссоздать) представление, включая всю часть as select …. Вы можете использовать вывод show create view report_toc_item для этого и просто изменить его в начале. Значения по умолчанию для definer и sql security будут текущим пользователем и definer.

Ответ №2

Если представление ссылается на недопустимый столбец, тогда показать, что создание представления не будет работать.

Итак, проверьте следующий запрос, который правильно определяет представление. Потому что, если вы удалите любой столбец из таблицы 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` ОПИСАНИЕ`, `ti««TYPE_ID« « `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` из (`my_db`.`toc_item« ti` присоединитесь к `my_db`.`toc_item« pti` on ((`pti«««` « « « « `PARENT_ID`)), где ((` ti««TYPE_ID` = ‘sub_segment’) и (( `pti`.`TYPE_ID` = ‘lesson’) или (` pti`.`TYPE_ID` = ‘activity’) или (`pti`.`TYPE_ID` = ‘activity_practice’) или (` pti`.`TYPE_ID` = ‘unit_opener’)));Код >

Содержание

  1. См. следующий пример:
  2. Как и ожидалось, это не сработает.
  3. Но это тоже не сработает.
  4. Как и ожидалось, это все равно не сработает.
  5. Но странно, теперь это работает!

См. следующий пример:

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;

Но странно, теперь это работает!

show create view test_view;

Источник здесь

Ответ №3

Войдите как myuser не как root, потому что определитель myuser.

Ответ №4

Обеспечьте аутентификацию с MySQL с localhost как myuser. Перед запуском любых тестов убедитесь, что вы сбросили эти привилегии.

В Руководстве по MySQL: “Чтобы сообщить серверу о перезагрузке таблиц грантов, выполните операцию сброса-привилегий. Это можно сделать, выпустив инструкцию FLUSH PRIVILEGES или выполнив mysqladmin flush-privileges или команду mysqladmin reload”.

Вместо предоставления ИСПОЛЬЗОВАНИЯ выделите ВСЕ и удалите “ALGORITHM = UNDEFINED DEFINER = myuser @localhost SQL Defence Defence”.

Поместите условный DROP TABLE IF EXISTS в верхнюю часть исчерпывающего экспериментального файла (который объединяет все настройки и тест)

Запустите тест и попросите его работать в простейшем случае, а затем постепенно добавьте ограничения и функции в таблицу, чтобы найти точку прерывания. Получите все остальное, чтобы работать, но функция, которая нарушает доступ.

Затем вы можете изучить функцию, которая нарушает доступ или не решит ее использовать.

Оцените статью
Добавить комментарий