如何在存储过程处理 接收一个多值参数做游标in的目标

zhujjcn 2004-12-12 11:44:13
过程接收一个参数是ID串
如'1,3,5,6,7'
在过程内部需要定义一个游标
这个游标 为 select * from table where ID in(1,3,5,6,7)

那么,这个游标的参数该如何设置,如何将接收的varchar2参数写进去?
...全文
456 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ATGC 2004-12-12
  • 打赏
  • 举报
回复
SQL> desc aa
名称 是否为空? 类型
----------------------------------------- -------- -----------
ID NUMBER(2)
NAME VARCHAR2(8)

SQL> select * from aa;

ID NAME
---------- --------
1 aa
2 gg
50 ddgg

create or replace procedure test(condition in varchar2)
as
type mycursor is ref cursor;
cursor_select mycursor;
sqlstr varchar2(500);
my_record aa%rowtype;
begin
sqlstr := 'select * from aa where id in ('||condition ||')';
open cursor_select for sqlstr;
loop
fetch cursor_select into my_record;
exit when cursor_select%notfound;
dbms_output.put_line(my_record.id||' '||my_record.name);
end loop;
close cursor_select;
end;
/

过程已创建

SQL>set serveroutput on

SQL> exec test('1,50')
1 aa
50 ddgg

PL/SQL 过程已成功完成。
ORARichard 2004-12-12
  • 打赏
  • 举报
回复
好像oracle本身没有类似split的函数,只能用substr和instr来循环取得
接着再循环里插入tmp
接着再从tmp取?
----------------------------
就这样做啊,将一个字符串拆开再插入表中这不会花多少时间的,从整体上来看效率应该不受影响
ATGC 2004-12-12
  • 打赏
  • 举报
回复
"INSTR('1,3,5,6,7',ID)>=1"
这样恐怕不行
INSTR('10,3,5,6,7',ID)>=1就不对了,就会把1也select出来
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
好像oracle本身没有类似split的函数,只能用substr和instr来循环取得
接着再循环里插入tmp
接着再从tmp取?

ORARichard 2004-12-12
  • 打赏
  • 举报
回复
在过程中建一个表tmp(id int),读入ID串,将1,3,5,6,7插入tmp;
select *from table where id in (select id from tmp);
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
这个不准的啊 除非传的ID都穿个外套,并且ID字段也穿上外套,来INSTR操作
而且效率奇低

大哥,再帮忙想想
qiaozhiwei 2004-12-12
  • 打赏
  • 举报
回复
考虑:
写为:select * from table where INSTR('1,3,5,6,7',ID)>=1
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
还有一个想问一下
我的输出可能只要3-4个字段 整个表有20-30个字段
my_record aa%rowtype这种行定义方式不能用 要怎么着来着?
CodeMagic 2004-12-12
  • 打赏
  • 举报
回复
create or replace procedure test(content varchar2) is
i pls_integer;
j pls_integer;
str varchar2(100);

type tarr is varray(100) of number;
arr tarr:=tarr();

rec emp%rowtype;
begin
i:=0;
str:=content;

loop
j:=instr(str,',');
if j<=0 then
exit;
end if;

arr.extend;
i:=i+1;
arr(i):=substr(str,1,j-1);

str:=substr(str,j+1);
end loop;

arr.extend;
i:=i+1;
arr(i):=str;

for i in arr.first..arr.last loop
select * into rec from emp where employee_id=arr(i);
dbms_output.put_line(rec.employee_id||' '||rec.first_name);
end loop;
end;
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
好像是自己搞的飞机
加引号现在不报错了 嘿嘿 揭帖了

ORARichard 2004-12-12
  • 打赏
  • 举报
回复
3: "AA"
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
问题1:
方法1:把作为PK的ID用in查询
方法2:ID换成两边戴帽子','的东西,自身ID串也最外边戴个帽子
,ID, ,1,2,3,4,5,
以instr做条件应该慢吧?

问题2:
用for sqlstr的方式是不是这句sql到执行时才编译的
直接给cursor定义sql是不是过程创建后就已经编译完了,第二种方法,可以不用forsql来搞定,效率时高在这里?

问题3:
我的数据库表是带"创建的,区分大小写,照my_record aa%rowtype;方法(my_record "aa"%rowtype;)定义行对象时报错,怎么解决


望解答 谢谢 :)
ORARichard 2004-12-12
  • 打赏
  • 举报
回复
ATGC的方法很好,不过在805上好象不行,不支持OPEN CURSORNAME FOR SQLSTR
可能是我用的版本太土了
ORARichard 2004-12-12
  • 打赏
  • 举报
回复
||在ORACLE中是连接两个字符串。
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
or?
zhujjcn 2004-12-12
  • 打赏
  • 举报
回复
多谢楼上的
||是啥西?
ATGC 2004-12-12
  • 打赏
  • 举报
回复
改了一下,速度应该更快
SQL> desc aa
名称 是否为空? 类型
----------------------------------------- -------- -----------
ID NUMBER(2)
NAME VARCHAR2(8)

SQL> select * from aa;

ID NAME
---------- --------
1 aa
2 gg
50 ddgg
10 孙悟空

create or replace procedure test(condition in varchar2)
as
type mycursor is ref cursor;
cursor_select mycursor;
sqlstr varchar2(500);
my_record aa%rowtype;
begin
sqlstr := 'select * from aa where instrb('','||condition||','','',''||id||'','') > 0';
--dbms_output.put_line(sqlstr);
open cursor_select for sqlstr;
loop
fetch cursor_select into my_record;
exit when cursor_select%notfound;
dbms_output.put_line(my_record.id||' '||my_record.name);
end loop;
close cursor_select;
end;
/

过程已创建

SQL> select * from aa;

ID NAME
---------- --------
1 aa
2 gg
50 ddgg
10 孙悟空

SQL> exec test('10,2')
2 gg
10 孙悟空

PL/SQL 过程已成功完成。

SQL> exec test('2,50,1')
1 aa
2 gg
50 ddgg

PL/SQL 过程已成功完成。

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧