Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql ADO可更新查询-其中一个联接表没有记录时出错_Sql_Delphi_Ado_Jet - Fatal编程技术网

Sql ADO可更新查询-其中一个联接表没有记录时出错

Sql ADO可更新查询-其中一个联接表没有记录时出错,sql,delphi,ado,jet,Sql,Delphi,Ado,Jet,我使用ADO的“可更新查询”功能,能够从多个表和条件中选择数据集,并将其显示在网格或其他用户界面中,供用户浏览和编辑 然而,我很惊讶我以前没有遇到过这个问题,当一个连接的表没有(主)键的记录,并且用户试图编辑该表中的一个字段时,ADO在post上给出了著名的“Row not locate..”错误 据我所知,这个错误是ADO驱动程序试图找到记录来更新它的字段——当然,在这个例子中,没有记录可以找到。在这些情况下,我所期望的是ADO驱动程序将为主表发出等效的更新查询,但为子表发出插入查询 还有其他

我使用ADO的“可更新查询”功能,能够从多个表和条件中选择数据集,并将其显示在网格或其他用户界面中,供用户浏览和编辑

然而,我很惊讶我以前没有遇到过这个问题,当一个连接的表没有(主)键的记录,并且用户试图编辑该表中的一个字段时,ADO在post上给出了著名的“Row not locate..”错误

据我所知,这个错误是ADO驱动程序试图找到记录来更新它的字段——当然,在这个例子中,没有记录可以找到。在这些情况下,我所期望的是ADO驱动程序将为主表发出等效的更新查询,但为子表发出插入查询

还有其他人遇到过这个问题并找到了解决办法吗

使用的ADO驱动程序是连接Access(mdb)数据库的Jet 4.0 OLE DB提供程序

我已确保两个表的主键字段在查询数据集中可用,供驱动程序使用

以下是我使用的SQL的基本版本:

SELECT 
    Table1.CustomerNo, Table1.Field1, Table1.Fieldn,  
    Table2.CustomerNo, Table2.Field1, Table2.Fieldn  
FROM 
    Table1 
LEFT JOIN Table2 
    ON Table1.CustomerNo = Table2.CustomerNo  
WHERE 
    Table1.CustomerNo = Newcode;

作为一个实验,我在MS Access 2007中尝试了同样的方法,并且成功了,因此ADO中可能有一个解决方案(但是Access可能使用了不同的驱动程序)。

最后,我选择了“黑客”解决方案。2个表上的可更新ADO查询只有在 两个表中都存在客户的REOCRD。因此,我必须进行检查,如果表2中缺少相关记录,则必须在调用主查询之前先插入它。代码如下:

   //Query customer account - open query from Table1 and Table2 tables                     
   TwoTableQuery.Close;
   //
   //SELECT Table2.CustomerNo
   // FROM Table2
   //WHERE (Table2.CustomerNo = CustomerCode);
   Table2Query.Close;
   Table2Query.Parameters[0].Value := CustomerCode;
   Table2Query.Open;                                /
   //does the Table2 record exist for this customer?
   if Table2Query.RecordCount = 0 then
   begin   //no, so create a new record
      Table2Query.Insert;
      Table2Query.FieldByName('CustomerNo').AsString := CustomerCode;
      Table2Query.Post;
      Table2Query.Close;
   end;
   //okay, now okay to open main query
   TwoTableQuery.Parameters[0].Value := CustomerCode;
   TwoTableQuery.Open;                                 


它效率不高,还创建了可能不需要的记录(见表2)。但这似乎是唯一的解决方案。

最后,我选择了“黑客”解决方案。2个表上的可更新ADO查询只有在 两个表中都存在客户的REOCRD。因此,我必须进行检查,如果表2中缺少相关记录,则必须在调用主查询之前先插入它。代码如下:

   //Query customer account - open query from Table1 and Table2 tables                     
   TwoTableQuery.Close;
   //
   //SELECT Table2.CustomerNo
   // FROM Table2
   //WHERE (Table2.CustomerNo = CustomerCode);
   Table2Query.Close;
   Table2Query.Parameters[0].Value := CustomerCode;
   Table2Query.Open;                                /
   //does the Table2 record exist for this customer?
   if Table2Query.RecordCount = 0 then
   begin   //no, so create a new record
      Table2Query.Insert;
      Table2Query.FieldByName('CustomerNo').AsString := CustomerCode;
      Table2Query.Post;
      Table2Query.Close;
   end;
   //okay, now okay to open main query
   TwoTableQuery.Parameters[0].Value := CustomerCode;
   TwoTableQuery.Open;                                 


它效率不高,还创建了可能不需要的记录(见表2)。但这似乎是唯一的解决方案。

首先尝试使用locate函数,以确保两个字段都存在。使参数等于字段(如果已找到),布尔值为true,否则将使用另一个字段的值更新或插入新字段。在知道条目存在之后,您可以加入字段…或者您可以使用try except finally首先尝试并执行语句,除非未找到字段,然后最终创建新条目。将所有这些放在repeat-until中,并确保until语句在两个表上都使用locate来查看是否找到了它。

首先尝试locate函数以确保两个字段都在那里。使参数等于字段(如果已找到),布尔值为true,否则将使用另一个字段的值更新或插入新字段。在知道条目存在之后,您可以加入字段…或者您可以使用try except finally首先尝试并执行语句,除非未找到字段,然后最终创建新条目。将所有这些放在repeat-until中,并确保until语句在两个表上都使用locate来查看是否找到了它。

如果您的表是客户和订单,那么驱动程序以静默方式创建订单行是没有意义的,是吗?如果您将连接更改为内部连接,则不存在的行错误应该会消失,但经过必要的修改后,您将只有一组有订单的客户。两个表之间是否存在
外键
(“强制引用完整性关系”)?当您“尝试相同的事情”时“在Access中,您使用了相同的表和相同的查询吗?@Tim:谢谢您的回复;顺便说一下,这些表格是一对一的,所以你的建议更有效,但是你能提供更多的细节吗?当数据集进入编辑模式时,我是否应该检查第二个表是否有记录,如果没有,请插入一条记录,然后关闭并重新打开查询?@onedaywhen:两个表之间没有强制关系,是的,我使用了相同的表和相同的查询(我很懒..)。我必须承认我对MS Access产品的评价不高,但这给我留下了深刻的印象。使用相同的表和查询是正确的做法。出于兴趣,请尝试在编辑前后将记录集保存为XML。从逻辑上讲,更新是删除和插入。但是,记录集也可以标记为要更新。因此,记录集不会对逻辑上等价的操作进行相同的处理。因为您没有FK,我想知道您是否可以利用它。如果您的表是客户和订单,比如说,驱动程序以静默方式创建订单行是没有意义的,是吗?如果您将连接更改为内部连接,则不存在的行错误应该会消失,但经过必要的修改后,您将只有一组有订单的客户。两个表之间是否存在
外键
(“强制引用完整性关系”)?当您“尝试相同的事情”时“在Access中,您使用了相同的表和相同的查询吗?@Tim:谢谢您的回复;顺便说一下,这些表格是一对一的,所以你的建议更有效,但是你能提供更多的细节吗?当数据集进入编辑模式时,我是否应该检查第二个表是否有记录,如果没有,请插入一条记录,然后关闭并重新打开查询?@onedaywhen:两个表之间没有强制关系,是的,我使用了相同的表和相同的查询(我很懒..)。我必须承认我对MS Access产品的评价不高,但这给我留下了深刻的印象。使用相同的表和查询是正确的做法。出于兴趣,请尝试在编辑前后将记录集保存为XML。从逻辑上讲,更新是删除和插入。但是,记录集可以是