“密钥违规” ClientDataSet 中的自动增量字段 [Delphi]

发布于 2024-08-22 11:27:09 字数 1199 浏览 9 评论 0原文

这是我的第三个问题,到目前为止,回复很好^^

我在浏览、编辑数据方面没有任何问题,但插入......

这是我的疑问: 在财务/股票软件中,我有一个用于创建新订单的表格,
当然,我需要在 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 中插入

项目 使用 ADO 建立连接。

我不确定是否可以这样做,那么我应该怎么做?

编辑:我尝试使用嵌套的 ClientDataSets,它可以部分工作,但我仍然不知道如何获取插入的订单 ID

edit2:
现在我遇到了另一个问题,我无法将多个项目添加到 ClientDataSet 中。
因为 OrderItemId 对于所有项目都是空的(我只能在数据库插入时获取该值),所以当我尝试添加第二个项目时,它会给我密钥冲突,有什么想法吗??

如果我将 Updatemode 设置为某项与 upWhereKeyOnly 不同并将 pfInKey 设置为 False 它可以工作,但我不认为这是一个选项

有什么想法吗?

提前致谢!
亚瑟.

this is my third question here, so far excellent responses ^^

I'm having no problems in browsing, editing the data, but insertions...

Here is my doubt:
In a finance/stock software i have a form to create a new order,
naturally i need to insert a new row in t_orders table
and insert items in t_orderitems table with orderId field linked to a row in 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 <--

How do i add itemorders to a grid and finally in "FinalizeOrder" button click

  • Create an order in t_orders
  • Insert items in t_orderitems linked to that order

Connection is made using ADO.

I'm not sure if it's possible to do like this, in that case, how i should do?

edit: I tried using nested ClientDataSets and it works in parts, but i still don't know how to get the inserted Order Id

edit2:
Now i have another problem, i can't add more than one item into the ClientDataSet.
Because OrderItemId is empty for all items (i can only get that values upon database insertion), when i attempt to add a second item it gives me Key Violation, any ideas??

If i set Updatemode to something different than upWhereKeyOnly and set pfInKey to False it works but i don't think it's an option

Any ideas?

Thanks in advance!
Arthur.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南巷近海 2024-08-29 11:27:09

我假设您有一个 ADO 数据集,可以从数据库获取数据并链接到网格?你需要做的是一个中间层。

创建一个 TClientDataset 并将其连接到 ADO 数据集,然后将网格连接到客户端数据集。当收到新订单时,对客户端数据集调用 Append 并将新订单的数据插入其中。这将使其显示在网格上。当您想要将更改保存到数据库时,请在客户端数据集上调用.Update。它将使用链接到的 ADO 数据集将更新发送到数据库。查看 TClientDataset 上的文档,了解如何设置这一切的说明;这是最近版本中为数不多的真正有很好记录的内容之一。

要更新多个表,请查看有关主/详细信息关系的文档,并使用两个像这样相互链接的数据集。

I assume that you have an ADO dataset that gets data from your DB and is linked to the grid? What you need to do this is an intermediate layer.

Create a TClientDataset and connect it to your ADO dataset, then connect the grid to the client dataset. When a new order comes in, call Append on the client dataset and insert the data for the new order into it. This will make it show up on the grid. When you want to save your changes to the DB, call .Update on the client dataset. It'l use the ADO dataset it's linked to to send the updates to the DB. Check the documentation on TClientDataset for explanations on how to set this all up; it's one of the few things in recent versions that's actually documented really well.

To update multiple tables, look at the documentation on master/detail relations and use two datasets like this, linked to each other.

心意如水 2024-08-29 11:27:09

如果您在应用程序中的两个数据集之间建立主从关系,ADO 可以自动处理它。这意味着,一旦您向主数据集(orders)插入新记录,您就可以在详细数据集(order_items)中插入新记录,而无需指定 order_id,因为主数据集中当前记录的 order_id 将被自动检索,并且插入新插入的详细信息数据集记录中。

要在数据集之间建立主/详细关系,如果您使用 AdoTable 作为详细数据集,则可以将其 MasterSource 设置为连接到主数据集的数据源,并使用 MasterFields 属性定义两个数据集之间的关系。
如果您使用 AdoDataset 或 AdoQuery,则应将详细数据集中的 DataSource 属性设置为连接到主数据集的数据源。然后,您必须使用与主数据集中的关键字段同名的 SQL 参数在详细数据集的 SQL 语句中添加 WHERE 子句。在您的情况下,它会是这样的:

SELECT * FROM t_orderitems WHERE OrderID = :OrderID

现在您可以在详细数据集的 MasterFields 属性中设置关系。

由于您的订单可以有多个商品,因此您可以在详细数据集 (order_items) 中将 LockType 设置为 ltBatchOptimistic,这样一旦插入新商品,就不会立即将其发送到数据库。使用 ltBatchOptimistic 意味着您的更改将暂时保存在客户端内存中,直到您调用 UpdateBatch 方法。 UpdateBatch 将所有更改发送到数据库。

如果要取消订单,则必须调用 CancelBatch 方法取消对明细数据集的修改,并手动删除主数据集中已创建的订单记录。

If you make a master-details relationship between the two datasets in your application, ADO can handle it automatically. That means, once you insert a new record into master dataset (orders), you can insert new records in your details dataset (order_items) without the need to specify order_id, because order_id for the current record in master dataset will be automatically retrieved, and inserted in the newly inserted records of details dataset.

To make a master/details relationship between your datasets, if you are using AdoTable for detail dataset, you can set its MasterSource to a datasource connected to your master dataset, and define relatinship between the two datasets using MasterFields property.
If you are using AdoDataset or AdoQuery, you should set DataSource property in detail dataset to a datasource connected to your master dataset. Then you have to add a WHERE clause in your detail dataset's SQL statement using a SQL paramater with the same name as your key field in the master dataset. In your case it would be something like this:

SELECT * FROM t_orderitems WHERE OrderID = :OrderID

Now you can set your relationship in MasterFields property of your detail dataset.

Since your orders can have multiple items, you can set LockType to ltBatchOptimistic in the detail dataset (order_items), so that once you insert a new item, it is not sent to database immediately. Using ltBatchOptimistic means your changes will be saved in client memory temporally until you call UpdateBatch method. UpdateBatch sends all the changes to the database.

If you want to cancel the order, you have to call CancelBatch method to cancel modifications done on detail dataset, and delete the created order record in master dataset manually.

雨落□心尘 2024-08-29 11:27:09

谢谢 RRUZ,这并不完全是我想要的(我仍然必须在插入之前手动设置所有 orderitems OrderId),但会这样做

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

thanks RRUZ, this isn't exactly what i wanted (i still have to manually set all orderitems OrderId's manually before insertion), but will do it

with DataModule1.ADOQuery1 do
begin
  SQL.Text := 'SELECT LAST_INSERT_ID()';
  Open();
  First();
  LastInsertId := Fields[0].Value;
  Close();
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文