过程 PLSQL 中的查询必须返回 1 行,但返回更多行
我在实现 pl/sql 过程时遇到一个奇怪的问题。
我的程序有四个 varchar 输入参数,并使用如下查询从表中提取 id 值:
SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
在此表中,name 和 sur 是唯一键。因此,对于几个输入参数(pn,ln),我期望只获得一行,但事实并非如此。 事实上,似乎只有第一个条件得到了处理,而第二个条件没有得到处理。
在我的表中,有这个测试行:
ID | NAME | SUR
1 | JO | SOME THING
2 | JO | OTHER ONE
3 | BO | SOME THING
如果在我的程序中通过,
('JO', 'SOME THING')
我将获得 ID:1 和 2。
但是,如果我传递值,
('BO', 'SOME THING')
我仅获得 ID 3。
显然,通过之前的查询,我获得了错误 ORA-01422,因此我首先用游标定义替换它,然后用“for row in (query)”替换它:
CURSOR C IS
SELECT ID FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
这种行为对于我,事实上,如果我只执行来自 sqlplus 或 toad 的查询,我会得到正确的结果。
Oracle版本是8.1。
预先感谢
#这是我的程序(我希望你不会发现不匹配,因为我更改了对象名称):
CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
ln in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
AS
idT NUMBER;
idST NUMBER;
idSE NUMBER;
CURSOR C IS
SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln;
BEGIN
for x in ( SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln )
loop
DBMS_OUTPUT.put_line('INFOR:' || x.ID);
end loop;
open C;
loop
fetch C into idT;
exit when C%NOTFOUND;
DBMS_OUTPUT.put_line('INLOOP:ID='||idT);
end loop;
close C;
DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idT );
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR(-20001, 'Exact Fetch Returned many Rows');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR');
ROLLBACK;
RAISE;
END myproc;
/
谢谢
I have a strange problem implementing pl/sql procedure.
My procedure has four varchar input parameter, and extracts from a table an id value with a query like this:
SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
In this table, name and sur are unique key. So for a couple of input parameter (pn,ln), I expect to obtain only one row, but isn't so.
Indeed, it seems that only the first condition processed, and the second doesn't.
In my table I have, this test row:
ID | NAME | SUR
1 | JO | SOME THING
2 | JO | OTHER ONE
3 | BO | SOME THING
If in my procedure I pass
('JO', 'SOME THING')
I obtain ID: 1 and 2.
But if I pass values
('BO', 'SOME THING')
i obtain only ID 3.
Clearly, with previous query I obtained error ORA-01422, so I substitute it with a cursor definition first, and a "for row in (query) " later:
CURSOR C IS
SELECT ID FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
This behavior is strange for me, in fact if I exec only query from sqlplus or toad, i obtain correct result.
Oracle version is 8.1.
Thanks in advance
#
This is my procedure (I Hope you don't find mismatch, because I changed name of objects):
CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
ln in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
AS
idT NUMBER;
idST NUMBER;
idSE NUMBER;
CURSOR C IS
SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln;
BEGIN
for x in ( SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln )
loop
DBMS_OUTPUT.put_line('INFOR:' || x.ID);
end loop;
open C;
loop
fetch C into idT;
exit when C%NOTFOUND;
DBMS_OUTPUT.put_line('INLOOP:ID='||idT);
end loop;
close C;
DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idT );
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR(-20001, 'Exact Fetch Returned many Rows');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR');
ROLLBACK;
RAISE;
END myproc;
/
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许您的参数和表字段之间存在冲突?
通过添加过程名称作为参数范围来更改它:
Maybe there's a clash between your parameters and fields of the table?
Change it by adding the name of your procedure as scope for your parameters:
“...因为我更改了对象的名称”
也许您的某些参数与某些列具有相同的名称。
例如,如果您的过程如下所示:
您将收到 TOO_MANY_ROWS 错误,因为条件“T.SUR = sur”与“T.SUR = T.SUR”具有相同的效果。
"... because I changed name of objects"
Maybe some of your parameters have the same names as some columns.
For example if your procedure looked like this:
you would get TOO_MANY_ROWS error because the condition "T.SUR = sur" would have the same effect as "T.SUR = T.SUR".
我用你的示例表测试了你的第一个语句!在我的机器上它可以工作。但那是一个 Oracle 10g 数据库。
编辑:
我重新编写了你的程序,并且在我的机器上该版本运行良好!
I tested your first statement with your example table! And on my machine it works. But that is an Oracle 10g database.
Edit:
I re-writed your procedure and on my machine that version works well!