这是我的第三个问题,到目前为止优秀的回应^^
我在浏览,编辑数据方面没有任何问题,但是插入......
这是我的疑问:
在财务/股票软件中,我有一个表单来创建新订单,
当然我需要在 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 <--
如何将项目订单添加到网格中,最后在“FinalizeOrder”按钮中单击
使用ADO进行连接。
我不确定是否可以这样做,在这种情况下,我该怎么做?
编辑:我尝试使用嵌套的ClientDataSets,它在部分工作,但我仍然不知道如何获取插入的订单ID
EDIT2:
现在我有另一个问题,我不能在ClientDataSet中添加多个项目
因为OrderItemId对于所有项目都是空的(我只能在数据库插入时获得该值),当我尝试添加第二项时,它会给我关键违规,任何想法?
如果我将Updatemode设置为与upWhereKeyOnly不同的东西并将pfInKey设置为False它可以工作,但我不认为这是一个选项
任何想法?
提前致谢!
亚瑟。
答案 0 :(得分:1)
我假设您有一个ADO数据集,它从您的数据库获取数据并链接到网格?你需要做的是一个中间层。
创建TClientDataset并将其连接到ADO数据集,然后将网格连接到客户端数据集。当新订单进入时,在客户端数据集上调用Append并将新订单的数据插入其中。这将使它显示在网格上。如果要将更改保存到数据库,请在客户端数据集上调用.Update。它使用它链接的ADO数据集将更新发送到DB。查看TClientDataset上的文档,了解如何设置全部内容;这是最近版本中为数不多的几件事实际记录得非常好。
要更新多个表,请查看有关主/明细关系的文档,并使用这样的两个数据集,相互链接。
答案 1 :(得分:1)
如果在应用程序中的两个数据集之间建立主 - 详细信息关系,ADO可以自动处理它。这意味着,一旦您将新记录插入主数据集(订单),您就可以在详细数据集(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方法取消对详细数据集执行的修改,并手动删除主数据集中创建的订单记录。
答案 2 :(得分:0)
感谢RRUZ,这不是我想要的(我仍然需要在插入之前手动设置所有orderitem OrderId),但是会这样做
with DataModule1.ADOQuery1 do
begin
SQL.Text := 'SELECT LAST_INSERT_ID()';
Open();
First();
LastInsertId := Fields[0].Value;
Close();
end;
答案 3 :(得分:0)