Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

problema SP, con un IN dentro de un cursor

Estas en el tema de problema SP, con un IN dentro de un cursor en el foro de Mysql en Foros del Web. Espero ser lo más claro posible... tengo un SP el cual recibe un parametro por ejemplo call spTest('10,11,12') dentro del procedimiento tengo una consulta del ...
  #1 (permalink)  
Antiguo 09/07/2012, 08:23
 
Fecha de Ingreso: octubre-2011
Ubicación: Chile
Mensajes: 9
Antigüedad: 12 años, 6 meses
Puntos: 0
problema SP, con un IN dentro de un cursor

Espero ser lo más claro posible... tengo un SP el cual recibe un parametro por ejemplo

call spTest('10,11,12')

dentro del procedimiento tengo una consulta del tipo select * from tabla where id IN (parametro), al parecer MySQL le agrega caracteres de escape por eso no funciona, si lo hago con CONCAT, funciona, pero no puedo utilizar CONCAT dentro de un Cursor. pongo algo de codigo

Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. CREATE DEFINER=`root`@`localhost` PROCEDURE `spListPrice`(
  4.         IN idInstrument VARCHAR(500),
  5.         IN quality CHAR(3)
  6.     )
  7.     DECLARE valores varchar(500);
  8.     DECLARE queryt VARCHAR(1000);
  9.     DECLARE _pkIntradayTransaction INTEGER;
  10.     DECLARE done INT DEFAULT 0;
  11.     DECLARE cTag CURSOR FOR
  12.         SELECT
  13.             max(pkIntradayTransaction)
  14.         FROM
  15.             tbIntradayTransactions
  16.         WHERE
  17.             fkInstrument IN (SELECT
  18.                 pkInstrument
  19.             FROM
  20.                 tbInstruments
  21.             WHERE
  22.                 fkInstrument IN (valores)) AND datetimeLastPrice <= DATE_SUB(NOW(),INTERVAL 15 MINUTE)
  23.         GROUP BY fkInstrument;
  24.  
  25.         DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

luego necesito hacer algo como

Código MySQL:
Ver original
  1.             max(pkIntradayTransaction)
  2.         FROM
  3.             tbIntradayTransactions
  4.         WHERE
  5.             fkInstrument IN (SELECT
  6.                 pkInstrument
  7.             FROM
  8.                 tbInstruments
  9.             WHERE
  10.                 fkInstrument IN (valores)) AND datetimeLastPrice <= DATE_SUB(NOW(),INTERVAL 15 MINUTE)
  11.         GROUP BY fkInstrument;

lo que sucede aquí es que no devuelve nada, como dije antes, creo que MySQL hace algo como

SELECT * FROM table WHERE id IN (`10,11,12`); al agregar eso, lo toma como si fuera un solo STRING.

ojalá alguien pudiera ayudarme, gracias!
  #2 (permalink)  
Antiguo 09/07/2012, 09:27
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: problema SP, con un IN dentro de un cursor

Primero: Las cadenas de texto se encierran entre apóstrofes. Los acentos inversos (`) son para los nombres de las tablas, bases, columnas y todo objeto creado por una sentencia DDL.
Segundo: IN() se usa para comparar un valor contra una lista de valores, pero cuando envías esto:
Código MySQL:
Ver original
  1. all spTest('10,11,12')
No estás enviando una lista de valores, sino una cadena de texto que contiene valores separados por comas, pero en esencia es un sólo valor, y no tres.
En tu caso, lo que debes hacer es comparar el valor buscado contra la lista contenida en la cadena, y para eso no sirve el IN(). Se debe usar una función de cadena denominada FIND_IN_SET():
Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. CREATE DEFINER=`root`@`localhost` PROCEDURE `spListPrice`(
  4.         IN idInstrument VARCHAR(500),
  5.         IN quality CHAR(3)
  6.     )
  7.     DECLARE valores VARCHAR(500);
  8.     DECLARE queryt VARCHAR(1000);
  9.     DECLARE _pkIntradayTransaction INTEGER;
  10.     DECLARE done INT DEFAULT 0;
  11.     DECLARE cTag CURSOR FOR
  12.         SELECT
  13.             max(pkIntradayTransaction)
  14.         FROM
  15.             tbIntradayTransactions
  16.         WHERE
  17.             fkInstrument IN (SELECT
  18.                 pkInstrument
  19.             FROM
  20.                 tbInstruments
  21.             WHERE
  22.                 (FIND_IN_SET (fkInstrument , valores)>0)
  23.               AND datetimeLastPrice <= DATE_SUB(NOW(),INTERVAL 15 MINUTE)
  24.         GROUP BY fkInstrument;
  25.  
  26.         DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
  27.     -- El resto del codigo
  28.  
  29. DELIMITER;
De todos modos, para el caso específico, es mejor usar sentencias preparadas y no un parámetro de cadena de este modo. Pero sin saber cómo es el resto del proceso, no estoy muy seguro de lo que conviene hacer.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 09/07/2012, 10:17
 
Fecha de Ingreso: octubre-2011
Ubicación: Chile
Mensajes: 9
Antigüedad: 12 años, 6 meses
Puntos: 0
Respuesta: problema SP, con un IN dentro de un cursor

Muchas gracias por responder tan pronto, justamente como dices, es lo que sucede, pero el requerimiento era así...

lo resolví de la siguiente manera,

hice un select con concat dentro del procedimiento, lo que me devuelve lo inserté a una tabla temporal, y cree un cursor en base a esa tabla temporal, tuve que agregar un paso más.

Código MySQL:
Ver original
  1. DECLARE cTag CURSOR FOR SELECT id FROM tbTransactionsTemp;
  2. DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

y dentro del procedimiento...

Código MySQL:
Ver original
  1. DROP TEMPORARY TABLE IF EXISTS tbTransactionsTemp;
  2. SET @qt = CONCAT("CREATE TEMPORARY TABLE tbTransactionsTemp SELECT max(pkIntradayTransaction) FROM tbIntradayTransactions WHERE fkInstrument IN (SELECT pkInstrument FROM tbInstruments WHERE fkInstrument IN (", idInstrument ,")) AND datetimeLastPrice <= DATE_SUB(NOW(),INTERVAL 15 MINUTE) GROUP BY fkInstrument;");
  3.  
  4. PREPARE stmt FROM @qt;
  5. EXECUTE stmt;
  6. DEALLOCATE PREPARE stmt;
  7.  
  8. OPEN cTag;
  9.  
  10.     REPEAT
  11.         FETCH cTag INTO _pkIntradayTransaction;
  12.         IF NOT done THEN
  13.            //lo que necesitaba hacer
  14.         END IF;
  15.         UNTIL done
  16.     END REPEAT;
  17.     CLOSE cTag;

no sé si sea la mejor forma para lograrlo, pero por ahora hace lo que necesitaba.

una vez más... muchas gracias...
  #4 (permalink)  
Antiguo 09/07/2012, 10:22
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: problema SP, con un IN dentro de un cursor

Es la alternativa que te mencionaba sobre las sentencias preparadas.
Nunca la había probado en ese contexto, pero si te funciona, adelante.
En cuanto a si es la mejor forma, sin conocer más sobre el requerimiento y el diseño de los datos, es difícil aconsejarte.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: cursor, select, sql, tabla, tipo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:09.