Как использовать DROP TABLE IF EXISTS в хранимой процедуре MySQL

Я хочу знать, как использовать DROP TABLE IF EXISTS в процедуре MySQLstored. Я пишу довольно длинную хранимую процедуру mySQL, которая будет выполнять кучу работы, а затем загружать временную таблицу с результатами. Однако у меня возникают проблемы с этой работой.

Я видел несколько способов сделать команду temp table. В принципе, вы либо создаете временную таблицу, работаете над ней, а затем бросаете ее в конце... или бросаете ее, если она существует, создаете ее, а затем выполняете свою работу над ней.

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

Вот мои примеры:

Работает:

DELIMITER//
    DROP PROCEDURE IF EXISTS pTest//
    CREATE PROCEDURE pTest()
    BEGIN
        CREATE TEMPORARY TABLE tblTest (
            OrderDate varchar(200)
        );
        DROP TEMPORARY TABLE tblTest;
    END//
 DELIMITER ;
CALL pTest();

Работает:

DELIMITER//
    DROP PROCEDURE IF EXISTS pTest//
    CREATE PROCEDURE pTest()
    BEGIN
        DROP TEMPORARY TABLE tblTest;
        CREATE TEMPORARY TABLE tblTest (
            OrderDate varchar(200)
        );
    END//
 DELIMITER ;
CALL pTest();

Это не:

DELIMITER//
    DROP PROCEDURE IF EXISTS pTest//
    CREATE PROCEDURE pTest()
    BEGIN
        DROP TEMPORARY TABLE IF EXISTS tblTest;
        CREATE TEMPORARY TABLE tblTest (
            OrderDate varchar(200)
        );
    END//
 DELIMITER ;
CALL pTest();

Первые 2 работы, но если эта таблица существует (например, если процедура не закончилась или что-то еще), она, очевидно, закончится ошибкой "Таблица tblTest не существует". Нерабочий пример - это то, что я ищу - отбросьте таблицу, если ее там, а затем воссоздайте, чтобы я мог начать чист.

Похоже на то, что "IF EXISTS" делает эту вещь неудачной. Я скопировал код со всех видов сайтов, которые очень похожи, и ни в коем случае я не могу получить "DROP TABLE IF EXISTS..." для работы. Когда-нибудь.

Dev Server: версия mySQL Server: сообщество 5.1.47 Сервер Prod: версия mySQL Server: 5.0.45-log

Мы не можем изменить версии db (администраторы не разрешат это делать), поэтому я застрял на том, что у меня есть. Является ли это ошибкой в ​​mySQL или в процедуре?

Спасибо.

Ответы

Ответ 1

Это старый вопрос, но он появился, когда я искал DROP TABLE IF EXISTS.

Ваш нерабочий код не работал на моем сервере MySQL 5.1.70.

Все, что мне нужно было сделать, это добавить пробел между DELIMITER и//в первой строке, и все работает нормально.

Рабочий код:

DELIMITER //
    DROP PROCEDURE IF EXISTS pTest//
    CREATE PROCEDURE pTest()
    BEGIN
        DROP TEMPORARY TABLE IF EXISTS tblTest;
        CREATE TEMPORARY TABLE tblTest (
            OrderDate varchar(200)
        );
    END//
DELIMITER ;

Ответ 2

У меня также была та же проблема. Кажется, MySQL не любит проверять, существует ли таблица в некоторых версиях или что-то в этом роде. Я работал над проблемой, сначала обратившись к базе данных, и если я нашел таблицу, я ее бросил. Использование PHP:

$q = @mysql_query("SELECT * FROM `$name`");
if ($q){
    $q = mysql_query("DROP TABLE `$name`");
    if(!$q) die('e: Could not drop the table '.mysql_error());
}

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

Ответ 3

Я не знаю, почему это не работает для вас, но вы должны иметь возможность обойти проблему с помощью обработчика continue. Если вы поместите оператор DROP TABLE в свой собственный блок BEGIN...END, вы можете использовать обработчик continue, чтобы игнорировать ошибку, если таблица не существует.

Попробуйте следующее:

DELIMITER //
    DROP PROCEDURE IF EXISTS pTest //
    CREATE PROCEDURE pTest()
    BEGIN
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' BEGIN END;
        DROP TEMPORARY TABLE tblTest;
      END;
        CREATE TEMPORARY TABLE tblTest (
            OrderDate varchar(200)
        );
    END //
 DELIMITER ;
CALL pTest();