[ Foro de SQL (y MySQL) ]

duda sentencia mysql

09-Oct-2016 20:05
Victor Pelegrin
33 Respuestas

Buena ,  no logro entender porque con la primera sentencia me da un resultado(el que esperaba) y la segunda sentencia me da vacío.

SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN DomingoApertura2 AND DomingoCierre2




SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN CONCAT(getDiaSemana(), 'Apertura2') AND CONCAT(getDiaSemana(), 'Cierre2')



Lo que quiero conseguir es que la segunda tras realizar las funciones termine siendo en la práctica como la primera.
Cuando hago getDiaSemana() evidentemente me sale Domingo , lo he comprobado.

¿Alguna idea de dónde estoy fallando?


12-Oct-2016 20:35
German Bernhardt

La variable DomingoApertura2 que contiene? O es un string literal


14-Oct-2016 13:32
Victor Pelegrin

Hola de nuevo.

Sigo sin resolverlo.

En DomingoApertura2 tengo un TIME

La primera sentencia si que se ejecuta correctamente. Lo que quiero es comprobar que el Time que me devuelve CURRENT_TIME esta entre las horas de DomingoApertura2 y DomingoCierre2.
Ésta primera sentencia si que funciona perfecta.

En realidad uso la segunda sentencia porque tengo los mismos campos para Lunes, martes, miercoles... hasta domingo y quería conseguir acceder a ellos de esa forma. Calculando en que día de la semana estoy.
Pero ésta segunda sentencia se ejecuta sin problemas pero me da resultado vacío.
Lo cual veo muy raro ya que en teoría dice lo mismo la primera y la segunda .

Gracias por contestar un saludo!


14-Oct-2016 17:40
German Bernhardt

Si me pasas el codigo y la estructura basica de la tabla te lo puedo resolver, ya entendi tu problema.

pone un print de la variable que te devuelve:
> CURRENT_TIME
> DomingoApertura2
> CONCAT(getDiaSemana(), 'Apertura2')
// CREO QUE LE TENES QUE SACAR LAS COMILLAS CONCAT(getDiaSemana(), Apertura2)

HACELO HACIENDO ESTO:

> SELECT  CURRENT_TIME;

> SELECT DomingoApertura2;

> SELECT CONCAT(getDiaSemana(), 'Apertura2');

// CREO QUE AHI TE VAS A DAR CUENTA AL TOQUE


14-Oct-2016 17:53
German Bernhardt

a mi SELECT CURRENT_TIME me devuelve la hora no el dia 12:39:25.000000


14-Oct-2016 18:03
German Bernhardt

CURRENT_DATE te devuelve el dia 2016-10-14

seria creo estoy trabajando en el aire

SELECT nombreNegocio FROM anuncio
WHERE
'2016-10-13 12:44:05' BETWEEN
'2016-10-13 09:00:00' AND
'2016-10-13 18:00:00'

y quedaria:

SELECT nombreNegocio FROM anuncio
WHERE
CONCAT(CURRENT_DATE,' ',CURRENT_TIME) BETWEEN
CONCAT(getDiaSemana(), ' ', Apertura2) AND
CONCAT(getDiaSemana(), ' ', Cierre2)

// getDiaSemana() te devuelve la fecha ej: 2016-08-23
// le concatenamos el espacio separador ' '
// Apertura2 te devuelve la hora 09:00:00
// y Cierre2 te devuelve la hora del cierre 18:00:00


14-Oct-2016 23:19
Victor Pelegrin

Hola, te comento de forma mas detallada.

La estructura de la base de datos es simple. Tengo una tabla llamada anuncio con diversos campos como

- nombreNegocio
y los que te muestro en la siguiente foto para poner las horas que abren esos negocios cada dia de la semana.
https://subefotos.com/ver/?65fd54af20c59bce6a4c078264f9a992o.jpg#codigos


Después de eso he metido a modo de prueba varios anuncios con la siguiente información sobre esos campos de hora. Te pongo los del Viernes ya que justo hoy es Viernes.
https://subefotos.com/ver/?d4785d6b72ab1a586d0473f2029ea24ao.jpg#codigos

Si pongo a mano esta sentencia me sale un resultado correcto. Comprueba que los 3 anuncios a los cuales les he puesto esas horas de apertura y cierre el Viernes me aparecen.

https://subefotos.com/ver/?f7b2f57254a4c386a007cfd5de46c5eco.jpg#codigos

Sin embargo para no realizar demasiada lógica en java y php, he decidido que una buena forma de poder saber en que dia de la semana estoy sería creandome una función en MySQL que la he llamado getDiaSemana() . ésta lo que hace es calcularme el día de la semana del servidor y me lo pone en castellano. He comprobado la función y funciona correctamente.
De hecho te expongo las siguientes fotos para que veas el resultado de usarla.
https://subefotos.com/ver/?cd8620e083bf3cc5c82a444670fe2b90o.jpg#codigos

Una vez tengo todo esto lo que quiero es poder hacer una sentencia MySQL más genérica combinando todo para que no tenga que indicarle a mano en que día de la semana estoy.
Esto se me ocurrio porque hice un SELECT y me di cuenta que podía obtener lo siguiente.

https://subefotos.com/ver/?bdcfeaa780c43c70bcdfb47c46673cc7o.jpg#codigos

Como ves me sale algo totalmente coherente.



Muy bien, una vez llegados aquí es cuando me decido a hacer la formula GENÉRICA que es la que no me funciona y no entiendo el porque ya que los resultados anteriores si que me salían correctos.

https://subefotos.com/ver/?cf75416b539adbe51669b4fa04cf00d5o.jpg#codigos

Como ves esta última sentencia me sale de resultado vacío y mi intención es que me salgan los 3 negocios que sí que están abiertos.


Espero haberme explicado un poco mejor.

De las dos formas que me has propuesto para usar el CONCAT me da error de sintaxis en ambas

https://subefotos.com/ver/?09e0488c97db5d0acfdd08f39852fdaao.jpg#codigos

https://subefotos.com/ver/?da4ca3cf4f2748ade82c10b4fc15e983o.jpg#codigos



15-Oct-2016 01:18
Invitado (gbernhardt)

Estoy con el tel ahora cuando agarre la compu me fijo saludos


15-Oct-2016 01:49
Victor Pelegrin

ok muchas gracias! porque me tiene desesperado este asunto :(


16-Oct-2016 02:58
German Bernhardt

Si ya entendi tu problema ahora si


16-Oct-2016 03:20
German Bernhardt

Mira:

SELECT nombreNegocio FROM anuncio WHERE


CURRENT_TIME    BETWEEN DomingoApertura2   AND DomingoCierre2
'12:39:25'                 BETWEEN '09:00:00'                       AND  '18:00:00' //PERO LA DB LO INTERPRETA ASI
'12:39:25'                 BETWEEN 'DomingoApertura2' AND 'DomingoCierre2' // Y AL HACER CONCAT INTERPRETA

osea no es lo mismo

DomingoApertura2

que

'DomingoApertura2'

solucion, varias, en php con un eval('DomingoApertura2' ) se soluciona, pero dentro del mismo mysql dejame pensar



16-Oct-2016 03:30
German Bernhardt

mira aca hay algo de como hacer eval en mysql

http://stackoverflow.com/questions/999200/is-it-possible-to-execute-a-string-in-mysql

si getDia() en vez de traerte 'Martes' te trae toda la sentencia sql emularia toda la sentencia


16-Oct-2016 03:32
German Bernhardt

@Expression = 'SELECT "Hello, World!";';
PREPARE myquery FROM @Expression;
EXECUTE myquery;

lo tuyo seria

@Expression = getDia();
PREPARE myquery FROM @Expression;
EXECUTE myquery;


16-Oct-2016 03:38
German Bernhardt

o tambien

@sql='SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ';
@sql=CONCAT(@sql,getDiaSemana(), 'Apertura2 AND ',getDiaSemana(),'Cierre2');
PREPARE myquery FROM @sql;
EXECUTE myquery;


16-Oct-2016 21:14
German Bernhardt

Lo probe y anda perfecto, faltaba el SET para que no te de error!

SET @sql='SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ';

SET @sql=CONCAT(@sql,getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

PREPARE myquery FROM @sql;

EXECUTE myquery;


16-Oct-2016 21:59
German Bernhardt

En modo consola funciona perfecto, ahora en php funciona pero no te muestra los resultados.

entonces es mas facil todavia.

$sql='SELECT getDiaSemana() AS dia';
if($result=mysqli_query($session,$sql)) {
   while($fetch=$result->fetch_array()) {
       $dia=$fetch['dia'];
   }
}

if(isset($dia)){
   $sql='SELECT nombreNegocio FROM anuncio';
   $sql.=' WHERE CURRENT_TIME BETWEEN ';
   $sql.=$dia.'Apertura1 AND '.$dia.'Cierre1';
   if($result=mysqli_query($session,$sql)) {
       while($fetch=$result->fetch_array()) {
           print $fetch['nombreNegocio'].PHP_EOL;
       }
   }
}


17-Oct-2016 18:04
Victor Pelegrin

Buenas, me pillas justo de viaje German. He leído por encima lo que comentas y tiene muy buena pinta.
Yo también pensé que podía ser lo que me has comentado pero lo que me parecía extraño es que mysql comparara directamente una fecha con un concat que no muestra fecha sino un varchar no?



En principio mi idea es ponerlo todo en UNA sentencia de mysql la cual paso primero por php con un query.

Entonces doy por hecho que lo que quieres decir es que en el parametro de php que mando para que haga la sentencia deberia meter todo esto?


SET @sql='SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ';

SET @sql=CONCAT(@sql,getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

PREPARE myquery FROM @sql;

EXECUTE myquery;


Decir que prefiero mucho antes que se ejecute todo en mysql antes que tu ultima opción de php por seguir con el patrón de trabajo que he seguido hasta ahora.

En cuanto llegue a casa lo pruebo y te comento.

Mil y una gracias!


17-Oct-2016 19:51
Victor Pelegrin

Por cierto, ¿cómo has sido capaz de hacer el debuger?

¿O lo has interpretado así para explicarmelo?

Un saludo.


17-Oct-2016 21:06
Victor Pelegrin

he estado probando y al intentar que me funcione ejecutando lo siguiente en SQL em da el siguiente fallo :(

SET @sql='SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ';

SET @sql=CONCAT(@sql,getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

PREPARE myquery FROM @sql;

EXECUTE myquery;



https://subefotos.com/ver/?ad1bfc24cfe0f6cca362fab1fcae26c5o.jpg#codigos


Esto lo estoy ejecutando en warmpserver en una version de mysql 5.7.14

A tit e funciona poniéndolo tal cual?




17-Oct-2016 23:45
German Bernhardt

Ahi te subi los screenshots

https://subefotos.com/ver/?4610c5991eaa3fd71bfc8a4334d054d6o.png#codigos

en modo consola funciona perfecto reemplace getDiaSemana(); por 'domingo' porque no tengo la funcion.

tambien te mando la estructura de la tabla que creo que vos tenes, y como podras observar en la parte de abajo te manda lo que me tira cundo lo ejecuto en phpmyadmin, que basicamente es php!

me dice que la sentencia devolvio 1 resultado ("El pilar") pero fijate que no me muestra el registro, por eso te mande el otro codigo en php

ahora el error que vos me mandas no es de mysql, es de phpmyadmin, tendrias que probar en consola para ver el verdadero error, ponele en phpmyadmin algo asi y en consola algo asi! en las dos me dice que no encuentra la funcion getDiaSemana();

https://subefotos.com/ver/?a70bd318e4dedc989ebdc6c83feffffdo.png#codigos


17-Oct-2016 23:52
German Bernhardt

que es debuger?


18-Oct-2016 01:41
Victor Pelegrin

queria decir la forma en la que te das cuenta lo que va ejecutando mysql.

croe que se puede ir paso a paso mirando que es lo que va haciendo el cógido que ejecutas


18-Oct-2016 17:06
Victor Pelegrin

Hola de nuevo German. Me he leído toda tu información y entiendo a la perfección lo que me quieres decir. Pero me están pasando lo siguiente.
Si pongo

SET @Expression = 'SELECT "Hello, World!";';
PREPARE myquery FROM @Expression;
EXECUTE myquery;

me funciona correctamente.

Pero si pongo una consulta cualquiera que involucre alguna tabla(pongo una fácil para que se nos haga más simple)  me da el siguiente error. He probado con varias y me sigue dando el mismo error.

¿Sabes que puede estar pasando?

SET @Expression = 'SELECT nombreNegocio FROM anuncio;';
PREPARE myquery FROM @Expression;
EXECUTE myquery;


Un saludo y gracias!


18-Oct-2016 17:08
Victor Pelegrin

Se me olvido colgarte la foto del fallo. Aquí la tienes :)

https://subefotos.com/ver/?d08534a720b8dac3721acf0dbc9fbe1bo.jpg#codigos


18-Oct-2016 17:40
German Bernhardt

Proba en modo consola porque te sigue pasando un error en phpmyadmin no en mysql,

mysql.exe -h 127.0.0.1 -u root

> USE mydb;

> ..........

> quit;


19-Oct-2016 02:22
Victor Pelegrin

Vale, me pasa lo siguiente.

Si ejecuto

SET @Expression = 'SELECT nombreNegocio FROM anuncio;';
PREPARE myquery FROM @Expression;
EXECUTE myquery;

me funciona via consola.

https://subefotos.com/ver/?aff3a2c01c111732098ed25e3634ad1fo.jpg#codigos


Si ejecuto el cógido que dijiste que te funcionaba ya no me va. Imagino que habrá algún fallo por versión de MySQL en la sintaxis del CONCAT.

SET @sql='SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ';

SET @sql=CONCAT(@sql,getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

PREPARE myquery FROM @sql;

EXECUTE myquery;


https://subefotos.com/ver/?1d33f926af8d3c46f9b68b6b4fa38749o.jpg#codigos



De todos modos el query lo hago desde un .php  Espero que no me de error desde allí una vez consiga solucionar la sintaxis del concat.
¿Me podrías confirmar que la segunda sentencia te funciona a la perfección? ¿Y tú versión de mysql?


Muchísimas gracias por tu ayuda. Realmente me está sirviendo aunque aún no haya conseguido el objetivo de hacerlo funcionar.


19-Oct-2016 02:42
German Bernhardt

Si lo vas a hacer desde php hace esto!, que si funciona!

$sql='SELECT getDiaSemana() AS dia';
if($result=mysqli_query($session,$sql)) {
  while($fetch=$result->fetch_array()) {
      $dia=$fetch['dia'];
  }
}

if(isset($dia)){
  $sql='SELECT nombreNegocio FROM anuncio';
  $sql.=' WHERE CURRENT_TIME BETWEEN ';
  $sql.=$dia.'Apertura1 AND '.$dia.'Cierre1';
  if($result=mysqli_query($session,$sql)) {
      while($fetch=$result->fetch_array()) {
          print $fetch['nombreNegocio'].PHP_EOL;
      }
  }
}

ahora el error del CONCAT si es un error por la diferencia de la version
proba haciendo solamente:

SET @sql=CONCAT(getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

si funciona podes hacer aunque te va a quedar mas largo

SET @sql=CONCAT('SELECT nombreNegocio FROM anuncio WHERE CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');

tenes que ver en que punto al hacer el set te esta fallado, si al intentar agregar getDiaSemana() o por declarar 2 veces SET @sql, sino a probar y buscar el error! ej:

SET @sql=CONCAT(getDiaSemana(), '');

SET @sql=CONCAT(getDiaSemana(), 'Apertura1 AND ');

SET @sql=CONCAT(getDiaSemana(), 'Apertura1 AND ',getDiaSemana());

SET @sql=CONCAT(getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1');


19-Oct-2016 20:53
Victor Pelegrin

Hola de nuevo German.

Ya he conseguido que me vaya en la consola de mysql perfecto con la siguiente sintaxis:

SET @sql=CONCAT('SELECT idAnuncio, image FROM anuncio WHERE (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1) OR (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura2 AND ',getDiaSemana(),'Cierre2)', 'LIMIT 5'); PREPARE myquery FROM @sql; EXECUTE myquery;

https://subefotos.com/ver/?9734083e5b354257472ba52bf75f832fo.jpg#codigos

Como ves me va perfecto.


Sin embargo si intento pasar la sentencia por medio de un .php o directamente desde el phpadmin de warmpserver no me funciona.
He pasado todas las demás sentencias de mysql con el mismo código que te muestro y todas me funcionaban salvo esta. Sigo pensando que es un error de sintaxis o algo parecido pero no sé como solucionarlo ya que en consola de mysql funciona pero en .php o un phpadmin no.

Te mando fotos para que veas a lo que me refiero:
Desde .php(no hace nada):

<?php


$aux=$_REQUEST['parametro'];
$cnx=new PDO("mysql:host=localhost;dbname=mydb","root", "");

$res=$cnx->query("SET @sql=CONCAT('SELECT idAnuncio, image FROM anuncio WHERE (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1) OR (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura2 AND ',getDiaSemana(),'Cierre2)', 'LIMIT 5'); PREPARE myquery FROM @sql; EXECUTE myquery;");

$datos = array();

foreach($res as $row){
   $datos[]=array_map('utf8_encode',$row);
}

echo json_encode($datos);

Desde el phpmyadmin (aqui al menos me da info la consola de porque no se muestra).
He metido sentencia por  sentencia y el problema aparece al ejecutar el PREPARE

SET @sql=CONCAT('SELECT idAnuncio, image FROM anuncio WHERE (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura1 AND ',getDiaSemana(),'Cierre1) OR (CURRENT_TIME BETWEEN ',getDiaSemana(), 'Apertura2 AND ',getDiaSemana(),'Cierre2)', 'LIMIT 5');       FUNCIONA!!

PREPARE myquery FROM @sql;      NO FUNCIONA , he probado tanto con el    ; al final como sin él

https://subefotos.com/ver/?4df66a42172de64c4e5bb64e02e0f197o.jpg#codigos

¿alguna idea para poder resolver este bug? En cuanto me funcione en el phpmyadmin se supone que desde el .php será la misma sintaxis.
Respecto a tu cógido de php que pasaste me gusta pero me gustaría seguir con la misma metodología usando mi .php por cuestión de legibilidad.


Un saludo y mil gracias por tu atención!




19-Oct-2016 21:01
Victor Pelegrin

Investigando el mensaje n4   http://www.forosdelweb.com/f86/ejecutar-sentencia-variable-string-procedimiento-almacenado-784456/


19-Oct-2016 21:49
German Bernhardt

Desde PHP no te va a funcionar a menos que hagas esto!, por lo menos lo que yo comprobe...

<?php
$aux=$_REQUEST['parametro'];
$cnx=new PDO("mysql:host=localhost;dbname=mydb","root", "");

$sql='SELECT getDiaSemana() AS diaActual';
$res=$cnx->query($sql);

/*
* esta parte no se si esta bien :S
*/
foreach($res as $row){
// CREO QUE ES ASI $diaActual deberia ser igual al dia domingo o lunes , etc!
  $diaActual=array_map('utf8_encode',$row);
}

$sql='SELECT idAnuncio, image FROM anuncio';
$sql.=' WHERE (CURRENT_TIME BETWEEN '.$diaActual.'Apertura1 AND '.$diaActual.'Cierre1)';
$sql.=' OR (CURRENT_TIME BETWEEN '.$diaActual.'Apertura2 AND '.$diaActual.'Cierre2) LIMIT 5';
$res=$cnx->query($sql);

$datos = array();
foreach($res as $row){
  $datos[]=array_map('utf8_encode',$row);
}

echo json_encode($datos);

La unica diferencia es que estas haciendo 1 consulta mas y queda mas prolijo, te vas a ahorrar muchos dolores de cabeza, por lo menos desde mi experiencia! saludos...


19-Oct-2016 21:58
Victor Pelegrin

me equivoqué de link . pero algunas personas dicen por google que tienen el mismo problema y que se debe a que a partir de ciertas versiones no dejan hacer varias sentencias a la vez.

Hablan de STATEMENT FLAG o algo así, pero no he conseguido resolver el bug :(


19-Oct-2016 22:01
Victor Pelegrin

Vale, entiendo lo que quieres hacer.

Haces lo que me acabas de escribir para evitar realizar varias sentencias a la vez verdad? y realizar por separado para resolver ese bug que tenemos.

Voy a probarlo! Un saludo y muchas gracias! Te diré si me funciona :)


19-Oct-2016 23:07
Victor Pelegrin

Me funciona!! He modificado alguna pequeña cosa pero ya va!!

Eres un grande, llevaba 2 semanas con este asunto. se me caen casi las lagrimas :_)

Muchísimas gracias por tu ayuda! no sé como recompensarte la verdad xD.

¿Tienes alguna web, canal de youtube o similar para seguirte?

<?php


$aux=$_REQUEST['parametro']; //recogemos el parametro de android

$cnx=new PDO("mysql:host=localhost;dbname=mydb","root", "");
$sql="SELECT getDiaSemana() AS diaActual";
$res=$cnx->query($sql);
foreach($res as $row){
// CREO QUE ES ASI $diaActual deberia ser igual al dia domingo o lunes , etc!
 $diaActual=array_map('utf8_encode',$row);
}


$cnx2=new PDO("mysql:host=localhost;dbname=mydb","root", "");
$sql2="SELECT imagen, idAnuncio FROM anuncio";
$sql2.=" WHERE (CURRENT_TIME BETWEEN ".$diaActual[0]."Apertura1 AND ".$diaActual[0]."Cierre1)";
$sql2.=" OR (CURRENT_TIME BETWEEN ".$diaActual[0]."Apertura2 AND ".$diaActual[0]."Cierre2) LIMIT ".$aux;
$res2=$cnx2->query($sql2);



$datos = array();

foreach($res2 as $row){
   $datos[]=array_map('utf8_encode',$row);
}

echo json_encode($datos);

Un saludo crack!


20-Oct-2016 22:15
German Bernhardt

De nada, solo mail german.bernhardt@gmail.com saludos!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)