Delphi SQL MS-Access 中的子选择错误
Delphi SQL subselect error in MS-Access
我正在使用带有 ADO 组件的 Delphi 7 和 MS Access 2003。SQL 句子
SELECT CMCB.Name,
(SELECT SUM(amount) FROM movement MCB
WHERE MCB.movement_classification_id=CMCB.movement_classification_id
AND MCB.operation_date >= #01/01/2013#
AND MCB.operation_date < #01/01/2014#
) AS MyYear
FROM movement_classification CMCB
在 MS Access 控制台中工作正常,但通过 Delphi 应用程序在我打开数据集时启动以下错误 (TADOQuery):
数据提供商或其他服务返回了 E_FAIL 状态
知道为什么会这样吗?是否与ADO组件相关(本例为TADOQuery)
我从数据库 dbdemos.mdb(程序 Files\Common Files\Borland Shared\Data 中尝试了类似的查询并且有效
SELECT CustNo,
(SELECT SUM(AmountPaid) FROM orders O
WHERE O.CustNo = C.CustNo
AND O.SaleDate >= #01/01/1994#
AND O.SaleDate < #01/01/1995#
) AS AmountPaid
FROM customer C
我在Delphi中使用的代码如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOConnection1.Connected := False;
ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\Xiber\Delphi\Whosebug\Subquerys\dbdemos.mdb';
ADOConnection1.Connected := True;
ADOQuery1.SQL.Text := 'SELECT CustNo, (SELECT SUM(AmountPaid) FROM orders O WHERE O.CustNo = C.CustNo AND O.SaleDate >= #01/01/1994# AND O.SaleDate < #01/01/1995#) AS AmountPaid FROM customer C';
ADOQuery1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
sSQL: string;
begin
ADOConnection1.Connected := False;
ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\Xiber\Delphi\Whosebug\Subquerys\XiGest-CASA.mdb';
ADOConnection1.Connected := True;
sSQL := ' SELECT CMCB.Name, ' +
' (SELECT SUM(amount) FROM movement MCB ' +
' WHERE MCB.movement_classification_id=CMCB.movement_classification_id ' +
' AND MCB.operation_date >= #01/01/2013# ' +
' AND MCB.operation_date < #01/01/2014# ' +
' ) AS MyYear ' +
' FROM movement_classification CMCB ';
ADOQuery1.SQL.Text := sSQL;
ADOQuery1.Open;
end;
按照目前的情况,您的查询应该 return 每行员工的 sum(qty) 值相同。如果 Access 是 "hiding" 两个 table 之间的关系,那就可以解释为什么它在 Access 中有效。
我希望查询类似于:
select e.name, sum(i.qty)
from
employee e,
items i
where
i.employeeid = e.employeeid
会更像您所追求的。当然,这假设两个table之间存在直接关系(项目table中employeeid的外键),这不太现实。
正如其他人评论的那样,更多的信息将允许更准确的答案!
您是否有任何原因无法简化查询(假设它是 ADO 错误),例如:
select CMCB.Name, SUM(MCB.amount)
from
movement_classification CMCB,
movement MCB
where
MCB.movement_classification_id=CMCB.movement_classification_id
AND MCB.operation_date >= #01/01/2013#
AND MCB.operation_date < #01/01/2014#
最后我意识到两个总和之间的区别是在 dbdemos 中字段 AmountPaid.mdb 是 double 而在我的例子中是 decimal(8 ,2)。
这似乎是一个 ADO 错误。可以自己复现。
因此,如果您更改 dbdemos.mdb 中的字段 AmountPaid(由 Borland 提供,您可以在程序 Files\Common Files\Borland Shared\Data) 到 decimal(8,2) 并通过 Delphi 7 执行查询(使用 ADOConnection 和 ADOQuery ), 你会得到上面提到的错误。
SELECT CustNo,
(SELECT SUM(AmountPaid) FROM orders O
WHERE O.CustNo = C.CustNo
AND O.SaleDate >= #01/01/1994#
AND O.SaleDate < #01/01/1995#
) AS AmountPaid
FROM customer C
但是如果你在 MS Access 中执行这个查询,它工作正常。
我正在使用带有 ADO 组件的 Delphi 7 和 MS Access 2003。SQL 句子
SELECT CMCB.Name,
(SELECT SUM(amount) FROM movement MCB
WHERE MCB.movement_classification_id=CMCB.movement_classification_id
AND MCB.operation_date >= #01/01/2013#
AND MCB.operation_date < #01/01/2014#
) AS MyYear
FROM movement_classification CMCB
在 MS Access 控制台中工作正常,但通过 Delphi 应用程序在我打开数据集时启动以下错误 (TADOQuery):
数据提供商或其他服务返回了 E_FAIL 状态
知道为什么会这样吗?是否与ADO组件相关(本例为TADOQuery)
我从数据库 dbdemos.mdb(程序 Files\Common Files\Borland Shared\Data 中尝试了类似的查询并且有效
SELECT CustNo,
(SELECT SUM(AmountPaid) FROM orders O
WHERE O.CustNo = C.CustNo
AND O.SaleDate >= #01/01/1994#
AND O.SaleDate < #01/01/1995#
) AS AmountPaid
FROM customer C
我在Delphi中使用的代码如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOConnection1.Connected := False;
ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\Xiber\Delphi\Whosebug\Subquerys\dbdemos.mdb';
ADOConnection1.Connected := True;
ADOQuery1.SQL.Text := 'SELECT CustNo, (SELECT SUM(AmountPaid) FROM orders O WHERE O.CustNo = C.CustNo AND O.SaleDate >= #01/01/1994# AND O.SaleDate < #01/01/1995#) AS AmountPaid FROM customer C';
ADOQuery1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
sSQL: string;
begin
ADOConnection1.Connected := False;
ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\Xiber\Delphi\Whosebug\Subquerys\XiGest-CASA.mdb';
ADOConnection1.Connected := True;
sSQL := ' SELECT CMCB.Name, ' +
' (SELECT SUM(amount) FROM movement MCB ' +
' WHERE MCB.movement_classification_id=CMCB.movement_classification_id ' +
' AND MCB.operation_date >= #01/01/2013# ' +
' AND MCB.operation_date < #01/01/2014# ' +
' ) AS MyYear ' +
' FROM movement_classification CMCB ';
ADOQuery1.SQL.Text := sSQL;
ADOQuery1.Open;
end;
按照目前的情况,您的查询应该 return 每行员工的 sum(qty) 值相同。如果 Access 是 "hiding" 两个 table 之间的关系,那就可以解释为什么它在 Access 中有效。 我希望查询类似于:
select e.name, sum(i.qty)
from
employee e,
items i
where
i.employeeid = e.employeeid
会更像您所追求的。当然,这假设两个table之间存在直接关系(项目table中employeeid的外键),这不太现实。
正如其他人评论的那样,更多的信息将允许更准确的答案!
您是否有任何原因无法简化查询(假设它是 ADO 错误),例如:
select CMCB.Name, SUM(MCB.amount)
from
movement_classification CMCB,
movement MCB
where
MCB.movement_classification_id=CMCB.movement_classification_id
AND MCB.operation_date >= #01/01/2013#
AND MCB.operation_date < #01/01/2014#
最后我意识到两个总和之间的区别是在 dbdemos 中字段 AmountPaid.mdb 是 double 而在我的例子中是 decimal(8 ,2)。
这似乎是一个 ADO 错误。可以自己复现。
因此,如果您更改 dbdemos.mdb 中的字段 AmountPaid(由 Borland 提供,您可以在程序 Files\Common Files\Borland Shared\Data) 到 decimal(8,2) 并通过 Delphi 7 执行查询(使用 ADOConnection 和 ADOQuery ), 你会得到上面提到的错误。
SELECT CustNo,
(SELECT SUM(AmountPaid) FROM orders O
WHERE O.CustNo = C.CustNo
AND O.SaleDate >= #01/01/1994#
AND O.SaleDate < #01/01/1995#
) AS AmountPaid
FROM customer C
但是如果你在 MS Access 中执行这个查询,它工作正常。