首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取PLS-00103错误。PLS-00103:遇到符号“返回”

获取PLS-00103错误。PLS-00103:遇到符号“返回”
EN

Stack Overflow用户
提问于 2021-05-06 16:30:15
回答 1查看 63关注 0票数 0

我是PL/sql的新手,目前正在编写一些必须从两个表中提取数据的PL/SQL代码。到目前为止,我的代码一直收到错误PLS-00103:遇到符号"RETURN“,而预期的是以下内容之一:*&=-+; at in is mod rem not rem

这是我目前的代码

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION LISTNATION(N_NAME in VARCHAR2, R_NAME IN VARCHAR2, R_REGIONKEY IN NUMBER)
  2  RETURN VARCHAR2 IS
  3  R_REGIONKEY NUMBER(3);
  4  R_NAME VARCHAR2(50);
  5  N_NAME VARCHAR2(50);
  6  
  7  BEGIN
  8  select r_regionkey, r_name, n_name
  9  from region
 10  inner join nation
 11  on r_regionkey = n_regionkey;
 12  
 13  dbms_output.put_line = (R_REGIONKEY || ' ' || R_NAME || ':' || N_NAME || ',')
 14  
 15  END;
 16  /
EN

回答 1

Stack Overflow用户

发布于 2021-05-06 16:53:44

出现错误的直接原因(在问题的原始版本中)是在第4行的末尾缺少一个分号。

但是还有很多其他的问题:

  • 你正在使用双引号"将字符串文字括起来,而不是单引号'。它们是用于标识符的,而不是字符串的。
  • 你的局部变量和参数是一样的,但是你无论如何都不需要所有这些参数。
  • 你没有选择任何东西;并且你的查询将返回多行。
  • 你的查询没有where子句,所以它将在所有dbms_output调用损坏的all语句中寻找数据;它缺少一个结束括号(同样,在原始问题中),并且不应该有返回test=.
  • you're,但还没有声明它。

因此,要让函数使用dbms_output来显示结果-这依赖于处理输出的调用者,您不应该假设-您可以这样做:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION LISTNATION(P_R_REGIONKEY IN NUMBER)
RETURN VARCHAR2 IS
  L_R_NAME REGION.R_NAME%TYPE;
  L_N_NAME NATION.N_NAME%TYPE;

BEGIN
  FOR l_row IN (
    select r.r_name, n.n_name
    from region r
    inner join nation n
    on r.r_regionkey = n.n_regionkey
    where r.r_regionkey = p_r_regionkey
  ) LOOP

    dbms_output.put_line (P_R_REGIONKEY || ' ' || l_row.R_NAME || ':' || l_row.N_NAME);

  END LOOP;

  RETURN 'test';
END;
/

这将向您的查询添加一个筛选器,将其转换为隐式游标,并循环结果。

带有一些虚构数据的db<>fiddle,以及从您的尝试中获取的表名和列名。

不清楚您实际想要返回什么;您可能需要一个逗号分隔的国家名称列表,在这种情况下,可以查看the listagg() function。例如,您可以这样做:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION LISTNATION(P_R_REGIONKEY IN NUMBER)
RETURN VARCHAR2 IS
  L_RESULT VARCHAR2(4000);

BEGIN
  select listagg(n.n_name, ',') within group (order by n.n_name)
  into l_result
  from region r
  inner join nation n
  on r.r_regionkey = n.n_regionkey
  where r.r_regionkey = p_r_regionkey;

  RETURN l_result;
END;
/

然后,您可以调用该函数来返回单个值列表。

db<>fiddle

尽管对该查询使用PL/SQL函数包装器似乎没有多大用处。不过,这大概只是一次练习。

有没有办法显示它,以便它只显示区域键和区域一次,而列出所有国家?

您可以更改第二个函数以包含区域信息,并将其与listagg结果连接起来:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION LISTNATION(P_R_REGIONKEY IN NUMBER)
RETURN VARCHAR2 IS
  L_RESULT VARCHAR2(4000);

BEGIN
  select r.r_regionkey || ' ' || r.r_name || ': '
    || listagg(n.n_name, ',') within group (order by n.n_name)
  into l_result
  from region r
  inner join nation n
  on r.r_regionkey = n.n_regionkey
  where r.r_regionkey = p_r_regionkey
  group by r.r_regionkey, r.r_name;

  RETURN l_result;
END;
/

然后为您感兴趣的每个区域键调用它。

db<>fiddle

你的表达方式听起来像是你不想传入一个区域键,而是想一次看到所有的区域;想要使用dbms_output,这并不理想;并且不想返回任何东西。因此,您可以改为使用过程,更改游标查询以返回区域名称,然后在循环内的put_line调用中进行连接:

代码语言:javascript
复制
CREATE OR REPLACE PROCEDURE LISTNATION IS
BEGIN
  FOR l_row IN (
    select r.r_regionkey, r.r_name,
      listagg(n.n_name, ',') within group (order by n.n_name) as names
    from region r
    inner join nation n
    on r.r_regionkey = n.n_regionkey
    group by r.r_regionkey, r.r_name
    order by r.r_regionkey
  ) LOOP

    dbms_output.put_line (l_row.R_REGIONKEY || ' ' || l_row.R_NAME || ': ' || l_row.names);

  END LOOP;
END;
/
代码语言:javascript
复制
dbms_output:
1 EMEA: FRANCE,UNITED KINGDOM
2 APAC: CHINA

db<>fiddle

当然,有很多变体,这完全取决于你想要发生什么,但你应该能够适应其中一种方法。另一种方法是让一个函数或过程生成一个引用游标,但同样不清楚您想要什么。但是使用dbms_output并不是一个好主意,因为调用者可能没有使用查找和显示它的客户端。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67414511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档