我对Oracle很陌生,我有一个问题,我已经被困了几个小时。
样品:
Create Table Accounts (Id number(10),Balance number(16,3), Status Varchar2(50),Owner_Id number(10));
Create Table Transactions (Id number(10),Amount number(16,3), Trxn_date date, Account_Id number(10));
Create Table Owner (Id number(10), Firstname varchar2(50),Lastname varchar2(50));
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (1,1000,'OPEN',10);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (2,5000,'CLOSED',11);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (3,1000,'OPEN',12);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (4,5000,'CLOSED',13);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (5,1000,'OPEN',14);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (6,5000,'CLOSED',15);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (7,1000,'OPEN',16);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (8,5000,'CLOSED',17);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (9,1000,'OPEN',18);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (10,5000,'CLOSED',19);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (11,1000,'OPEN',20);
Insert Into Accounts(Id,Balance,Status,Owner_Id) Values (12,5000,'CLOSED',21);
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST1');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST2');
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST3');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST4');
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST5');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST6');
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST7');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST8');
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST9');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST10');
Insert Into Owner(Id,Firstname,Lastname) Values (10,'John','TEST11');
Insert Into Owner(Id,Firstname,Lastname) Values (11,'John','TEST12');
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (1,10,'02-FEB-2015',5);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (2,10,'02-APR-2015',5);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (3,10,'02-JUN-2015',5);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (4,10,'02-AUG-2015',5);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (5,10,'02-FEB-2015',2);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (6,10,'02-APR-2015',2);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (7,10,'02-JUN-2015',2);
Insert Into Transactions(Id,Amount,Trxn_Date,Account_Id) Values (8,10,'02-AUG-2015',2);
数据检查:
Select Unique(Account_Id) From Accounts A
Inner Join Owner B on B.ID=A.OWNER_ID
Inner Join Transactions I on I.ACCOUNT_ID=A.Id
Where I.Trxn_date Between '01-FEB-2015' and '01-JUL-2015'
And A.Status='CLOSED'
and A.Balance=5000;/*1 Row Returned*/
Loop必须先退出,然后返回
Declare
l_NewDate date:='01-FEB-2015';
l_OldDate date:='01-JUL-2015';
l_pID number(10);
Begin
For I in (Select Account_Id From Transactions
Where Trxn_date Between l_NewDate and l_OldDate)
Loop
Select Id Into l_pID From
(Select B.Id From Accounts A
Inner Join Owner B on A.Owner_Id = B.Id
Where A.Status = 'CLOSED' And A.Balance = 5000 And A.Id=I.Account_Id)
Where rownum < 2;
dbms_output.put_line(l_pID);
Exit;
End Loop;
End;
ORA-01403: No data found
ORA-06512: at line 12
我无法理解为什么在上面的数据检查明确说明时没有找到数据。
此致 J.奥尔森
答案 0 :(得分:1)
就像你说的,你的数据检查查询:
Select Unique(Account_Id)
From Accounts A
Inner Join Owner B on B.ID=A.OWNER_ID
Inner Join Transactions I on I.ACCOUNT_ID=A.Id
Where I.Trxn_date Between '01-FEB-2015' and '01-JUL-2015'
And A.Status='CLOSED'
and A.Balance=5000;
...返回单行,Account_Id
值为2
。
但是,您的PL / SQL代码基本上会在2个查询中拆分逻辑。您循环的查询是:
Select Account_Id
From Transactions
Where Trxn_date Between '01-FEB-2015' and '01-JUL-2015'
而且,当我运行它时,它返回:
5
5
5
2
2
2
现在上述订单无法保证,因为您没有ORDER BY
条款。但是如果你得到的结果与我的顺序相同,那么你的第一个循环迭代将使用5
作为输入执行下一个查询:
Select *
From Accounts A
Inner Join Owner B on A.Owner_Id = B.Id
Where A.Status = 'CLOSED'
And A.Balance = 5000
And A.Id = 5
...它不会返回任何数据,这就是您收到错误的原因。
如果你足够幸运,可以开始使用2
的价值:
Select *
From Accounts A
Inner Join Owner B on A.Owner_Id = B.Id
Where A.Status = 'CLOSED'
And A.Balance = 5000
And A.Id = 2
......它会按预期工作。
我希望我能推荐一个合适的解决方案,但我真的不明白你想要做什么。但你肯定觉得你不应该需要PL / SQL循环来做你想做的事情。一个简单的查询就足够了。您的数据检查查询似乎是一个良好的开端。
修改强>
对于它的价值,我认为这是一种更直接的方式来做你想做的事情(没有循环):
Declare
l_NewDate date:='01-FEB-2015';
l_OldDate date:='01-JUL-2015';
l_pID number(10);
Begin
select o.id into l_pID
from transactions t
join accounts a
on a.id = t.account_id
and a.status = 'CLOSED'
and a.balance = 5000
join owner o
on o.id = a.owner_id
where t.trxn_date between l_NewDate and l_OldDate
and rownum < 2;
dbms_output.put_line(l_pID);
End;