ti-enxame.com

Como usar DROP TABLE IF EXISTS em um procedimento armazenado do MySQL

Eu quero saber como usar DROP TABLE IF EXISTS em um procedimento MySQLstored. Estou escrevendo um Procedimento Armazenado mySQL bastante longo que fará um monte de trabalho e, em seguida, carregará uma tabela temporária com os resultados. No entanto, estou tendo problemas para fazer isso funcionar. 

Eu vi algumas maneiras de fazer a coisa da tabela temporária. Basicamente, você pode criar a tabela temporária, trabalhar nela e, em seguida, soltá-la no final ... ou soltá-la se existir, criá-la e depois fazer o seu trabalho nela.

Eu prefiro o segundo método para que você comece sempre limpo, e é uma verificação interna para a existência da tabela. No entanto, parece que não consigo fazer isso funcionar:

Aqui estão meus exemplos:

Isso funciona:

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();

Isso funciona:

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();

Isso não faz:

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();

Os dois primeiros trabalham, mas se essa tabela existir (como se o procedimento não tivesse terminado ou algo assim), obviamente terminaria com um erro "Tabela tblTest não existe". O exemplo que não funciona é o que eu estou procurando - solte a tabela se ela estiver lá e, em seguida, recrie-a para que eu possa começar limpo.

Parece que é o "SE EXISTE" fazendo essa coisa falhar. Eu copiei o código de todos os tipos de sites que fazem coisas muito semelhantes e em nenhum caso eu posso obter um "DROP TABLE IF EXISTS ..." para funcionar. Sempre.

Servidor de Desenvolvimento: Versão do mySQL Server: 5.1.47-community Prod Server: Versão do mySQL Server: 5.0.45-log

Não podemos alterar as versões do db (os DBAs não permitem isso), então estou preso no que tenho. Isso é um bug no mySQL ou no procedimento?

Obrigado.

15
Coach John

É uma pergunta antiga, mas surgiu quando eu estava procurando DROP TABLE IF EXISTS.

Seu código não funcional não funcionou no meu servidor MySQL 5.1.70.

Tudo o que eu tive que fazer foi adicionar um espaço entre DELIMITER e // na primeira linha, e tudo funcionou bem.

Código de trabalho:

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 ;
16
IvanD

Eu também tive o mesmo problema. Parece que o MySQL não gosta de verificar se a tabela existe em algumas versões ou algo assim. Eu trabalhei em torno do problema, consultando o banco de dados em primeiro lugar, e se eu encontrei uma tabela eu deixei cair. Usando 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());
}

Você suprime o erro na primeira consulta com o símbolo @, para que você não tenha um erro de interferência e solte a tabela quando a consulta retornar falso.

2
Abraham Brookes

Eu não sei porque isso não está funcionando para você, mas você deve ser capaz de contornar o problema usando um manipulador continuar. Se você colocar a instrução DROP TABLE em seu próprio bloco BEGIN...END, poderá usar um manipulador continue para ignorar o erro se a tabela não existir.

Tente isto:

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();
1
Ike Walker

Eu recomendo adicionar nova linha 

SET sql_notes = 0// before DROP PROCEDURE IF EXISTS get_table //

Caso contrário, ele mostrará o aviso PROCEDURE não existe.

0
user5957221