C'è un incremento automatico in sqlite?


109

Sto cercando di creare una tabella con un incremento automatico primary keyin Sqlite3 . Non sono sicuro che ciò sia davvero possibile, ma spero di dover designare solo gli altri campi.

Per esempio:

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

Quindi, quando aggiungo un valore, speravo di dover fare solo:

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

È anche possibile?

Sono in esecuzione sqlite3sotto cygwinWindows 7.

Risposte:


167

Ne ottieni uno gratuitamente, chiamato ROWID. Questo è in ogni tabella SQLite, che tu lo chieda o meno.

Se includi una colonna di tipo INTEGER PRIMARY KEY, quella colonna punta alla colonna ROWID automatica (è un alias per).

ROWID (con qualsiasi nome tu lo chiami) viene assegnato un valore ogni volta che INSERISCI una riga, come ti aspetteresti. Se si assegna esplicitamente un valore non NULL su INSERT, otterrà quel valore specificato invece dell'incremento automatico. Se si assegna esplicitamente un valore NULL su INSERT, otterrà il successivo valore di incremento automatico.

Inoltre, dovresti cercare di evitare:

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

e utilizzare

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

anziché. La prima versione è molto fragile: se aggiungi, sposti o elimini colonne nella definizione della tabella, INSERT fallirà o produrrà dati errati (con i valori nelle colonne sbagliate).


53
ROWID non è esattamente la stessa cosa di un vero incremento automatico poiché il valore SAME può essere generato più di una volta. Ad esempio, con una tabella vuota, l'inserimento di 3 righe fornisce alla terza riga un ROWID di 3 come previsto. Tuttavia, inserisci 2 righe, elimina l'ultima e inserisci un'altra, assegna alla 3a riga inserita un ROWID di 2, proprio come la 2a riga. Esiste quindi un ovvio problema serio se le tabelle fanno riferimento a ROWID in una tabella in cui si verificano le eliminazioni e in cui le eliminazioni o l'annullamento di ROWID non vengono eseguite anche nelle tabelle correlate.
Nick

10
Nel caso in cui non sia ovvio dalla risposta, puoi utilizzare ROWID nella dichiarazione di selezione, ad esempioselect rowid from people;
Colin D,

@ Nick solo per completare la tua idea: quindi l'incremento automatico è una misura di sicurezza. E non stiamo parlando di due righe che si scontrano in ROWID.
YoussefDir

68

Sì, è possibile. Secondo le FAQ di SQLite :

Una colonna dichiarata INTEGER PRIMARY KEYsi autoincrementerà.


12
L'avvertenza, come menzionato da Uku, e anche spiegato nella documentazione, è che è necessario passare un NULL per l'ID affinché funzioni.
Matt Hulse

22
Hai solo bisogno di usare un NULL se lasci l'elenco di colonne su INSERT - mai una buona pratica. Se specifichi le colonne, puoi semplicemente lasciare fuori la colonna di incremento automatico e riceverà il valore successivo.
Larry Lustig

5
Un altro avvertimento: scrivi "INTEGER ..." esattamente come indicato sopra. Una scorciatoia "INT ..." NON funzionerà.
Marcin Wojnarski

26

Ad oggi - giugno 2018


Ecco cosa ha da dire la documentazione ufficiale di SQLite sull'argomento (grassetto e corsivo sono miei):

  1. La parola chiave AUTOINCREMENT impone CPU, memoria, spazio su disco e overhead di I / O su disco aggiuntivi e dovrebbe essere evitata se non strettamente necessaria. Di solito non è necessario.

  2. In SQLite, una colonna di tipo INTEGER PRIMARY KEY è un alias per ROWID (tranne nelle tabelle WITHOUT ROWID) che è sempre un intero con segno a 64 bit.

  3. Su un INSERT, se la colonna ROWID o INTEGER PRIMARY KEY non viene esplicitamente dato un valore, allora verrà riempita automaticamente con un numero intero non utilizzato, di solito uno in più rispetto al ROWID più grande attualmente in uso. Ciò è vero indipendentemente dall'utilizzo o meno della parola chiave AUTOINCREMENT.

  4. Se la parola chiave AUTOINCREMENT viene visualizzata dopo INTEGER PRIMARY KEY , viene modificato l'algoritmo di assegnazione ROWID automatica per impedire il riutilizzo dei ROWID durante la durata del database. In altre parole, lo scopo di AUTOINCREMENT è impedire il riutilizzo di ROWID da righe precedentemente eliminate.


11

Hai letto questo? Come creo un campo AUTOINCREMENT.

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

Quindi quello che stai dicendo è che quello che sto cercando di fare non è possibile, ma posso simulare. Ho bisogno di usare un null nell'inserto?
ewok

1
non devi fare nulla, ma inserire sempre NULL come id, spiega solo come sqlite lo fa internamente.
Uku Loskit

7
Il NULL su INSERT è richiesto solo se non si specifica l'elenco di colonne su INSERT (nel qual caso, è necessario un numero di valori che corrisponda esattamente al numero di colonne e si deve utilizzare NULL come segnaposto). Ma fare un INSERT senza specificare l'elenco delle colonne non è mai una buona pratica. Se specifichi l'elenco di colonne, lascia fuori sia la colonna autoincrement che il valore NULL e otterrai il risultato che ti aspetti.
Larry Lustig

4

Non si dovrebbe specificare la AUTOINCREMENTparola chiave vicino PRIMARY KEY. Esempio di creazione della chiave primaria con incremento automatico e inserimento:

$ 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

4

Oltre a rowid, puoi definire il tuo campo di incremento automatico ma non è consigliato. È sempre una soluzione migliore quando usiamo rowid che viene automaticamente aumentato.

La AUTOINCREMENTparola chiave impone CPU, memoria, spazio su disco e overhead di I / O su disco extra e dovrebbe essere evitata se non strettamente necessaria. Di solito non è necessario.

Leggi qui per informazioni dettagliate.


apparentemente rowid non viene sempre aumentato automaticamente, vedi il commento di Nick
rogerdpack

1
Non vero. L'incremento automatico è migliore sotto alcuni aspetti, poiché non riutilizzerà gli ID, un requisito piuttosto importante per molti sistemi.
O'Rooney

3

SQLite AUTOINCREMENT è una parola chiave utilizzata per l'incremento automatico di un valore di un campo nella tabella. È possibile incrementare automaticamente un valore di campo utilizzando la parola chiave AUTOINCREMENT quando si crea una tabella con un nome di colonna specifico per incrementarlo automaticamente.

La parola chiave AUTOINCREMENT può essere utilizzata solo con il campo INTEGER. Sintassi:

L'utilizzo di base della parola chiave AUTOINCREMENT è il seguente:

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

Per esempio vedi sotto: considera la tabella AZIENDA da creare come segue:

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

Ora, inserisci i seguenti record nella tabella TB_COMPANY_INFO:

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

Ora seleziona il record

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

2

So che questa risposta è un po 'in ritardo.
Il mio scopo per questa risposta è per il riferimento di tutti se dovessero incontrare questo tipo di sfida con SQLite ora o in futuro e stanno attraversando un momento difficile con esso.

Ora, guardando indietro alla tua domanda, dovrebbe essere qualcosa del genere.

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

Funziona dalla mia parte. Così,

inserisci qui la descrizione dell'immagine

Nel caso in cui tu stia lavorando con SQLite, ti suggerisco di controllare DB Browser per SQLite . Funziona anche su diverse piattaforme.


0

Quello che fai è corretto, ma la sintassi corretta per "incremento automatico" dovrebbe essere senza spazio:

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

(Tieni inoltre presente che ho cambiato i tuoi varchar in stringhe. Questo perché SQLite trasforma internamente un varchar in una stringa, quindi perché preoccuparsi?)

allora il tuo inserto dovrebbe essere, nel linguaggio SQL il più standard possibile:

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

mentre è vero che se si omette id verrà automaticamente incrementato e assegnato, personalmente preferisco non affidarmi a meccanismi automatici che potrebbero cambiare in futuro.

Una nota sull'autoincrement: sebbene, come molti hanno sottolineato, non sia consigliato da persone SQLite, non mi piace il riutilizzo automatico degli id ​​dei record cancellati se l'autoincrement non viene utilizzato. In altre parole, mi piace che l'id di un record cancellato non appaia mai più.

HTH


A questo proposito condivido totalmente ciò che dice O'Rooney.
Luca Nanetti
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.