Autoinkrementacja w SQLite?

Autoinkrementacja w SQLite?
soob
  • Rejestracja:ponad 15 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Kielce
  • Postów:59
0

Witam,
Próbuję w SQLite użyć AUTOINCREMENT, ale ciągle wywala mi błąd i nie wiem za bardzo jaka jest przyczyna.

Kopiuj
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteBaza := nil;
  _PATH := ExtractFilePath(Application.ExeName);
  if not FileExists(_PATH + 'baza.dat') then
  begin
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat');
    SQLIteBaza.ExecSQL('CREATE TABLE test (ID INTEGER PRIMARY KEY AUTOINCREMENT, wykonawca STRING, album STRING, rok VAR, gatunek STRING)');
  end
  else
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat');
end;   

Później mam taką procedurę, którą wykonuję w OnClicku buttona

Kopiuj
procedure TMainForm.AddToDatabase;
Begin
  SQLiteBaza.ExecSQL('INSERT INTO test VALUES("'
  + ArtistEdit.Text + '", "'
  + AlbumEdit.Text + '", "'
  + YearEdit.Text + '", "'
  + GenreBox.Text + '", "'
  + '")');
end;

Wszystko ładnie się zapisuje tylko, że chciałbym, żeby automatycznie uzupełniało mi kolumnę ID. Próbowałem też wpisywać nazwy kolumn po nazwie tabeli, ale wtedy pokazuje, że jest za mało kolumn. To pewnie jakiś prosty problem, ale może ktoś będzie chętny :)

Dodam, że tu w dokumentacji SQLite napisano, że automatycznie powinno dodawać wartość, ale u mnie tego nie robi dlatego chciałem spróbować z AUTOINCREMENT

edytowany 1x, ostatnio: soob
LA
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 11 godzin
  • Postów:471
0

wywal AUTOINCREMENT z deklaracji tabeli

Sensacyjny Sebastian
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 7 godzin
  • Postów:387
0

Jeżeli używasz INSERT INTO nazwa_tabeli VALUES, wtedy musisz podać wartości dla wszystkich kolumn. Musisz użyć INSERT INTO nazwa_tabeli (kolumna1, kolumna2) VALUES.

Poza tym - sprawdź, jaką wiadomość błędu dostajesz od SQLite.

soob
  • Rejestracja:ponad 15 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Kielce
  • Postów:59
0
lampasss napisał(a):

wywal AUTOINCREMENT z deklaracji tabeli

Tak zrobiłem na początku. Nie działa.

Sensacyjny Sebastian napisał(a):

Jeżeli używasz INSERT INTO nazwa_tabeli VALUES, wtedy musisz podać wartości dla wszystkich kolumn. Musisz użyć INSERT INTO nazwa_tabeli (kolumna1, kolumna2) VALUES.

Poza tym - sprawdź, jaką wiadomość błędu dostajesz od SQLite.

No ale właśnie chodzi o to, że nie chcę dodawać 1 kolumny. Chcę żeby automatycznie ją numerowało.

screenshot-20191024193610.png

Te bład pojawia się, gdy mam SQLiteBaza.ExecSQL('INSERT INTO tabela (wykonawca, album, rok, gatunek) VALUES("' . Jak usune nazwy kolumn i AUTOINCREMENT to zapisze się wszsytko ładnie jak chcę tylko, że ID nie numeruje się automatycznie, a na tym mi zależy.

Sensacyjny Sebastian
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 7 godzin
  • Postów:387
1

Przeczytałeś w ogóle tę wiadomość o błędzie?

5 values for 4 columns

Podajesz 4 nazwy kolumn, do których chcesz wstawić wartości, po czym podajesz krotkę z pięcioma wartościami:

  • a
  • a
  • 1
  • ambient
soob
Ok. Masz rację. Niezauważyłem tej ostatniej wartości, bo jeszcze niedawno coś tam było. Mój błąd, przeprszam. W tej chwili działa też autoinkrementacja więc wszystko ok :) Dziękuję
_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:20 dni
0

podaj zamiast Id -> null lub podaj jakie kolumny podajesz w values.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
cerrato
Moderator Kariera
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:Poznań
  • Postów:8807
1

Wprawdzie problem został rozwiązany, ale ja wkleję tutaj fragment z dokumentacji SQLite dotyczący AUTOINCREMENT w kontekście PRIMARY KEY. Pewnie nie każdy się tym interesował, a zrozumienie jak to działa w SQLite może się przydać w przyszłości :)

  • The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
  • In SQLite, a column with type INTEGER PRIMARY KEY is an alias for the ROWID (except in WITHOUT ROWID tables) which is always a 64-bit signed integer.
  • On an INSERT, if the ROWID or INTEGER PRIMARY KEY column is not explicitly given a value, then it will be filled automatically with an unused integer, usually one more than the largest ROWID currently in use. This is true regardless of whether or not the AUTOINCREMENT keyword is used.
  • If the AUTOINCREMENT keyword appears after INTEGER PRIMARY KEY, that changes the automatic ROWID assignment algorithm to prevent the reuse of ROWIDs over the lifetime of the database. In other words, the purpose of AUTOINCREMENT is to prevent the reuse of ROWIDs from previously deleted rows.

Więcej konkretów dla zainteresowanych - https://www.sqlite.org/autoinc.html
oraz
https://www.sqlite.org/lang_createtable.html#rowid


_13th_Dragon
Dokumentacja, zawsze wymiata wszelkie wątpliwości.
cerrato
Pod warunkiem, że jest dobrze napisana. Bo czasami to więcej zamieszania wprowadza, niż jest z niej pożytku ;)
_13th_Dragon
Czy cytowałbyś taką dokumentację? No właśnie! Takim tekstem: - "Dokumentacja, zawsze wymiata ... wszelkie wątpliwości" - poprzedzam cytowanie dokumentacji, owszem chodzi o cytowanie tej wartej cytowania, zaś tamtych oczywiście nie cytuję ;D
cerrato
Chodziło mi o to, że często dokumentacja jest super, ale czasami mam wrażenie, że ktoś pisał ją za karę. Stworzył fajną bibliotekę, ale że trzeba jakieś docs'y do tego zrobić. to siada i pisze na odpieprz, żeby tylko cokolwiek było. Niestety, o ile pamiętam, to część dokumentacji do PHP jest napisana mniej-więcej w takim właśnie stylu.
_13th_Dragon
Tu masz racje czasami są na odwal się, ale takiej dokumentacji być nie cytował, racja? Z drugiej strony prowadzę całkiem poważny projekt, zaś pisać dokumentacje kazałem testerom, użytkownikom tego szajsu nie udostępniam, tylko sam czytam, i jak testerzy zaczynają plątać się w zeznaniach - to poważny sygnał że w tym miejscu zrobiono nieintuitywne, więc zwyczajnie trza przerobić.
cerrato
zdradzisz, co to za projekt prowadzisz? Czy to jest TOP SECRET?
_13th_Dragon
Chyba nie, ale ponieważ jestem tak jak by na zleceniach to bez specjalnej zgody firmy raczej nie powinienem o tym gadać.
cerrato
Czyli to jest projekt wewnętrzny/pisany na zlecenie - tak? Myślałem, że chodzi o coś OSS, ogólnie dostępnego online. Jeśli to projekt komercyjny, to nie było tematu.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.