2008-11-14 23 views
6

Siempre escucho que usar "lastInsertId" (o mysql_insert_id() si no está usando PDO) es malo. En el caso de los desencadenadores, obviamente lo es, porque podría devolver algo que no es la última identificación que creó su INSERT.Alternativa a "PDO :: lastInsertId"/"mysql_insert_id"

$DB->exec("INSERT INTO example (column1) VALUES ('test')"); 
// Usually returns your newly created ID. 
// However when a TRIGGER inserts into another table with auto-increment: 
// -> Returns newly created ID of trigger's INSERT 
$id = $DB->lastInsertId(); 

¿Cuál es la alternativa?

Respuesta

2

Si vas a la ruta de ADOdb (http://adodb.sourceforge.net/), entonces se puede crear el ID de inserción antes de la mano y explícitamente el ID específico cuando se inserta. Esto puede implementarse de manera portátil (ADOdb admite una tonelada de diferentes bases de datos ...) y garantiza que está utilizando la ID de inserción correcta.

El tipo de datos SERIANO de PostgreSQL es similar excepto que es por tabla/por secuencia, especifica la tabla/secuencia para la que desea la última identificación de inserción cuando la solicita.

+0

+1 .Le escribí mi respuesta mientras escribía la suya –

+0

Parece bastante interesante. ¿Qué efecto tiene esta técnica en el rendimiento? – BlaM

+2

Sí, pero ¿qué haces si estás atascado con PDO? – Elijah

0

No es sofisticado y no es eficiente, pero si los datos que ha insertado incluyen campos únicos, entonces un SELECT puede obviamente dar lo que está buscando.

Por ejemplo:

INSERT INTO example (column1) VALUES ('test'); 
SELECT id FROM example WHERE column1 = 'test'; 
+0

obviamente;) -, sino también, evidentemente, bastante feo;) – BlaM

1

supongo que en realidad no es estado de la técnica tampoco, pero yo uso bloqueos de escritura para asegurarse de que realmente sale el último registro insertado ID.

+0

obviamente también está trabajando - pero en mi humilde opinión de bloqueo es aún más mal en aplicaciones web de alto rendimiento ... – BlaM

4

En mi humilde opinión solo se considera "malo" porque casi ninguna otra base de datos SQL (si lo hay) lo tiene.

Personalmente, me resulta increíblemente útil, y me gustaría no tener que recurrir a otros métodos más complicados en otros sistemas.

+0

al menos MSSQL tiene la misma función. En mi antiguo trabajo, el uso de la "inserción de identificación" ha causado grandes dolores de cabeza cuando alguien agregaba un desencadenante a una tabla que rompía todo el sitio web, sin una razón obvia para los que no sabían sobre ese desencadenador ... – BlaM

3

Una alternativa es usar secuencias en su lugar, por lo que debe generar la identificación usted mismo antes de hacer la inserción.

Desafortunadamente no son compatibles con MySQL pero las bibliotecas como Adodb pueden emularlas usando otra tabla. Creo sin embargo, que la emulación en sí utilizará lastInsertId() o equivalente ... pero por lo menos tienen menos probabilidades de tener un disparador en una tabla que se utilizó exclusivamente para una secuencia

-3

Usted podría intentar esto:

$sql = "SELECT id FROM files ORDER BY id DESC LIMIT 1"; 
$PS = $DB -> prepare($sql); 
$PS -> execute(); 
$result = $PS -> fetch(); 
+3

No es una alternativa en entornos de mucho tráfico. Constantemente obtendrá identificaciones incorrectas. – BlaM