¿Hay un incremento automático en sqlite?

109

Estoy tratando de crear una tabla con un incremento automático primary keyen Sqlite3 . No estoy seguro de si esto es realmente posible, pero espero solo tener que designar los otros campos.

Por ejemplo:

CREATE TABLE people (id integer primary key auto increment, first_name varchar(20), last_name varchar(20));

Luego, cuando agrego un valor, esperaba solo tener que hacer:

INSERT INTO people
VALUES ("John", "Smith");

¿Es esto siquiera posible?

Estoy funcionando sqlite3bajo cygwinWindows 7.

ewok
fuente

Respuestas:

167

Obtienes uno gratis, llamado ROWID. Esto está en todas las tablas de SQLite, lo solicite o no.

Si incluye una columna de tipo INTEGER PRIMARY KEY, esa columna apunta a (es un alias de) la columna ROWID automática.

A ROWID (por el nombre que lo llame) se le asigna un valor cada vez que INSERT una fila, como es de esperar. Si asigna explícitamente un valor no NULO en INSERT, obtendrá ese valor especificado en lugar del incremento automático. Si asigna explícitamente un valor de NULL en INSERT, obtendrá el siguiente valor de incremento automático.

Además, debes intentar evitar:

 INSERT INTO people VALUES ("John", "Smith");

y use

 INSERT INTO people (first_name, last_name) VALUES ("John", "Smith");

en lugar. La primera versión es muy frágil: si alguna vez agrega, mueve o elimina columnas en la definición de su tabla, INSERT fallará o producirá datos incorrectos (con los valores en las columnas incorrectas).

Larry Lustig
fuente
53
ROWID no es exactamente lo mismo que un verdadero autoincremento, ya que el MISMO valor puede generarse más de una vez. Por ejemplo, con una tabla vacía, insertar 3 filas le da a la tercera fila un ROWID de 3 como se esperaba. Sin embargo, inserte 2 filas, elimine la última e inserte otra, le da a la tercera fila insertada un ROWID de 2, al igual que la segunda fila. Por lo tanto, existe un problema grave obvio si las tablas hacen referencia a los ROWID en una tabla donde ocurren eliminaciones y donde las eliminaciones o la anulación de ROWID no se realizan también en las tablas relacionadas.
Nick
10
En caso de que no sea obvio por la respuesta, puede usar ROWID en su declaración de selección, por ejemploselect rowid from people;
Colin D
@Nick solo para complementar su idea: el incremento automático es una medida de seguridad. Y no estamos hablando de dos filas que chocan en ROWID.
YoussefDir
68

Si, esto es posible. Según las preguntas frecuentes de SQLite :

Una columna declarada INTEGER PRIMARY KEYse incrementará automáticamente.

Matt Hulse
fuente
12
La advertencia, como lo menciona Uku, y también se explica en la documentación, es que debe pasar un NULL para el ID para que esto funcione.
Matt Hulse
22
Solo necesita usar un NULL si omite la lista de columnas para INSERT; nunca es una buena práctica. Si especifica las columnas, simplemente puede omitir la columna de incremento automático y recibirá el siguiente valor.
Larry Lustig
5
Otra advertencia: escriba "INTEGER ..." exactamente como se indica arriba. Una abreviatura "INT ..." NO funcionará.
Marcin Wojnarski
26

A partir de hoy - junio de 2018


Esto es lo que la documentación oficial de SQLite tiene que decir sobre el tema (negrita y cursiva son mías):

  1. La palabra clave AUTOINCREMENT impone una sobrecarga adicional de CPU, memoria, espacio en disco y E / S de disco y debe evitarse si no es estrictamente necesario. Por lo general, no es necesario.

  2. En SQLite, una columna con tipo INTEGER PRIMARY KEY es un alias para ROWID (excepto en tablas SIN ROWID) que siempre es un entero de 64 bits con signo.

  3. En un INSERT, si la columna ROWID o INTEGER PRIMARY KEY no tiene un valor explícito, entonces se llenará automáticamente con un número entero no utilizado, generalmente uno más que el ROWID más grande actualmente en uso. Esto es cierto independientemente de si se utiliza o no la palabra clave AUTOINCREMENT.

  4. Si la palabra clave AUTOINCREMENT aparece después de INTEGER PRIMARY KEY , eso cambia el algoritmo de asignación automática de ROWID para evitar la reutilización de ROWID durante la vida útil de la base de datos. En otras palabras, el propósito de AUTOINCREMENT es evitar la reutilización de ROWID de filas previamente eliminadas.


fuente
11

¿Has leído esto? ¿Cómo creo un campo AUTOINCREMENT?

INSERT INTO people
VALUES (NULL, "John", "Smith");
Uku Loskit
fuente
Entonces, lo que estás diciendo es que lo que estoy tratando de hacer no es posible, pero puedo simular. ¿Necesito usar un nulo en el inserto?
ewok
1
no necesita hacer nada, pero siempre debe insertar NULL como id, solo explica cómo lo hace sqlite internamente.
Uku Loskit
7
El NULL en INSERT solo es necesario si no especifica la lista de columnas para INSERT (en cuyo caso, necesita un número de valores que coincida exactamente con el número de columnas y debe usar NULL como marcador de posición). Pero hacer un INSERT sin especificar la lista de columnas nunca es una buena práctica. Si especifica la lista de columnas, simplemente omita tanto la columna de autoincremento como el valor NULL, y obtendrá el resultado que espera.
Larry Lustig
4

No se debe especificar la AUTOINCREMENTpalabra clave cerca PRIMARY KEY. Ejemplo de creación de clave primaria de autoincremento e inserción:

$ sqlite3 ex1

CREATE TABLE IF NOT EXISTS room(room_id INTEGER PRIMARY KEY, name VARCHAR(25) NOT NULL, home_id VARCHAR(25) NOT NULL);

INSERT INTO room(name, home_id) VALUES ('test', 'home id test');

INSERT INTO room(name, home_id) VALUES ('test 2', 'home id test 2');

SELECT * FROM room;

daré:

1|test|home id test
2|test 2|home id test 2
Denis Kutlubaev
fuente
4

Además de rowid, puede definir su propio campo de incremento automático, pero no se recomienda. Siempre es una mejor solución cuando usamos rowid que aumenta automáticamente.

La AUTOINCREMENTpalabra clave impone una sobrecarga adicional de CPU, memoria, espacio en disco y E / S de disco y debe evitarse si no es estrictamente necesario. Por lo general, no es necesario.

Lea aquí para obtener información detallada.

sonvx
fuente
aparentemente, rowid no siempre aumenta automáticamente, vea el comentario de Nick
rogerdpack
1
No es verdad. El incremento automático es mejor en algunos aspectos, ya que no reutilizará las ID, un requisito bastante importante para muchos sistemas.
O'Rooney
3

AUTOINCREMENT de SQLite es una palabra clave que se utiliza para incrementar automáticamente el valor de un campo en la tabla. Podemos incrementar automáticamente un valor de campo usando la palabra clave AUTOINCREMENT al crear una tabla con un nombre de columna específico para incrementarla automáticamente.

La palabra clave AUTOINCREMENT se puede utilizar con el campo INTEGER solamente. Sintaxis:

El uso básico de la palabra clave AUTOINCREMENT es el siguiente:

CREATE TABLE table_name(
   column1 INTEGER AUTOINCREMENT,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);

Para ver un ejemplo, consulte a continuación: Considere que la tabla EMPRESA se creará de la siguiente manera:

sqlite> CREATE TABLE TB_COMPANY_INFO(
   ID INTEGER PRIMARY KEY   AUTOINCREMENT,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

Ahora, inserte los siguientes registros en la tabla TB_COMPANY_INFO:

INSERT INTO TB_COMPANY_INFO (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'MANOJ KUMAR', 40, 'Meerut,UP,INDIA', 200000.00 );

Ahora seleccione el registro

SELECT *FROM TB_COMPANY_INFO
ID      NAME            AGE     ADDRESS             SALARY
1       Manoj Kumar     40      Meerut,UP,INDIA     200000.00
mkumar0304
fuente
2

Sé que esta respuesta llega un poco tarde.
Mi propósito para esta respuesta es para referencia de todos en caso de que encuentren este tipo de desafío con SQLite ahora o en el futuro y estén teniendo dificultades con eso.

Ahora, mirando hacia atrás en su consulta, debería ser algo como esto.

CREATE TABLE people (id integer primary key autoincrement, first_name varchar(20), last_name varchar(20));

Funciona por mi parte. Al igual que,

ingrese la descripción de la imagen aquí

En caso de que esté trabajando con SQLite, le sugiero que consulte DB Browser para SQLite . También funciona en diferentes plataformas.

Kent Aguilar
fuente
0

Lo que hace es correcto, pero la sintaxis correcta para 'incremento automático' debe ser sin espacio:

CREATE TABLE people (id integer primary key autoincrement, first_name string, last_name string);

(Tenga en cuenta también que cambié sus varchars a cadenas. Eso es porque SQLite transforma internamente un varchar en una cadena, ¿por qué molestarse?)

entonces su inserción debe ser, en lenguaje SQL lo más estándar posible:

INSERT INTO people(id, first_name, last_name) VALUES (null, 'john', 'doe');

si bien es cierto que si omite id, se incrementará y asignará automáticamente, personalmente prefiero no depender de mecanismos automáticos que podrían cambiar en el futuro.

Una nota sobre el autoincremento: aunque, como muchos señalaron, la gente de SQLite no lo recomienda, no me gusta la reutilización automática de los identificadores de los registros eliminados si no se usa el autoincremento. En otras palabras, me gusta que la identificación de un registro eliminado nunca vuelva a aparecer.

HTH

Luca Nanetti
fuente
A este respecto, comparto totalmente lo que dice O'Rooney.
Luca Nanetti