Foro de elhacker.net

Programación => Bases de Datos => Mensaje iniciado por: Cioouw en 9 Mayo 2010, 18:55 pm



Título: Update con clausala where id in () solo actualiza el primer valor del criterio
Publicado por: Cioouw en 9 Mayo 2010, 18:55 pm
Hola a todos, pues resulta que tengo el siguiente problema, tengo un procedimiento almacenado:

Código
  1. DROP PROCEDURE IF EXISTS sp_actualiza_estado_control //
  2. CREATE PROCEDURE sp_actualiza_estado_control(control text)
  3. BEGIN
  4. UPDATE control SET estado='1' WHERE idcontrol IN (control);
  5. END //

Lo llamo asi:

Código
  1. CALL sp_actualiza_estado_control('1, 2, 3');

El problema es que solo considera el primer valor, es decir solo registro cuyo ID es 1.

Yo supongo que es porque la consulta queda asi:

Código
  1. UPDATE control SET estado='1' WHERE idcontrol IN (1,2,3);

Y deberia ser asi:

Código
  1. UPDATE control SET estado='1' WHERE idcontrol IN ('1,2,3');

Haber si alquien me hecha una mano.

Saludos.


Título: Re: Update con clausala where id in () solo actualiza el primer valor del criterio
Publicado por: ^Tifa^ en 9 Mayo 2010, 19:50 pm
Tu parametro es de tipo alfanumerico sin embargo pasas numeros enteros entre comillas (las comillas califican el dato como alfanumerico no numerico) y como el parametro es de tipo alfanumerico el motor interpreta una palabra llamada '1,2,3'  (ya que el parametro del procedure es de tipo TEXT) sin embargo el campo id_control de que tipo es? por la pinta que tiene pareciese ser un INTEGER entonces suponiendo que id_control es INT y tu estas pasandole una palabra "1,2,3" el motor terminara interpretando que quieres pasarle un numero DOUBLE (por las comillas 1,2,3) a un campo INTEGER y como INTEGER no soporta numeros separados por 'comas' ni 'puntos' (o sea cero valores decimales) el motor leera el primer numero (si ese que colocas antes de la primera coma), en este caso el numero UNO que es el primero que pasas en la palabra "1,2,3" mas algun warning que capture el motor y que tu no leeras puesto que el rango "1,2,3" a pesar que es interpretado como un decimal sobrepasa el limite maximo de un campo INTEGER entonces el motor corta (trunca) el valor y solo lee el que esta antes de la primera coma para respetar el tipo de dato del campo idcontrol que es INTEGER (Si es que es INTEGER realmente).

Finalmente el motor esta leyendo esto:

Código
  1. UPDATE control SET estado='1' WHERE idcontrol IN ('1,2,3');
  2.  

Siendo '1,2,3' un dato alfanumerico que el campo idcontrol lo leera como un Decimal o Double por las comillas que separan los numeros.

Y tu quieres realmente pasarle esto:

Código
  1. UPDATE control SET estado='1' WHERE idcontrol IN (1,2,3);
  2.  

De la manera anterior los valores 1,2,3 serian numeros enteros delimitados por una coma en vez de ser valores alfanumericos. Pero para pasar lo anterior tendrias que hacerle un SPLIT a tu unico parametro pasado (ahi se alarga un pelin las instruciones del procedure) y hacer un bucle de 3 repeticiones con un incremento que vaya leyendo valor por valor para que sea 1,2,3 o en vez de alargar el procedure pasale 3 parametros de tipo INT no TEXT a tu procedure:

Código
  1. DROP PROCEDURE IF EXISTS sp_actualiza_estado_control //
  2. CREATE PROCEDURE sp_actualiza_estado_control(IN control INT, IN control1 INT, IN control2 INT )
  3. BEGIN
  4.        UPDATE control SET estado='1' WHERE idcontrol IN (control, control1, control2);
  5. END //
  6.