在循环中使用获取数据的PL/SQL
表: 1)试验 2.)位置 第一桌在循环中使用获取数据的PL/SQL,sql,oracle,plsql,Sql,Oracle,Plsql,表: 1)试验 2.)位置 第一桌 //TEST A# --------------- 1 2 3 第二张表: //Position A# POSITION ------------------ 1 GM 1 DIRECTOR 2 DOCTOR 3 HELLO 3 GM 当我在sqlplus中使用以下pl/sql时 DECLARE c_a# test.A#%TYPE; c_p
//TEST
A#
---------------
1
2
3
第二张表:
//Position
A# POSITION
------------------
1 GM
1 DIRECTOR
2 DOCTOR
3 HELLO
3 GM
当我在sqlplus中使用以下pl/sql时
DECLARE
c_a# test.A#%TYPE;
c_pos position.position%TYPE;
CURSOR c_app IS
SELECT t.a#,p.position from test t
INNER JOIN position p ON t.a#=p.p#;
BEGIN
OPEN c_app
LOOP
FETCH c_app into c_a# , c_pos;
DBMS_OUTPUT.PUT_LINE( c_a# || ':' || c_pos );
END LOOP;
CLOSE c_app;
END;
/
以下是输出:
1:GM
1:Director
2:Doctor
...
...
预期产出:
1:GM,Director
2:Doctor
3:HELLO,GM
我的循环有什么问题吗?对于11g,您可以使用
CURSOR c_app IS
SELECT t.a#, listagg(p.position, ', ') WITHIN GROUP(order by t.a#) over(partition by t.a#) from test t
INNER JOIN position p ON t.a#=p.p#;
不确定,但是,你不需要关闭这条线路吗
OPEN c_app;
看看这个。可能会对您有所帮助我不确定您使用的是哪种环境,因为Oracle对
10G
和11G
版本具有不同的字符串聚合功能
<10>您应该考虑使用<代码> WMLCONTAT < /代码>函数。下面是您试图通过cursor
DECLARE
CURSOR C_APP
IS
SELECT T.A#, WM_CONCAT (P.POSITION)
FROM TEST T INNER JOIN POSITION P ON T.A# = P.P#
GROUP BY T.A#;
C_A# TEST.A#%TYPE;
C_POS POSITION.POSITION%TYPE;
BEGIN
OPEN C_APP;
LOOP
FETCH C_APP
INTO C_A#, C_POS;
EXIT WHEN C_APP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (C_A# || ':' || C_POS);
END LOOP;
CLOSE C_APP;
END;
对于11G
您可以使用listag
功能。下面是示例代码
DECLARE
CURSOR C_APP
IS
SELECT T.A#,
LISTAGG(P.POSITION,',') WITHIN GROUP (ORDER BY P.POSITION)
FROM TEST T INNER JOIN POSITION P ON T.A# = P.P#
GROUP BY T.A#;
C_A# TEST.A#%TYPE;
C_POS POSITION.POSITION%TYPE;
BEGIN
OPEN C_APP;
LOOP
FETCH C_APP
INTO C_A#, C_POS;
EXIT WHEN C_APP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (C_A# || ':' || C_POS);
END LOOP;
CLOSE C_APP;
END;
确保
已将serveroutput设置为打开状态
,以便显示结果。您可以尝试一件事。使用收集功能。它将获取详细信息并以所需格式打印。这与我的问题无关,无需使用光标即可完成。您真的需要使用游标吗?您使用的是哪个版本的Oracle?11g@arnab。不需要光标。有什么办法吗?总是要面对数值太小的问题ORA-06502,它在第11行指出。有什么解决方案吗?@user3664490我不确定您的表定义是什么样子的。很可能是因为您的位置列数据类型varchar
范围在为A#
列返回多个值后超出了限制。否则,我似乎想不出上述代码不起作用的任何其他原因