在李维的<<Delphi5.x ADO/MTS/COM+>>一书中,提到了“处理多个数据表Join的数据”,根据书中的介绍,我做了如下的测试:数据库:oracle9i表A:客户信息表
字段:CustNo,CustName,CustTypeNo表B:客户类别表
字段:CustTypeNo,CustTypeName表A和表B通过CustTypeNo关联。现在做一个对表A:客户信息表的添加操作,其中TADOQuery设为了BatchUpdate模式,对于数据的输入都采用DbEdit控件:1.首先打开表A: with ADOQuery do
begin
close
sql.text := 'SELECT A.CustNo,A.CustName,A.CustTypeNo,B.CustTypeName '+
'FROM A LEFT JOIN B ON A.CustTypeNo=B.CustTypeNo '+
'ORDER BY A.CustNo ';
open;
end;2.添加一条记录 ADOQuery.append;
ADOQuery.fieldbyname('CustNo').asstring := '1001';
ADOQuery.fieldbyname('CustTypeName').asstring := '测试客户';
ADOQuery.fieldbyname('CustTypeNo').asstring := '01';
ADOQuery.fieldbyname('CustTypeName').asstring := '海外客户'; 3.保存记录 ADOQuery.UpdateBatch; 出现的问题如下:保存记录是提示错误“Ora-00904:CustTypeName无效的标示符”,我想,ADOQuery.UpdateBatch方法执行后,最后自动生成的SQL语句,可能把CustTypeName字段作为了表A:客户信息表的字段了。可是从李维的书里了解到,ADO比BDE先进的一个地方就是在多表联接时的数据更新,能够自动为每个表生成相应的SQL语句。
其实,对于ADOQuery.fieldbyname('CustTypeName').asstring := '海外客户'这一句的作用,主要是为了在DBGrid中适时的显示CustTypeNo所对应的CustTypeName值,相信大家也经常这样用。
注:不想采用TDBNavigator控件 恳请有经验的兄弟帮忙看看。
字段:CustNo,CustName,CustTypeNo表B:客户类别表
字段:CustTypeNo,CustTypeName表A和表B通过CustTypeNo关联。现在做一个对表A:客户信息表的添加操作,其中TADOQuery设为了BatchUpdate模式,对于数据的输入都采用DbEdit控件:1.首先打开表A: with ADOQuery do
begin
close
sql.text := 'SELECT A.CustNo,A.CustName,A.CustTypeNo,B.CustTypeName '+
'FROM A LEFT JOIN B ON A.CustTypeNo=B.CustTypeNo '+
'ORDER BY A.CustNo ';
open;
end;2.添加一条记录 ADOQuery.append;
ADOQuery.fieldbyname('CustNo').asstring := '1001';
ADOQuery.fieldbyname('CustTypeName').asstring := '测试客户';
ADOQuery.fieldbyname('CustTypeNo').asstring := '01';
ADOQuery.fieldbyname('CustTypeName').asstring := '海外客户'; 3.保存记录 ADOQuery.UpdateBatch; 出现的问题如下:保存记录是提示错误“Ora-00904:CustTypeName无效的标示符”,我想,ADOQuery.UpdateBatch方法执行后,最后自动生成的SQL语句,可能把CustTypeName字段作为了表A:客户信息表的字段了。可是从李维的书里了解到,ADO比BDE先进的一个地方就是在多表联接时的数据更新,能够自动为每个表生成相应的SQL语句。
其实,对于ADOQuery.fieldbyname('CustTypeName').asstring := '海外客户'这一句的作用,主要是为了在DBGrid中适时的显示CustTypeNo所对应的CustTypeName值,相信大家也经常这样用。
注:不想采用TDBNavigator控件 恳请有经验的兄弟帮忙看看。
FROM A, B
WHERE A.CustTypeNo=B.CustTypeNo(+)
ORDER BY A.CustNo意思是:如果在B表中没有找到B.CustTypeNo、B.CustTypeName字段自動补空
结果我把 ADOQuery换了一个新的,名字用原来的就可以,我也觉得很怪!~
我觉得你这种操作,最好在SQL server的查询分析器中建一个视图来操作
感谢各位的答复,我的代码都是经过调试的,我可以向大家保证。大家的回复大多都把注意力放在了Sql语句上了,而我的主要问题还是关于Delphi中ADO处理多表联结时,更新主表的问题。
ADOQuery.fieldbyname('CustNo').asstring := '1001';
ADOQuery.fieldbyname('CustTypeName').asstring := '测试客户';
//――――按NI自己的SQL文、↑此処的字段名応該是CustName吧?
{...}
我一时疏忽写错了,应该是:
ADOQuery.fieldbyname('CustName').asstring := '测试客户'; 不过这不是造成最终不能添加记录的的原因!!!
其实,如果大家有空,可以自己找个多表联结,写代码试试,我相信只要在机子上亲自调试一下,很多问题都会凸现出来。
当ADOQuery.append時、只対B表中的CustTypeName追加記録、
1.若CustTypeNo文段是B表中的PrimaryKey、会出錯。
2.按你的録入方法在B表中的CustTypeNo文段一定NULL,
那你上述的SQL文B.CustTypeName也会是NULL。二)還有你可以建一個View、在Oracle環境下、検証你的SQL文是否可行。CREATE VIEW yourView_Name AS
SELECT A.CustNo,A.CustName,A.CustTypeNo,B.CustTypeName
FROM A LEFT JOIN B ON A.CustTypeNo=B.CustTypeNo
ORDER BY A.CustNoINSERT INTO yourView_Name
VALUES ('1001', '测试客户', '01', '海外客户');
実際解決問題、有時是不看技术上有没有意义的、hehe~~~
B表并不是A表的从表呀、A表是做修改,删除、并不影響B表!
厳格的説:B表是MASTER、A表是INFORMATION。
建議你看看主从表方面的書...
你不会以为我连“主从表”的概念的都不懂吧^-^,我之所以用“主表更新”这个词语,主要还是想说明白我只想更新多表连接中某一单表。不过这个问题我已经解决了,自己写一个适用于ADO的TADOUpdateSql控件,适用于任何多表查询,单表更新问题。再次感谢你的热心参与回复。
什麽时侯公开呀? 很想拜读!