Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Autoincrement не работает в dbExpress
 
 автор: Wyfinger   (09.05.2007 в 02:28)   письмо автору
 
 

Добрый день.

Есть таблица, первое поле которой: ID - auto_increment, подключаюсь к базе через dbExpress из Delphi 7 (TSimpleDataSet буферизирует данные и обеспечивает двунаправленный курсор).

Пытаюсь добавить новую запись:

data_one.Insert;
data_one.FieldByName('str_field').AsString := 'C:\test.exe';
data_one.FieldByName('int_field').AsInteger := 15550;
data_one.Post;

Однако при попытке внести изменения (Post) выскакивает ошибка "Field 'ID' must have a value", но ведь это SQL сервер должен назначать новое значение автоинкремент поля.

Что делать?

   
 
 автор: Trianon   (09.05.2007 в 11:44)   письмо автору
 
   для: Wyfinger   (09.05.2007 в 02:28)
 

А ID - точно AUTO_INCREMENT?
И вообще - это разве MySQL-база?

   
 
 автор: Wyfinger   (09.05.2007 в 13:41)   письмо автору
 
   для: Trianon   (09.05.2007 в 11:44)
 

Ну да, MySQL база, версия MySQL сервера: 4.0.15-nt, подключаюсь через технологию dbExpress из Delphi версии 7 (в седьмой версии Delphi компонент TSimpleDataSet сильно отличается от своего аналога из Delphi 6 - TSQLClientDataSet).

Посмотрите скриншот из атачмента.

Я уже согласен и сам устанавливать значение, но как его выбрать, чтобы целостность базы не нарушилась?, я же не буду делать отдельный запрс, чтобы выяснить какого значения еще не было при каждом добавлении - это слишком долго. А если запоминать последнее значение в другой таблице - это тоже вариант, но неправильно это.

   
 
 автор: cheops   (09.05.2007 в 13:46)   письмо автору
 
   для: Wyfinger   (09.05.2007 в 02:28)
 

Приведите структуру базы данных (можно получить операторо SHOW CREATE TABLE)?

   
 
 автор: Wyfinger   (10.05.2007 в 00:16)   письмо автору
 
   для: cheops   (09.05.2007 в 13:46)
 

База данных состоит из одной таблицы, как видно из рисунка, приложенного в моем последнем сообщении.
Таблица - files, состоит из столбцов:
ID - INT AUTOINCREMENT
sccess_time - DateTime
file_name - VARCHAR(255)
file_path - BLOB
file_size - BIGINT

кроме PRYMIRY KEY, по столбцу ID других индексов нет.

   
 
 автор: Wyfinger   (10.05.2007 в 06:25)   письмо автору
 
   для: Wyfinger   (09.05.2007 в 02:28)
 

Пробовал создать другую таблицу, в конце объявления добавил:

AUTO_INCREMENT=62865


Честно говоря - не знаю что эта опция делает, но с ней, да и вообще с другими таблицами, другими базами (я уж подумал может есть зависимость с типом таблиц), но нет, все-равно автоинкремент поле не заполняется.

Кстати в InterBase вообще нет автоинкремента, вместо этого там используется механизм т.н. Генераторов, представляющих собой что-то вроде StoredProc, и вешающихся как триггер. Можно такое сделать и в MySQL, но мне такое решение кажется "корявым".

   
 
 автор: cheops   (10.05.2007 в 12:58)   письмо автору
 
   для: Wyfinger   (10.05.2007 в 06:25)
 

Хм... может драйвер dbExpress для MySQL глючит... попробуйте более свежую версию установить. А в обход программы запрос
INSERT INTO files VALUES(NULL, NOW(), "", "", "");

выполняется? Например в консольном клиенте mysql? Вообще механизм AUTO_INCREMENT обычно работает как часы, в том числе и через dbExpress (я правда, предпочитаю пользоваться SQL-запросом).
Вот ещё, что, попробуйте выполнить также запрос (т.е. заменить NULL на 0)
INSERT INTO files VALUES(0, NOW(), "", "", "");

Он выполняется?

PS Хранимые процедуры и триггеры появились в MySQL в более поздних версиях, нужно 5 версию ставить (это скорее всего точно потребует обновления драйвера dbExpress для MySQL).
PPS Параметр таблицы AUTO_INCREMENT позволяет установить счётчику значение, начиная с которого будут присваиваться уникальные значения.

   
 
 автор: Wyfinger   (10.05.2007 в 16:36)   письмо автору
 
   для: cheops   (10.05.2007 в 12:58)
 

Значит так, SQL запрос вида "INSERT INTO files VALUES(NULL, NOW(), "", "", "");", выполненный из компонента TSQLQuery работает нормально, значит будет работать и из консоли и из PHP.

Похоже ошибка в реализации интерфейса подключения к MySQL, конкретно в реализации процедур добавления записей в TSimpleDataSet. Там же операции добавленя/удаления/изменения, если не пакетные, реализуются не с помощью SQL, а с помощью прямых обращений к серверу (для MySQL - libmySQL.dll), так вот, похоже эта ошибка появилась из-за несовместимой (частично) библиотеки подключения к MySQL.

В любом случае, вариант с добавлением через SQL запрос мне кажется слишком нерациональным - мне нужно за один раз добавлять около 150 тыс. записей.

Есть трансляция MySQL Client API для Delphi, может с ее помощю удастся что-то найти.

PS Хранимые процедуры и триггеры появились в MySQL в более поздних версиях, нужно 5 версию ставить (это скорее всего точно потребует обновления драйвера dbExpress для MySQL).

> Я все больше разочаровываюсь в MySQL - мне всего-то и нужно-то база данных, способная работать с рег. выражениями и к которой можно подключиться и из Delphi и из PHP.

PPS Параметр таблицы AUTO_INCREMENT позволяет установить счётчику значение, начиная с которого будут присваиваться уникальные значения.

> Понятно, спасибо.

   
 
 автор: cheops   (10.05.2007 в 16:56)   письмо автору
 
   для: Wyfinger   (10.05.2007 в 16:36)
 

Драйвер для MySQL в dbExpress - штука достаточно кривая - там ещё много тараканов встретите, особенно при выборке (у меня например, в случае много табличного запроса за раз можно было только 6 полей вытащить). У вас какие версии Delphi и dbExpress?

>В любом случае, вариант с добавлением через SQL запрос мне кажется слишком
>нерациональным - мне нужно за один раз добавлять около 150 тыс. записей.
1) У вас внешний MySQL-сервер? Может проще сформировать временный файл с многострочным INSERT-запросом и выпонить его внешней утилитой mysql, запустив через exec()? (Утилита mysql выполняет дампы очень быстро - правда формирование файла может занимать время).
2) Скорее всего dbExpress всё равно его в SQL-запрос преобразует - вряд ли оперирует протоколом MySQL.
3) Тут удобно воспользоваться было бы многострочным запросом, однако следует учитывать, что следует выставить соответствующий объём для запроса при помощи системной переменной max_allowed_packet, иначе очень объёмный запрос будет отвергнут.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования