oracle PL/SQL为性别创建单独的列表

e37o9pze  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(115)

我需要使用循环在单独的列表中打印出男性和女性朋友,但是收到错误:
'循环06550。00000 -“行%s,列%s:\n%s”* 原因:PL/SQL编译错误。* 行动:'

DECLARE
 v_gender VARCHAR2(500);
 v_male VARCHAR2(1);
 v_female VARCHAR2(1);
BEGIN
    FOR i IN (select * from friend_name)
        LOOP
    v_gender := 'Gender ' || i.gender ||', '|| i.first_name ||', '|| i.last_name;
    dbms_output.put_line(v_gender);
    
    v_male      := null;
    v_female    := null;  
    
    FOR J IN (SELECT * FROM friend_name)LOOP
   
             IF(j.gender = 'M')
    THEN dbms_output.put_line(first_name ||', '|| last_name ||', '|| v_male);
    
    ELSE
    dbms_output.put_line(first_name ||', '|| last_name ||', '|| v_female); 
    
             END IF;
        END LOOP;
END;

你能帮我看看丢了什么吗?

o2rvlv0m

o2rvlv0m1#

您得到的错误与您没有END第一个LOOP有关。如果你修复它,你会得到另一个错误,因为你没有正确地 * 限定 * J游标变量(即不只是first_name,而是j.first_name)。
固定后,带样品表:

SQL> SELECT * FROM friend_name;

GENDER  FIRST_NAME      LAST_NAME
------- --------------- ---------------
M       Little          Foot
M       Scott           Tiger
F       Big             Feet

程序 * 工程 *

SQL> SET SERVEROUTPUT ON
SQL>
SQL> DECLARE
  2     v_gender  VARCHAR2 (500);
  3     v_male    VARCHAR2 (1);
  4     v_female  VARCHAR2 (1);
  5  BEGIN
  6     FOR i IN (SELECT * FROM friend_name)
  7     LOOP
  8        v_gender := 'Gender ' || i.gender || ', ' || i.first_name || ', ' || i.last_name;
  9        DBMS_OUTPUT.put_line (v_gender);
 10
 11        v_male := NULL;
 12        v_female := NULL;
 13     END LOOP;
 14
 15     FOR J IN (SELECT * FROM friend_name)
 16     LOOP
 17        IF (j.gender = 'M')
 18        THEN
 19           DBMS_OUTPUT.put_line (j.first_name || ', ' || j.last_name || ', ' || v_male);
 20        ELSE
 21           DBMS_OUTPUT.put_line (j.first_name || ', ' || j.last_name || ', ' || v_female);
 22        END IF;
 23     END LOOP;
 24  END;
 25  /

并产生以下输出:

Gender M, Little, Foot
Gender M, Scott, Tiger
Gender F, Big, Feet
Little, Foot,
Scott, Tiger,
Big, Feet,

PL/SQL procedure successfully completed.

SQL>

我不知道这是否是你真正想要的,因为你没有发布想要的结果,但是-考虑一下这样的事情:

SQL> DECLARE
  2     v_male    VARCHAR2 (10000);
  3     v_female  VARCHAR2 (10000);
  4  BEGIN
  5     FOR i IN (SELECT gender, first_name, last_name FROM friend_name)
  6     LOOP
  7        IF i.gender = 'M'
  8        THEN
  9           v_male := v_male || ', ' || i.first_name || ' ' || i.last_name;
 10        ELSIF i.gender = 'F'
 11        THEN
 12           v_female := v_female || ', ' || i.first_name || ' ' || i.last_name;
 13        END IF;
 14     END LOOP;
 15
 16     v_male := LTRIM (v_male, ', ');
 17     v_female := LTRIM (v_female, ', ');
 18
 19     DBMS_OUTPUT.put_line ('Male: ' || v_male);
 20     DBMS_OUTPUT.put_line ('Female: ' || v_female);
 21  END;
 22  /
Male: Little Foot, Scott Tiger
Female: Big Feet

PL/SQL procedure successfully completed.

SQL>

或者,使用集合?

SQL> DECLARE
  2     v_male    SYS.odcivarchar2list;
  3     v_female  SYS.odcivarchar2list;
  4  BEGIN
  5     SELECT first_name || ' ' || last_name
  6       BULK COLLECT INTO v_male
  7       FROM friend_name
  8      WHERE gender = 'M';
  9
 10     SELECT first_name || ' ' || last_name
 11       BULK COLLECT INTO v_female
 12       FROM friend_name
 13      WHERE gender = 'F';
 14
 15     DBMS_OUTPUT.put_line ('Male:');
 16
 17     FOR i IN v_male.FIRST .. v_male.LAST
 18     LOOP
 19        DBMS_OUTPUT.put_line (v_male (i));
 20     END LOOP;
 21
 22     DBMS_OUTPUT.put_line ('Female:');
 23
 24     FOR i IN v_female.FIRST .. v_female.LAST
 25     LOOP
 26        DBMS_OUTPUT.put_line (v_female (i));
 27     END LOOP;
 28  END;
 29  /
Male:
Little Foot
Scott Tiger
Female:
Big Feet

PL/SQL procedure successfully completed.

SQL>

有很多选择(像往常一样)。

xt0899hw

xt0899hw2#

您可以使用参数化光标,然后为每个性别循环:

DECLARE
  CURSOR c_friends (v_gender IN VARCHAR2) IS
    SELECT * FROM friend_name WHERE gender = v_gender ORDER BY first_name, last_name;
BEGIN
  DBMS_OUTPUT.PUT_LINE('M');
  FOR f IN c_friends('M') LOOP
    DBMS_OUTPUT.PUT_LINE(f.first_name ||', '|| f.last_name ||', M');
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('F');
  FOR f IN c_friends('F') LOOP
    DBMS_OUTPUT.PUT_LINE(f.first_name ||', '|| f.last_name ||', F');
  END LOOP;
END;
/

或者你可以使用光标来查找不同的性别,然后使用参数化查询来查找该性别的名称:

DECLARE
  CURSOR c_friends (v_gender IN VARCHAR2) IS
    SELECT * FROM friend_name WHERE gender = v_gender ORDER BY first_name, last_name;
BEGIN
  FOR g IN (SELECT DISTINCT gender FROM friend_name ORDER BY gender DESC) LOOP
    DBMS_OUTPUT.PUT_LINE(g.gender);
    FOR f IN c_friends(g.gender) LOOP
      DBMS_OUTPUT.PUT_LINE(f.first_name ||', '|| f.last_name ||', '||g.gender);
    END LOOP;
  END LOOP;
END;
/

或者,如果您只需要显示名称,那么您不需要使用多个光标;相反,只需按性别对查询进行排序:

DECLARE
  v_gender VARCHAR2(20);
BEGIN
  FOR f IN (SELECT * FROM friend_name ORDER BY gender DESC, first_name, last_name) LOOP
    IF v_gender IS NULL OR v_gender != f.gender THEN
      v_gender := f.gender;
      DBMS_OUTPUT.PUT_LINE(f.gender);
    END IF;
    DBMS_OUTPUT.PUT_LINE(f.first_name ||', '|| f.last_name ||', '||f.gender);
  END LOOP;
END;
/

其中,对于样本数据:

CREATE TABLE friend_name (gender, first_name, last_name) AS
SELECT 'F', 'Alice', 'Abbot' FROM DUAL UNION ALL
SELECT 'M', 'Bobby', 'Baron' FROM DUAL UNION ALL
SELECT 'F', 'Carol', 'Count' FROM DUAL UNION ALL
SELECT 'M', 'David', 'Duke'  FROM DUAL UNION ALL
SELECT 'F', 'Emily', 'Earl'  FROM DUAL;

所有输出:

M
Bobby, Baron, M
David, Duke, M
F
Alice, Abbot, F
Carol, Count, F
Emily, Earl, F

fiddle

相关问题