Delphi SQLite вставить в таблицу с первичным ключом как автоинкремент

Я пытаюсь перенести свое приложение с mySQL на SQLite, и для этого я воссоздал все свои таблицы mySQL в SQLite.

Я читал о том, что AUTOINCREMENT не рекомендуется использовать при объявлении фактического поля автоинкремента. И вместо этого я должен просто объявить свое поле автоинкремента как PRIMARY KEY NOT NULL, и SQLite будет автоматически увеличивать его. Все в порядке, кроме того, что он не работает или я не могу его использовать.

Я использую Delphi XE с Zeos и SQLite-3

Вот что я пробовал:

1.

  dm.ZConnection1.Protocol := 'sqlite-3';
  dm.ZConnection1.Database := 'myDB.s3db';
  dm.ZConnection1.Connect;
  dm.ZConnection1.ExecuteDirect('CREATE TABLE IF NOT EXISTS test ('+
  '  id int AUTOINC PRIMARY KEY,'+
  '  myval varchar(200) default NULL);');

  dm.ZConnection1.ExecuteDirect('insert into test (myval) values (''first'')');
  dm.ZConnection1.ExecuteDirect('insert into test (myval) values (''second'')');
  dm.ZConnection1.ExecuteDirect('insert into test (myval) values (''third'')');
  dm.ZConnection1.ExecuteDirect('insert into test (myval) values (''fourth'')');

Если я запустил приведенный выше код, моя таблица будет сгенерирована, но вставленные строки не имеют значений (я думаю, NULL) в поле идентификатора

  1. а затем я попытался заменить AUTOINC на AUTOINCREMENT и получил синтаксическую ошибку при создании таблицы рядом с AUTOINCREMENT, поэтому я предполагаю, что ZEOS не поддерживает объявление AUTOINCREMENT?!?!

  2. А потом я попробовал без AUTOINC, я просто объявил поле ID как

    id int (11) ПЕРВИЧНЫЙ КЛЮЧ,

и мой код не выдает ошибок, за исключением того, что все значения поля ID пусты (автоинкрементация не производилась)

  1. Если я добавляю NOT NULL после PRIMARY KEY, мой код выдает ошибки, потому что я пытаюсь вставить нулевые значения в поле NOT NULL.

Итак, дайте мне знать, что именно я могу сделать для достижения того, что мне нужно, без необходимости вручную вычислять следующее значение идентификатора для каждой вставки. Это вообще возможно?


person user1137313    schedule 18.09.2015    source источник
comment
Я думаю, что вы хотите id INTEGER PRIMARY KEY Отказаться от AUTOINCREMENT обычно рекомендуется (если это действительно не нужно), потому что это предполагает сохранение максимального значения, когда-либо использовавшегося в таблице, что (немного) замедляет работу.   -  person TripeHound    schedule 18.09.2015
comment
По-видимому, мне следовало использовать INTEGER вместо INT при объявлении поля id. Я просто проведу еще несколько тестов и вернусь сюда ...   -  person user1137313    schedule 18.09.2015
comment
SQLite принимает множество вариантов определения поля (чтобы быть максимально несовместимым с другими диалектами SQL), но в большинстве случаев они почти не имеют значения, потому что любое поле может содержать значения любого типа. Одно из немногих исключений состоит в том, что для того, чтобы поле PRIMARY KEY имело желаемое поведение автогенерации, оно должно применяться к INTEGER, а не к любому из его похожих по звучанию вариантов.   -  person TripeHound    schedule 18.09.2015
comment
Да, это была моя проблема. Ключевое слово было неправильным.   -  person user1137313    schedule 18.09.2015


Ответы (1)


В другой части документации говорится:

Столбец PRIMARY KEY становится целочисленным первичным ключом только в том случае, если объявленное имя типа точно "INTEGER". Другие имена целочисленных типов, такие как «INT», «BIGINT», «SHORT INTEGER» или «UNSIGNED INTEGER», заставляют столбец первичного ключа вести себя как обычный столбец таблицы ...

person CL.    schedule 18.09.2015