Existe um incremento automático no sqlite?

109

Estou tentando criar uma tabela com incremento automático primary keyno Sqlite3 . Não tenho certeza se isso é realmente possível, mas espero ter apenas que designar os outros campos.

Por exemplo:

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

Então, quando adiciono um valor, esperava apenas ter que fazer:

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

Isso é mesmo possível?

Estou executando sqlite3sob cygwinno Windows 7.

ewok
fonte

Respostas:

167

Você recebe um gratuitamente, chamado ROWID. Isso está em cada tabela SQLite, quer você peça ou não.

Se você incluir uma coluna do tipo INTEGER PRIMARY KEY, essa coluna aponta para (é um alias para) a coluna ROWID automática.

ROWID (por qualquer nome que você o chame) recebe um valor sempre que você INSERT uma linha, como seria de esperar. Se você atribuir explicitamente um valor não NULL em INSERT, ele obterá o valor especificado em vez do incremento automático. Se você atribuir explicitamente um valor NULL em INSERT, ele obterá o próximo valor de incremento automático.

Além disso, você deve tentar evitar:

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

E use

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

em vez de. A primeira versão é muito frágil - se você adicionar, mover ou excluir colunas em sua definição de tabela, o INSERT irá falhar ou produzir dados incorretos (com os valores nas colunas erradas).

Larry Lustig
fonte
53
ROWID não é exatamente o mesmo que um incremento automático verdadeiro, pois o MESMO valor pode ser gerado mais de uma vez. Por exemplo, com uma tabela vazia, a inserção de 3 linhas fornece à terceira linha um ROWID de 3 conforme o esperado. No entanto, inserir 2 linhas, excluir a última e inserir outra, dá à 3ª linha inserida um ROWID de 2, assim como a 2ª linha tinha. Portanto, há um problema sério e óbvio se as tabelas fizerem referência a ROWIDs em uma tabela onde as exclusões ocorrem e onde as exclusões ou anulação de ROWID também não são feitas nas tabelas relacionadas.
Nick de
10
Caso a resposta não seja óbvia, você pode usar ROWID em sua declaração selecionada, por exemploselect rowid from people;
Colin D
@Nick apenas para complementar a sua ideia: portanto, o incremento automático é uma medida de segurança. E não estamos falando sobre duas linhas colidindo no ROWID.
YoussefDir
68

Sim, isso é possível. De acordo com o SQLite FAQ :

Uma coluna declarada INTEGER PRIMARY KEYserá incrementada automaticamente.

Matt Hulse
fonte
12
A ressalva, conforme mencionado por Uku, e também explicado na documentação, é que você precisa passar um NULL para o ID para que isso funcione.
Matt Hulse
22
Você só precisa usar um NULL se omitir a lista de colunas para INSERT - nunca é uma boa prática. Se você especificar as colunas, pode simplesmente deixar de fora a coluna de incremento automático e ela receberá o próximo valor.
Larry Lustig
5
Outra advertência: escreva "INTEGER ..." exatamente como indicado acima. Uma abreviação "INT ..." NÃO funcionará.
Marcin Wojnarski
26

A partir de hoje - junho de 2018


Aqui está o que a documentação oficial do SQLite tem a dizer sobre o assunto (negrito e itálico são meus):

  1. A palavra-chave AUTOINCREMENT impõe CPU extra, memória, espaço em disco e sobrecarga de E / S de disco e deve ser evitada se não for estritamente necessária. Geralmente não é necessário.

  2. No SQLite, uma coluna com o tipo INTEGER PRIMARY KEY é um alias para o ROWID (exceto em tabelas WITHOUT ROWID) que é sempre um inteiro assinado de 64 bits.

  3. Em um INSERT, se a coluna ROWID ou INTEGER PRIMARY KEY não receber um valor explicitamente, ela será preenchida automaticamente com um inteiro não utilizado, geralmente um a mais do que o maior ROWID atualmente em uso. Isso é verdadeiro independentemente de a palavra-chave AUTOINCREMENT ser usada ou não.

  4. Se a palavra-chave AUTOINCREMENT aparecer após INTEGER PRIMARY KEY , isso altera o algoritmo de atribuição automática de ROWID para evitar a reutilização de ROWIDs durante o tempo de vida do banco de dados. Em outras palavras, o objetivo de AUTOINCREMENT é evitar a reutilização de ROWIDs de linhas excluídas anteriormente.


fonte
11

Você leu isso? Como faço para criar um campo AUTOINCREMENT.

INSERT INTO people
VALUES (NULL, "John", "Smith");
Uku Loskit
fonte
O que você está dizendo é que o que estou tentando fazer não é possível, mas posso simular. Preciso usar um nulo no insert?
ewok
1
você não precisa fazer nada, mas sempre inserir NULL como o id, apenas explica como o sqlite faz isso internamente.
Uku Loskit
7
O NULL em INSERT é necessário se você não especificar a lista de colunas para INSERT (nesse caso, você precisa de um número de valores que correspondam exatamente ao número de colunas e deve usar NULL como um espaço reservado). Mas fazer um INSERT sem especificar a lista de colunas nunca é uma boa prática. Se você especificar a lista de colunas, apenas deixe de fora a coluna de incremento automático e o valor NULL e você obterá o resultado esperado.
Larry Lustig
4

Não se deve especificar a AUTOINCREMENTpalavra-chave próxima PRIMARY KEY. Exemplo de criação de chave primária de incremento automático e inserção:

$ 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;

darei:

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

Ao lado de rowid, você pode definir seu próprio campo de incremento automático, mas não é recomendado. É sempre a melhor solução quando usamos o rowid que é aumentado automaticamente.

A AUTOINCREMENTpalavra-chave impõe CPU extra, memória, espaço em disco e sobrecarga de E / S de disco e deve ser evitada se não for estritamente necessária. Geralmente não é necessário.

Leia aqui para obter informações detalhadas.

sonvx
fonte
aparentemente, o rowid nem sempre é aumentado automaticamente, veja o comentário de Nick
rogerdpack,
1
Não é verdade. O incremento automático é melhor em alguns aspectos, já que não reutilizará IDs - um requisito muito importante para muitos sistemas.
O'Rooney
3

SQLite AUTOINCREMENT é uma palavra-chave usada para incrementar automaticamente um valor de um campo na tabela. Podemos incrementar automaticamente um valor de campo usando a palavra-chave AUTOINCREMENT ao criar uma tabela com um nome de coluna específico para incrementá-lo automaticamente.

A palavra-chave AUTOINCREMENT pode ser usada apenas com o campo INTEGER. Sintaxe:

O uso básico da palavra-chave AUTOINCREMENT é o seguinte:

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

Por exemplo, veja abaixo: Considere a tabela COMPANY a ser criada da seguinte forma:

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

Agora, insira os seguintes registros na tabela TB_COMPANY_INFO:

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

Agora selecione o registro

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

Eu sei que esta resposta está um pouco atrasada.
Meu objetivo com esta resposta é para a referência de todos, caso eles encontrem esse tipo de desafio com o SQLite agora ou no futuro e estejam tendo dificuldades com isso.

Agora, olhando para trás em sua consulta, deve ser algo assim.

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

Funciona do meu lado. Igual a,

insira a descrição da imagem aqui

Caso você esteja trabalhando com SQLite, sugiro que você dê uma olhada no DB Browser for SQLite . Funciona em diferentes plataformas também.

Kent Aguilar
fonte
0

O que você faz é correto, mas a sintaxe correta para 'incremento automático' deve ser sem espaço:

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

(Observe também que alterei seus varchars para strings. Isso porque o SQLite transforma internamente um varchar em uma string, então por que se preocupar?)

então sua inserção deve ser, na linguagem SQL o mais padrão possível:

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

embora seja verdade que se você omitir id, ele será automaticamente incrementado e atribuído, eu pessoalmente prefiro não confiar em mecanismos automáticos que podem mudar no futuro.

Uma nota sobre o autoincremento: embora, como muitos apontaram, não seja recomendado pelo pessoal do SQLite, eu não gosto da reutilização automática de ids de registros excluídos se o autoincremento não for usado. Em outras palavras, gosto que o id de um registro excluído nunca mais apareça.

HTH

Luca Nanetti
fonte
A esse respeito, compartilho totalmente o que O'Rooney diz.
Luca Nanetti