Foros del Web » Programando para Internet » PHP »

Validar que solos los ids nuevos sean insertados

Estas en el tema de Validar que solos los ids nuevos sean insertados en el foro de PHP en Foros del Web. Buen día compañeros estoy haciendo un foreach en donde de una txt traigo una base de datos y la inserto mediante el foreach que les ...
  #1 (permalink)  
Antiguo 25/04/2016, 10:01
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Validar que solos los ids nuevos sean insertados

Buen día compañeros estoy haciendo un foreach en donde de una txt traigo una base de datos y la inserto mediante el foreach que les comentaba, pero necesito validar que no me entren ids repetidos a la tabla.

Me gustaría saber si hay alguna forma de validar esto, con php.

__________________
La vida es un juego de Ajedrez.
  #2 (permalink)  
Antiguo 25/04/2016, 10:06
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

Un pregunta por discernir un poco lo que quieres.

Si el id esta ya en la tabla, quieres descartar el registro por completo o añadirlo con otro id?

Para insertar solo si no existe puedes hacer algo asi:
Código SQL:
Ver original
  1. INSERT INTO emails (id,  email)
  2. SELECT 5, '[email protected]'
  3. FROM DUAL
  4. WHERE NOT EXISTS (SELECT id FROM emails WHERE id = 5  LIMIT 1)
__________________
Unset($vida['malRollo']);

Última edición por xerifandtomas; 25/04/2016 a las 10:15
  #3 (permalink)  
Antiguo 25/04/2016, 11:07
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Respuesta: Validar que solos los ids nuevos sean insertados

Si. Necesito que no inserte uno que ya existe.

Lo hago con un autoincremental no hay problema mira mi código
Código PHP:
Ver original
  1. foreach ($filasP as $key => $valoresP) {
  2.           $valoresP1 = trim(str_replace("'", "", $valoresP));
  3.           list($Id_U, $Id_chk, $Cnt, $Producto) = explode(",",($key + 1).",$valoresP1");
  4.           $InsertP = mysql_query("REPLACE INTO pedido(Id_U, Id_chk, Cnt, Producto) VALUES ('$Id_U','$Id_chk','$Producto','$Cnt')", $conexion);
  5.     }

Ese REPLACE que ves hay es el que debemos cambiar y creo que con lo que dices quedaría así:

Código MySQL:
Ver original
  1. INSERT INTO pedido(Id_U, Id_chk, Cnt, Producto)
  2. SELECT '$Id_U','$Id_chk','$Producto','$Cnt'
  3. FROM DUAL
  4. WHERE NOT EXISTS (SELECT Id_U FROM pedido WHERE id = $Id_U  LIMIT 1)

Sería así, por fa?
__________________
La vida es un juego de Ajedrez.
  #4 (permalink)  
Antiguo 25/04/2016, 12:01
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

Si tu id es un PK o un campo único, quizás lo más fácil es algo como esto:

Código MySQL:
Ver original
  1.   INTO tabla
  2.     (id, valor, ...)
  3.   VALUES
  4.     (25, 'valor, ...)

Básicamente en tu consulta cambia el REPLACE por IGNORE

Con ignore evitas que se inserte el registro y que te arroje un error por violación de PK o unique, indicando que es duplicado. Sólo tienes que asegurarte de que el valor que no quieres que se repita sea único o v clave primaria.


Puedes obtener más información sobre insert en el manual.

Igualmente esto es un problema que si lo vas a tratar con sql, nada tiene que ver con php.

En caso de tratarlo con php, debes realizar dos consultas, la primera para comprobar si existe el dato en la tabla.

Y mediante un if determinar si se ejecuta o no la segunda sentencia.
__________________
Unset($vida['malRollo']);

Última edición por xerifandtomas; 25/04/2016 a las 12:16
  #5 (permalink)  
Antiguo 25/04/2016, 13:05
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Respuesta: Validar que solos los ids nuevos sean insertados

Si ese ya lo hice pero como ese valor viene como autoincremental (lo creo en el foreach que viste antes) no me funciona.

http://www.forosdelweb.com/f86/mejor...gnore-1150757/

Como sería en PHP a ver, no se como más o si lo traigo ese autoincremental desde del txt y el campo varchar e index en la tabla y hay si el Insert Ignore, son muchas lineas de entrada en trafico que se actualizan cada 30 segundos. No se como más hacer D;

Intentaré nuevamente a ver
__________________
La vida es un juego de Ajedrez.
  #6 (permalink)  
Antiguo 25/04/2016, 14:01
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

A ver lo que no me queda es que quieres hacer exactamente.

Al insertar un registro:
a) si el id existe, insertarlo con otra id diferente
b) si el id existe, descartar la inserción por completo
c) si el id existe, reemplazar los datos existentes por los nuevos
__________________
Unset($vida['malRollo']);
  #7 (permalink)  
Antiguo 26/04/2016, 06:53
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Respuesta: Validar que solos los ids nuevos sean insertados

b) Si el Id existe descartar la inserción por completo... y seguir con el siguiente Id.

Mira así me llegan los datos por el txt - Mi Id o indice es un autoincremental no en la tabla de MySQL pero si en el txt así:

1,8840,'Set Cubiertos',1
2,8840,'Efectivo',1
3,8841,'Serv. Domicilio',1
4,8841,'Huev RevCebTomat',1
5,8841,'Empq Fritat Desy',1
6,8841,'.SIN',1
7,8841,'ArepitasQueso(3)',1
8,8841,'Mini Salchichas.',1
9,8841,'Empq M Salc Desy',1
10,8842,'Serv. Domicilio',1
11,8842,'Huev RevCebTomat',1
12,8842,'Empq Fritat Desy',1
13,8842,'ArepitasQueso(3)',1
14,8842,'Pan Brioche',2

Código PHP:
Ver original
  1. $filasP = file('C:\IntranetPV\Pedido.txt');
  2.  
  3.     foreach ($filasP as $key => $valoresP) {
  4.           $valoresP1 = trim(str_replace("'", "", $valoresP));
  5.           list($Id_U, $Id_chk, $Cnt, $Producto) = explode(",",$valoresP1);
  6.           $InsertP = mysql_query("REPLACE INTO pedido(Id_U, Id_chk, Cnt, Producto) VALUES ('$Id_U','$Id_chk','$Producto','$Cnt')", $conexion);
  7.     }

Actualmente remplaza... pero cuando son muchas líneas se lentea la aplicación y el servidor también sube en performance :/.

Intente con consulta INSERT IGNORE en vez de REPLACE

Código MySQL:
Ver original
  1. INSERT IGNORE INTO pedido(Id_U, Id_chk, FechaP, Total, Cnt, Producto)
  2. VALUES ('$Id_U','$Id_chk','$FechaP','$Total','$Producto','$Cnt')

Pero lo que hace es insertar una vez todos los registros y ya de hay de vuelve a insertar ni a ignorar ni nada.

Dicho esto necesito es que solo inserte una cantidad prudente (100 registros/lineas) y o así sea que valide el ultimo Id y vaya insertando (lo cual sería mucho mejor).

Insertaría solo un pedido por ciclo. (el ciclo lo hace cada 30 segundos) entonces cada vez que pase inserte solo el nuevo o el grupo de nuevos.
__________________
La vida es un juego de Ajedrez.
  #8 (permalink)  
Antiguo 26/04/2016, 07:21
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

Puedes salir del bucle con return
Código PHP:
Ver original
  1. $i=0;
  2. foreach ($filasP as $key => $valoresP) {
  3. if ($i>100){return;}
  4. /* código */
  5. ++$i;
  6. }

El problema de esto es que si no eliminas las filas ya procesadas del txt siempre va a recorrer las mismas, siempre va a recorrer las 100 primeras.

Utilizando el ignore claro, para que descarte las que dan error por clave duplicada.

El problema es que sin un contador o alguna forma que indique los registros nuevos, no hay manera de saber desde el php, cuales son nuevos y cuales no antes de procesarlos.
__________________
Unset($vida['malRollo']);
  #9 (permalink)  
Antiguo 26/04/2016, 07:37
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

Espera, quizás con mysql_affected_rows(), puedas realizar la tarea, la única duda que me cabe es que retorna la función en caso de utilizar un ignore, ya que en el manual no se indica de forma explícita, pero entiendo que debe devolver 0.

Por lo tanto podrías probar asi:

Código PHP:
Ver original
  1. $i=0;
  2. foreach ($filasP as $key => $valoresP) {
  3. if ($i>100){return;}
  4. /* código */
  5. }
Para que el bucle pare cuando haya insertado 100 registros.

Igualmente, no creo que sea lo más óptimo, por que cada vez que se ejecute va a recorrer todo asta insertar 100 registros o el bucle terminé. Por lo que si el txt no para de crecer el tiempo empleado para realizar la tarea tampoco. Ya que siempre va a empezar por la primera fila del txt.
__________________
Unset($vida['malRollo']);
  #10 (permalink)  
Antiguo 26/04/2016, 07:39
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Respuesta: Validar que solos los ids nuevos sean insertados

El txt es traido mediante en un bat (herramienta que ejecuta archivos) esté lo ejecuta cada 28/30 segundos unas consulta una base de datos Sybes de otro servidor. Teniendo esto en cuenta el puede traer las ultimas 300 o 100 lineas el problema es que....

Como hago para que inserte en la tabla y alo que vuelva a ejecutar mi ciclo ignore la key duplicada e inserte las nuevas.

No se si insertando el id que le sigue... con myssql_insert_id o si desde php se puede manejar o controlar por medio de un arreglo no se que mas se me ocurre
__________________
La vida es un juego de Ajedrez.
  #11 (permalink)  
Antiguo 26/04/2016, 08:00
 
Fecha de Ingreso: febrero-2015
Ubicación: Bogotá
Mensajes: 41
Antigüedad: 9 años, 2 meses
Puntos: 1
Respuesta: Validar que solos los ids nuevos sean insertados

Cita:
Iniciado por xerifandtomas Ver Mensaje
Espera, quizás con mysql_affected_rows(), puedas realizar la tarea, la única duda que me cabe es que retorna la función en caso de utilizar un ignore, ya que en el manual no se indica de forma explícita, pero entiendo que debe devolver 0.

Por lo tanto podrías probar asi:

Código PHP:
Ver original
  1. $i=0;
  2. foreach ($filasP as $key => $valoresP) {
  3. if ($i>100){return;}
  4. /* código */
  5. }
Para que el bucle pare cuando haya insertado 100 registros.

Igualmente, no creo que sea lo más óptimo, por que cada vez que se ejecute va a recorrer todo asta insertar 100 registros o el bucle terminé. Por lo que si el txt no para de crecer el tiempo empleado para realizar la tarea tampoco. Ya que siempre va a empezar por la primera fila del txt.
El bat se ejecuta y hay se ejecuta todo el txt y luego el script (bucle) que inserta, no se si se pueda coger el ultimo id e ingresar el siguiente.
__________________
La vida es un juego de Ajedrez.
  #12 (permalink)  
Antiguo 26/04/2016, 11:14
 
Fecha de Ingreso: octubre-2010
Ubicación: España
Mensajes: 1.007
Antigüedad: 13 años, 6 meses
Puntos: 123
Respuesta: Validar que solos los ids nuevos sean insertados

Es que todo depende, me vas diciendo cosas conforme vamos avanzando y sin tener una visión completa de lo que deseas y como se generan los datos o si siguen unas reglas claras pues es difícil establecer una solución concreta a tu problema.

Si el archivo txt se va a corresponder con la base de datos, de modo que cada línea del archivo se corresponde con un registro en la base de datos y a su vez sus id se correcponden con el número de line en el archivo, puede ser fácil.
Ya que cuando traes el archivo mediante file y generas el array cada clave del array se corresponde con el id de la base de datos (clave_array+1).

Por lo que puedes hacer lo siguiente:

Obtener el último id con un consulta como esta.
Código SQL:
Ver original
  1. SELECT MAX(id) AS id_mas_alto FROM tabla

Y ahora puedes intentar algo como esto:
Código PHP:
Ver original
  1. //cortas el array por el id más alto obtenido en la consulta
  2. $filas_pendientes = array_slice($filasP, $id_mas_alto);
  3. //desecha el array $filasP para liberar memoria
  4. unset($filasP);
  5.  
  6. //realizas tu bucle estableciendo un límite si quieres o no
  7. $i=0;
  8. foreach ($filas_pendientes as $key => $valoresP) {
  9. if ($i>100){return;}
  10. /* código */
  11. }

El único inconveniente es que se deben corresponder las filas del archivo con las de la bd. Y por lo menos no se deberían de borrar nada del archivo.



No lo he probado, por que estoy desde el móvil, pero te puede servir de idea para desarrollar tu Script.
__________________
Unset($vida['malRollo']);

Etiquetas: ids, nuevos, 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




La zona horaria es GMT -6. Ahora son las 12:50.