Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Lucas Dillmann

Falha em Query MySQL

Recommended Posts

Olá, gostaria de pedir a vossa ajuda num pequeno (mas irritante) problema que estou tendo. Em suma, estou tentando executar uma simples Query MySQL através do PHP contida em um arquivo .sql via cron-job que irá apagar todas as tabelas e as re-inserir.

 

No caso, o MySQL me retorna um erro de sintaxe. Vejam o erro:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL [...]

Já tentei de inúmeras formas de exportação (no phpMyAdmin) ou codificação do arquivo .sql, nenhuma funciona (a atual em que ele está salvo é UTF-8).

 

Vejam o código PHP em questão:

<?php
$mysql = mysql_connect("HOST", "USUARIO", "SENHA") or die("Falha ao conectar-se ao DB");
mysql_select_db("BANCO-DE-DADOS", $mysql) or die("Falha ao escolher o DB");

$arquivo = "resetar-db.sql";
$hnd = fopen($arquivo, "r");
$query = fread($hnd, filesize($arquivo)) or die("Falha ao ler arquivo SQL");
fclose($hnd);

$query = utf8_decode($query);

mysql_query($query) or die("Falha ao executar Query: ".mysql_error());
mysql_close();
echo "Tarefa concluida";
?>

Lembrando que, caso eu adicione um header("Content-type: text/plain") e mande imprimir a variável $query em vez de a executar nenhum caractere inválido é exibido, está tudo certo conforme o arquivo .sql original.

 

Algum erro ou idéia do que possa estar acontecendo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

O erro é explícito!

Tem um erro na sua query no arquivo resetar-db.sql.

Se você puder postar para análise.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O erro é explícito!

Tem um erro na sua query no arquivo resetar-db.sql.

 

Sim e não Dee, apesar de parecer que o erro está no resetar-db.sql, a função mysql_query não aceita queries múltiplas, então se o arquivo contiver mais de uma query a função irá falhar, mesmo que esteja funcionando corretamente se executada diretamente no servidor.

 

Algum erro ou idéia do que possa estar acontecendo?

 

Para resolver seu problema, você deverá primeiro testar o arquivo resetar-db.sql e garantir que ele está funcionando corretamente. Caso esteja funcionando é como eu disse logo acima e também está muito claro no manual:

 

mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier

 

E

 

A SQL query

 

The query string should not end with a semicolon. Data inside the query should be properly escaped.

 

 

Em vez das funções mysql_connect e mysql_query, utilize a classe mysqli ou (ainda melhor) PDO

 

Caso faça a opção pela mysqli, você poderá utilizar o método mysqli::multi_query.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

O erro é explícito!

Tem um erro na sua query no arquivo resetar-db.sql.

 

Sim e não Dee, apesar de parecer que o erro está no resetar-db.sql, a função mysql_query não aceita queries múltiplas, então se o arquivo contiver mais de uma query a função irá falhar, mesmo que esteja funcionando corretamente se executada diretamente no servidor.

 

 

Como eu executaria uma procedure no PHP ?

Que função ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como eu executaria uma procedure no PHP ?

Que função ?

 

Bom, assumindo que você já tem o procedimento no banco de dados:

mysql> create schema `Dee`;
Query OK, 1 row affected (0.00 sec)

mysql> use Dee
Database changed

mysql> DELIMITER $$
mysql> CREATE PROCEDURE `Hoje`()
	-> BEGIN
	-> 	SELECT Concat( 'Hoje é ' , Date_format( Now() , '%d/%m/%Y' ) ) AS 'hoje';
	-> END$$
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;

Você pode chamá-lo pelo PHP assim:

 

Usando PDO:

$pdo = new PDO( 'mysql:host=127.0.0.1;dbname=Dee' , 'usuario' , 'senha' );
$stmt = $pdo->query( 'call Hoje();' );
$ret = $stmt->fetch( PDO::FETCH_OBJ );

echo $ret->hoje;

 

Usando mysqli:

$mysqli = new mysqli( '127.0.0.1' , 'usuario' , 'senha' , 'Dee' );
$res = $mysqli->query( 'call Hoje();' );
$ret = $res->fetch_object();

echo $ret->hoje;

$res->close();

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi João.

Vlww =)

 

Mas aí está em PDO e MySQLi.

Como seria no SQLServer ?

 

Por exemplo:

 

Criei a Stored Procedure, 'SP_Cancela_NotaFiscal', onde tem vários Selects, Updates.

Como você disse, a função mssql_query() ou mysql_query() não executa uma sequência de instruções.

 

Então como faria se assim não pode ?

<?php

   include 'conecta_banco.php';
   
   $sp = "SP_CalculaNotaFiscal";
   $exec_sp = mssql_query($sp); // Assim que eu queria saber. Assim não dá! Como é ?

?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas aí está em PDO e MySQLi.

Como seria no SQLServer ?

 

A grande vantagem do PDO é justamente essa, o fragmento que enviei anteriormente funciona perfeitamente para o SQLServer, basta apenas que você modifique o DSN para o correspondente do seu servidor, e troque o CALL do MySQL por EXECUTE do SQL Server, por exemplo:

 

//Perceba que agora, o PDO conecta ao banco de dados SQL Server e não mais ao MySQL
$pdo = new PDO( 'mssql:host=sqlserver;dbname=SeuBancoDeDados' , 'usuario' , 'senha' );

// executamos o procedimento
$stmt = $pdo->query( 'EXECUTE SP_Cancela_NotaFiscal;' );

// Recuperamos todas as linhas do resultset
foreach ( $stmt->fetchAll( PDO::FETCH_OBJ ) as $row ){
//cada $row é um objeto onde as propriedades são os nomes das colunas
}

 

O PDO veio para unificar as extensões de banco de dados de forma que você possa acessá-los utilizando a mesma interface, as extensões suportadas você encontra aqui: http://www.php.net/manual/en/pdo.drivers.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para resolver seu problema, você deverá primeiro testar o arquivo resetar-db.sql e garantir que ele está funcionando corretamente.

Em vez das funções mysql_connect e mysql_query, utilize a classe mysqli ou (ainda melhor) PDO

 

Quanto ao arquivo .sql, está tudo correto e funcional, mas é como você disse, são queries múltiplas.

 

Atualizei o código conforme você me indicou (com o PDO) e funcionou (mas apenas no servidor de testes que montei aqui no computador [popular localhost], no servidor onde ficaria não funciona - tanto o PDO como a extenção MySQLi não estão disponíveis). Obrigado por sua ajuda, atenção e disponibilidade. http://forum.imasters.com.br/public/style_emoticons/default/natal_wink.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

tanto o PDO como a extenção MySQLi não estão disponíveis).

 

Lucas, você não consegue entrar em contato com o administrador do seu servidor e solicitar que PDO seja habilitado ?

 

Muitas vezes é com um pedido simples que se resolve um grande problema...

 

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Lucas, você não consegue entrar em contato com o administrador do seu servidor e solicitar que PDO seja habilitado ?

 

Conseguir eu consigo, o porém é que sou patrocinado por tal empresa, em outras palavras, não quero abusar... http://forum.imasters.com.br/public/style_emoticons/default/natal_tongue.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

não quero abusar...

 

Acredite amigo, não é abuso solicitar que a empresa de tecnologia acompanhe a evolução do mercado. Nas próximas versões do PHP está previsto que o PDO passará a ser o padrão e não poderá mais ser desabilitado o que significa que qualquer empresa que não tiver o PDO habilitado terá que fazê-lo mais cedo ou mais tarde.

E o fato de você ser patrocinado facilita ainda mais a resolução do seu problema, uma vez que você já tem o contato necessário.

 

Agora, é óbvio que você está tentando implementar uma rotina de backup, mas, qual é o contexto do problema ?

 

Você tem uma tarefa agendada via cron:

 

1. Você gera um backup.

2. Você restaura o backup.

 

Mas, quais são as circunstâncias desses procedimentos ?

Você os faz periodicamente independente de qualquer ação externa ?

Alguma coisa causa essa ação ?

 

Talvez consigamos implementar uma outra solução para o seu problema, mas é necessário conhecer os detalhes que levam a ação e como de fato a ação é executada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agora, é óbvio que você está tentando implementar uma rotina de backup, mas, qual é o contexto do problema ?

 

Não, não é rotina de backup.

 

Em suma, eu possuo 2 blogs: o patrocinado (TechNow) e o Projeto WordPress. No segundo eu iria disponibilizar uma instalação de demonstração do WordPress 3.0, este que, ao que pude perceber, irá "juntar" o WP e WPMU.

 

Com o script acima eu iria, a cada hora, apagar todo o banco de dados e o re-inserir de forma automatizada via cron. Assim, eu evitaria que pessoas "engraçadinhas" escrevessem palavras de baixo calão em posts e/ou similares visto que, ao acessar a instalação, seria logado automaticamente como admin, permitindo assim o acesso total ao backend para testes de todas as funcionalidades (exceto área de plugins, obviamente, que poderia liberar o acesso aos meus arquivos ou banco de dados).

 

Porém, o banco de dados iria ficar localizado no servidor do blog patrocinado, visto que ele é consideravelmente melhor (com a devida configuração que permite o acesso de outros IPs ao mesmo).

 

Mas nem se preocupe com isto, eu publico um artigo demonstrando com imagens a versão e tudo fica bem. Obrigado novamente por sua atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

você pode separar essa query pelo ponto e virgula com explode e executar um a um no array retornado, vai ser um processo bem mais lento, mas acho que dá certo.

 

Um exemplo:

 

<?php
$arquivo = 'dump.sql';
$conteudo = file_get_contents($arquivo);
$consultas = explode(';', $conteudo);
foreach ($consultas AS $consulta) {
 echo "<h1>Consulta</h1><pre>{$consulta}</pre>";

 if (mysql_query($consulta)) { 
 	echo "<h2>OK</h2>";
 } else {
 	echo "<h2>ERRO</h2>";
 }

 echo "<hr />";
}
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.