2010-02-20 15 views
1

это мой третий вопрос здесь, до сих пор отличные ответы ^^«ключ нарушение» автоинкремент поле в ClientDataSet [Delphi]

Я не имею никаких проблем в просмотре, редактирование данных, но вставка ...

Вот мои сомнения: в финансах/фондовом программное обеспечение у меня есть форма, чтобы создать новый заказ,
естественно мне нужно вставить новую строку в t_orders таблицы
и вставка элементов в t_orderitems таблицы с OrderId поле связано с рядом в t_orders

CREATE TABLE `t_orders` (
    `orderId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `clientId` INT(10) UNSIGNED NOT NULL, 
    ...) 

CREATE TABLE `t_orderitems` (
    `orderitemId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `orderId` INT(10) UNSIGNED NOT NULL, 
    ...) 

--> INDEXES AND FOREIGN KEYS OMITTED <-- 

Как добавить itemorders к сетке и, наконец, кнопка "FinalizeOrder" нажмите

  • Создать заказ в t_orders
  • Включить позиции в t_orderitems 0 связался с этим заказом

Подключение осуществляется с использованием ADO.

Я не уверен, что так можно сделать в таком случае, как я должен это делать?

редактировать: Я попытался с помощью вложенных ClientDataSets и он работает в частях, но я до сих пор не знаю, как получить вставленную Id Order

edit2:
Теперь у меня есть еще одна проблема, я могу Не добавляйте более одного элемента в ClientDataSet.
Поскольку OrderItemId пуст для всех элементов (я могу получить только эти значения при вставке базы данных), когда я пытаюсь добавить второй элемент, он дает мне Key Violation, любые идеи?

Если я установить UpdateMode на что-то другое, чем upWhereKeyOnly и установить pfInKey Ложь это работает, но я не думаю, что это вариант

Любые идеи?

Заранее спасибо!
Arthur.

+0

Wich Database Вы используете? MySQL? – RRUZ

+0

Да, но я изменюсь на PosgreSql в окончательной версии – arthurprs

+1

Проверьте функцию mysql LAST_INSERT_ID(), см. Эту ссылку http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html – RRUZ

ответ

1

Я предполагаю, что у вас есть набор данных ADO, который получает данные из вашей БД и связан с сеткой? Что вам нужно сделать, это промежуточный уровень.

Создайте TClientDataset и подключите его к вашему набору данных ADO, а затем подключите сетку к набору данных клиента. Когда приходит новый заказ, вызовите Append в наборе данных клиента и вставьте в него данные для нового заказа. Это заставит его появиться в сетке. Если вы хотите сохранить свои изменения в БД, вызовите .Update в наборе данных клиента. Он использует набор данных ADO, с которым он связан, чтобы отправлять обновления в БД. Проверьте документацию на TClientDataset для объяснения того, как установить все это; это одна из немногих вещей в последних версиях, которые действительно хорошо документированы.

Чтобы обновить несколько таблиц, просмотрите документацию по отношениям мастера/детали и используйте два набора данных, подобные этому, связанные друг с другом.

+0

Спасибо за ответ. То, что я пытаюсь сделать здесь, рекомендуется? И как мне установить элементы orderId? – arthurprs

+0

Я не уверен. У меня нет опыта с полями AUTO_INCREMENT. –

0

благодаря RRUZ, это не совсем то, что я хотел (я все равно придется вручную установить все OrderItems OrderId кодов вручную перед установкой), но будет делать это

with DataModule1.ADOQuery1 do 
begin 
    SQL.Text := 'SELECT LAST_INSERT_ID()'; 
    Open(); 
    First(); 
    LastInsertId := Fields[0].Value; 
    Close(); 
end; 
1

Если вы сделаете мастер-данные отношения между два набора данных в вашем приложении, ADO может обрабатывать его автоматически. Это означает, что после того, как вы введете новую запись в основной набор данных (заказы), вы можете вставить новые записи в свой набор данных (order_items) без необходимости указывать order_id, потому что order_id для текущей записи в базовом наборе данных будет автоматически извлечен, и вставлен во вновь вставленные записи набора данных.

Чтобы создать связь между вашими наборами данных, если вы используете AdoTable для подробного набора данных, вы можете установить его MasterSource на источник данных, подключенный к вашему базовому набору данных, и определить реляционное взаимодействие между двумя наборами данных с использованием свойства MasterFields. Если вы используете AdoDataset или AdoQuery, вы должны установить свойство DataSource в подробный набор данных на источник данных, подключенный к вашему базовому набору данных. Затем вам нужно добавить предложение WHERE в SQL-инструкцию детализированного набора данных с помощью SQL-paramater с тем же именем, что и ваше ключевое поле в главном наборе данных. В вашем случае это будет что-то вроде этого:

SELECT * FROM t_orderitems WHERE OrderID = :OrderID 

Теперь вы можете установить отношения в MasterFields свойстве вашей детализации данных.

Поскольку ваши заказы могут иметь несколько элементов, вы можете установить LockType на ltBatchOptimistic в наборе данных детали (order_items), чтобы после того, как вы вставляете новый элемент, он не сразу отправляется в базу данных. Использование ltBatchOptimistic означает, что ваши изменения будут сохранены в клиентской памяти временно, пока вы не вызовете метод UpdateBatch. UpdateBatch отправляет все изменения в базу данных.

Если вы хотите отменить заказ, вам необходимо вызвать метод CancelBatch, чтобы отменить изменения, сделанные на подробном наборе данных, и вручную удалить созданную запись заказа в главном наборе данных.

+0

Я сделал это, но когда я не могу добавить несколько ** Items ** в ** Order **, я получаю «нарушение ключа», потому что 2 равно OrderItemId – arthurprs

+0

Если поле определено как AutoInc в вашей таблице, то ваш база данных отвечает за предоставление значения для поля OrderItemID, а не для вас. Вы не должны передавать какое-либо значение для этого поля в свою базу данных. Кстати, как вы вставляете элементы? используете ли методы TDateset (например, Insert, Append) или записываете инструкцию Insert SQL вручную? – vcldeveloper

+0

Я добавляю к ClientDataSet, используя append, и я оставил поле OrderItemId пустым (это проблема, потому что ClientDataSet не разрешает 2 равных ClientOrderId's) – arthurprs

Смежные вопросы