Создание объединения взглядов в хранимой процедуре MySQL - PullRequest
0 голосов
/ 17 ноября 2018

Я создаю хранимую процедуру MySQL, которая получает имена двух представлений и выполняет их объединение в первое из двух.

Я использовал подготовленные операторы для принятия имен представлений в виде строк, поэтому я могу использовать эту хранимую процедуру с множеством других хранимых процедур, которые создают представления с разными именами.

Следующий код работает как положено:

DROP view if exists test1;
DROP view if exists test2;

CREATE VIEW test1 as SELECT "Cows";
CREATE VIEW test2 as SELECT "Horses";

DROP VIEW if exists tempView;
CREATE VIEW tempView AS SELECT * FROM test1 UNION SELECT * FROM test2;
SELECT * from tempView;

Однако, когда я выполняюследующий код:

DELIMITER //
DROP PROCEDURE IF EXISTS SP_unionViews //
CREATE PROCEDURE SP_unionViews(IN viewname varchar(255), 
                               IN viewname2 varchar(255))
BEGIN
    DROP VIEW IF EXISTS tempView;
    SET @in1 = viewname;
    SET @in2 = viewname2;
    SET @str = 'CREATE VIEW tempView AS 
       SELECT * FROM ? UNION SELECT * FROM ?';
    PREPARE stmt FROM @str;
    EXECUTE stmt USING @in1, @in2;

    SET @str2 = 'DROP VIEW ?';
    SET @in3 = viewname;
    PREPARE stmt2 FROM @str2;
    EXECUTE stmt2 USING @in3;

    SET @str3 = 'CREATE VIEW ? AS SELECT * FROM tempView';
    PREPARE stmt3 FROM @str3;
    EXECUTE stmt3 USING @in3;

    DEALLOCATE PREPARE stmt;
    DEALLOCATE PREPARE stmt2;
    DEALLOCATE PREPARE stmt3;
END //
DELIMITER ;

DROP view if exists test1;
DROP view if exists test2;

CREATE VIEW test1 as SELECT "Cows";
CREATE VIEW test2 as SELECT "Horses";
CALL SP_unionViews(test1, test2);
SELECT * from test1;

Я получаю следующую ошибку:

#1054 - Unknown column 'test1' in 'field list'

Это может указывать на то, что эта хранимая процедура пытается использовать test1 в качестве столбца там, где она не предназначена дляодин.Но я не могу понять, где.

ОБНОВЛЕНИЕ: Когда редактировалось, как показано ниже, я ожидал, что решение сработает, но оно дает мне еще одну ошибку.

Новый код читает:

DELIMITER //
DROP PROCEDURE IF EXISTS SP_unionViews //
CREATE PROCEDURE SP_unionViews(IN viewname varchar(255), 
                               IN viewname2 varchar(255))
BEGIN
    DROP VIEW IF EXISTS tempView;
    SET @str = CONCAT('
    CREATE VIEW tempView AS 
        SELECT * FROM ', viewname, ' UNION SELECT * FROM ', viewname2);
    PREPARE stmt FROM @str;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    SET @str2 = CONCAT('DROP VIEW ', viewname, ';');
    PREPARE stmt2 FROM @str2;
    EXECUTE stmt2;
    DEALLOCATE PREPARE stmt2;

    SET @str3 = CONCAT('CREATE VIEW ', viewname ,' AS SELECT * FROM tempView');
    PREPARE stmt3 FROM @str3;
    EXECUTE stmt3;
    DEALLOCATE PREPARE stmt3;
END //
DELIMITER ;

DROP view if exists test1;
DROP view if exists test2;

CREATE VIEW test1 as SELECT "Cows";
CREATE VIEW test2 as SELECT "Horses";
CALL SP_unionViews("test1", "test2");
SELECT * from test1;

И его ошибка гласит:

#1615 - Prepared statement needs to be re-prepared

1 Ответ

0 голосов
/ 17 ноября 2018

Вы не можете использовать параметры для имен таблиц в подготовленном операторе, поэтому вам нужно будет поместить имена таблиц в строку запроса перед подготовкой оператора.Попробуйте изменить ваши запросы на следующие:

SET @str = CONCAT('
CREATE VIEW tempView AS 
    SELECT * FROM (
        SELECT * FROM ', viewname, ' UNION SELECT * FROM ', viewname2, '
    )');

SET @str2 = CONCAT('DROP VIEW ', viewname);

SET @str3 = CONCAT('CREATE VIEW ', viewname, ' AS SELECT * FROM tempView');

После того, как вы это сделаете, вам больше не понадобятся какие-либо параметры для EXECUTE s

...