1

我正在尝试运行一个排列给定字符串的递归过程。它在 sqldeveloper 上编译,但是当我尝试使用输入运行时,它给了我 ora-06502: numeric or value errors on line 13(前缀分配)

create or replace 
  procedure print_anagrams
  (pre in varchar2, str in varchar2)
  is
    prefix varchar2(30);
    stringg varchar2(30);
    strlen number;
  begin
    strlen := length(str);
    if strlen = 0 then
     dbms_output.put_line(pre);
    else
      for i in 1..strlen loop
        prefix := pre || SUBSTR(str,i,1);
        stringg := SUBSTR(str,1,i) || SUBSTR(str,i+1,strlen);
        print_anagrams(prefix,stringg);
      end loop;
    end if;
  end;
4

1 回答 1

5

有两个问题:

首先,如果函数的参数是,而不是 0,则该LENGTH函数返回,因此您的代码中的以下条件永远不会为真(因为is ):NULLNULLstrlenNULL

if strlen = 0 then

您收到ora-06502: numeric or value errors错误消息,因为当str参数为空时,范围上限FOR LOOPNULL(因为strlenNULL):

for i in 1..NULL loop

这会产生:

ora-06502: numeric or value errors

其次,Oracle中函数的最后一个参数与Java中的方法的substr含义不同。在 Oracle 中,该参数表示“应该返回多少个字符”,而在 Java 中,它代表“要从原始字符串返回的子字符串的结束索引”,因此应该更改以下行:Stringsubstring

stringg := SUBSTR(str,1,i) || SUBSTR(str,i+1,strlen);

至:

stringg := SUBSTR(str,1,i - 1) || SUBSTR(str,i+1,strlen);

必须进行更改,因为在您提供链接的 Java 代码中,循环从 0 开始,并且 0 作为第三个参数传递,这导致循环的第一次迭代返回一个空字符串。如果不进行更改,PL/SQL 版本中的第一次迭代将返回参数的第一个字符。

最后,你得到一个工作程序:

create or replace 
  procedure print_anagrams
  (pre in varchar2, str in varchar2)
  is
    prefix varchar2(30);
    stringg varchar2(30);
    strlen number;
  begin
    strlen := length(str);
    if NVL(strlen, 0) = 0 then
     dbms_output.put_line(pre);
    else
      for i in 1..strlen loop
        prefix := pre || SUBSTR(str,i,1);
        stringg := SUBSTR(str,1,i - 1) || SUBSTR(str,i+1,strlen);
        print_anagrams(prefix,stringg);
      end loop;
    end if;
  end;
/

测试:

EXEC print_anagrams('', 'cat');

输出:

猫
cta
行为
atc
tca
tac

Oracle Substr 函数

Java String 的子字符串方法

于 2013-11-13T02:11:06.783 回答