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

concurrencia - insert select max(id)

Estas en el tema de concurrencia - insert select max(id) en el foro de Mysql en Foros del Web. hola, espero me puedan ayudar con la siguiente consulta: si en una tabla no se esta utilizando un campo auto_increment. cual seria la mejor forma ...
  #1 (permalink)  
Antiguo 17/07/2011, 15:07
 
Fecha de Ingreso: abril-2010
Mensajes: 36
Antigüedad: 9 años, 6 meses
Puntos: 2
concurrencia - insert select max(id)

hola,
espero me puedan ayudar con la siguiente consulta:

si en una tabla no se esta utilizando un campo auto_increment.
cual seria la mejor forma de guardar el siguiente secuencial?

seria correcto utilizar la funcion max dentro del insert?
al usar insert ocurre una especie de block? para que cuando lleguen varios insert simultaneamente, se hace una cola entre cada uno.

el ejemplo del sp seria el siguiente:

Código MySQL:
Ver original
  1. id,
  2. texto)
  3.  
  4. (select max(id)+1 from table),
  5. 'param_descripcion');

gracias por su tiempo.
  #2 (permalink)  
Antiguo 18/07/2011, 05:15
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.318
Antigüedad: 11 años, 10 meses
Puntos: 2653
Respuesta: concurrencia - insert select max(id)

No puedes usar el MAX() en una subconsulta puesta como VALUES porque no puedes leer y actualizar la tabla al mismo tiempo en la misma acción. Además ten en cuenta que la consulta en si tiene el problema de que usas MAX() y MAX() en ese caso tiene valores contradictorios: ¿Es el MAX() hasta el momento o es el MAX() de la inserción?
Se vuelve alg inconsistente.
De todos modos existe una solución, rústica, pero eficiente: Un TRIGGER que tenga un código mas o menos así:

Código MySQL:
Ver original
  1. DELIMITER $$
  2. DROP TRIGGER IF EXISTS set_id_tabla$$
  3. CREATE TRIGGER set_id_tabla BEFORE INSERT
  4. ON tabla
  5.     IF(SELECT MAX(id) FROM tabla) IS NULL THEN
  6.       SET NEW.id = 1;
  7.     ELSE
  8.       SET NEW.Iid = (SELECT MAX(id) FROM tabla) + 1;
  9.     END IF;
  10. END$$
  11.  
  12. DELIMITER ;

Para usar este tipo de TRIGGER no debes enviar el valor del ID, sólo el resto de los campos, lo que implica que deben indicarse específicamente los valores que mandas a la tabla:
Código MySQL:
Ver original
  1. INSERT INTO table(texto)
  2. VALUES('param_descripcion');
__________________
¿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 18/07/2011, 08:37
 
Fecha de Ingreso: abril-2010
Mensajes: 36
Antigüedad: 9 años, 6 meses
Puntos: 2
Respuesta: concurrencia - insert select max(id)

muchas gracias por tu respuesta gnzsoloyo.
  #4 (permalink)  
Antiguo 22/07/2011, 14:13
 
Fecha de Ingreso: abril-2010
Mensajes: 36
Antigüedad: 9 años, 6 meses
Puntos: 2
Respuesta: concurrencia - insert select max(id)

pero si el campo id es llave me sale el siguiente error:

Código MySQL:
Ver original
  1. Error Code: 1364
  2. Field 'id' doesn't have a default value

supongo que podria enviarle un valor en el campo y el trigger lo actualizaria.

Última edición por Huaskar; 23/07/2011 a las 08:45
  #5 (permalink)  
Antiguo 18/09/2011, 12:01
 
Fecha de Ingreso: septiembre-2011
Mensajes: 1
Antigüedad: 8 años
Puntos: 0
Respuesta: concurrencia - insert select max(id)

Hola tengo un problema parecido al que se plantea en este tema solo que difiere en esta parte
IF(SELECT MAX(id_campo) FROM tabla) IS NULL THEN
En mi caso la consulta seria
IF(SELECT MAX(id_campo) FROM tabla WHERE otro_campo="otro dato" ) IS NULL THEN

El problema radica en como pasar al trigger el "otro dato" de la consulta considerando que el valor de este dato es una variable que cambia en función de la consulta.

GRACIAS POR SU AYUDA.

Etiquetas: insert, select, tabla
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 15:32.