在循环中使用获取数据的PL/SQL

在循环中使用获取数据的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

表: 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_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#
列返回多个值后超出了限制。否则,我似乎想不出上述代码不起作用的任何其他原因