2017-01-30 3 views
2

Добрый день,MYSQL: Ошибка присоединения 2 Выберите утверждения, которые включают в себя хранимую функцию

Я создал хранимую функцию, чтобы эмулировать поведение «SHOW ГРАНТЫ ДЛЯ» команды в MySQL. Определение сценария выглядит следующим образом:

CREATE FUNCTION get_grants(p_user text, p_host text, p_type text, p_obj text) 
    RETURNS text 
    NOT DETERMINISTIC 
    READS SQL DATA 
BEGIN 
... 
END; 

Если я использую функцию в инструкции выбора, она выполнена правильно. Например:

SELECT User as USER, Host as HOST, 
     'GLOBAL' as PRIV_TYPE, NULL as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'GLOBAL', '') as PRIVILEGES 
    FROM mysql.user 

Однако, когда я использую UNION или UNION ALL заявление присоединиться 2 выберите заявления, которые вызывают функцию с различными значениями параметров, например:

SELECT User as USER, Host as HOST, 
     'GLOBAL' as PRIV_TYPE, NULL as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'GLOBAL', '') as PRIVILEGES 
    FROM mysql.user 
UNION ALL 
SELECT User as USER, Host as HOST, 
     'DB' as PRIV_TYPE, Db as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'DB', Db) as PRIVILEGES 
    FROM mysql.db 
ORDER BY USER, HOST, DATABASE_NAME IS NULL, DATABASE_NAME; 

I получите следующую ошибку: # 1222 - Используемые операторы SELECT имеют различное количество столбцов.

Может ли кто-нибудь объяснить, что здесь происходит и как решить эту проблему?

Заранее спасибо.

ответ

0

После почти жарки мой мозг пытается найти проблему, то получается что фактическая проблема не имела ничего общего с сообщением об ошибке, предоставленным MySQL (по крайней мере, не с описанием, представленным в этом сообщении об ошибке в документации).

В этом случае ошибка была в реализации хранимой функции. В команде SELECT ... INTO мне не хватало «,» между двумя переменными в предложении INTO. Количество выбранных столбцов соответствовало количеству переменных в предложении INTO, проблема была решена, и мне удалось без проблем использовать функцию в вышеуказанном запросе.

Для справки проблемный запрос был:

SELECT Select_priv, Insert_priv, Update_priv, Delete_priv, 
     Create_priv, Alter_priv, Index_priv, Drop_priv, 
     Create_tmp_table_priv, Create_view_priv, Show_view_priv, 
     Create_routine_priv, Alter_Routine_priv, Execute_priv, 
     Event_priv, Trigger_priv, Grant_priv, Lock_tables_priv, 
     References_priv 
    INTO v_select_priv, v_insert_priv, v_update_priv, v_delete_priv, 
     v_create_priv, v_alter_priv, v_index_priv, v_drop_priv, 
     v_tmptables_priv, v_createview_priv, v_showview_priv, 
     v_createroutine_priv, v_alterroutine_priv, v_execute_priv, 
     v_event_priv, v_trigger_priv, v_grant_priv, v_locktables_priv, 
     v_references_priv 
    FROM mysql.db 
WHERE User = p_user 
    AND Host = p_host 
    AND Db = p_obj; 
0

Я думаю, что это СОЮЗ ВСЕ, что вызывает проблему. Обычно, если вы используете UNION ALL, не имеет значения, отличается ли количество столбцов, а UNION они должны быть равны. Так что попробуйте использовать либо UNION ALL и удалить NULL в качестве DATABASE_NAME или использовать только UNION и сохранить NULL в качестве DATABASE_NAME

SELECT User as USER, Host as HOST, 
     'GLOBAL' as PRIV_TYPE, NULL as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'GLOBAL', '') as PRIVILEGES 
    FROM mysql.user 
UNION 
SELECT User as USER, Host as HOST, 
     'DB' as PRIV_TYPE, Db as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'DB', Db) as PRIVILEGES 
    FROM mysql.db 
ORDER BY USER, HOST, DATABASE_NAME IS NULL, DATABASE_NAME; 

ИЛИ

SELECT User as USER, Host as HOST, 
     'GLOBAL' as PRIV_TYPE, 
     mydatabase.get_grants(User, Host, 'GLOBAL', '') as PRIVILEGES 
    FROM mysql.user 
UNION ALL 
SELECT User as USER, Host as HOST, 
     'DB' as PRIV_TYPE, Db as DATABASE_NAME, 
     mydatabase.get_grants(User, Host, 'DB', Db) as PRIVILEGES 
    FROM mysql.db 
ORDER BY USER, HOST, DATABASE_NAME IS NULL, DATABASE_NAME; 
Смежные вопросы