在 Oracle pl/sql 函数中定义类型

Defining a type inside an Oracle pl/sql function

我正在尝试创建一个 pl/sql 函数(我第一次使用 pl/sql 函数),它将以 10 为基数的数字转换为以 26 为基数的字符串(我的以 26 为基数的是 A..Z)。

create or replace function generateId(numericId IN NUMBER) RETURN VARCHAR2 AS
declare
  type array_t is varray(26) of CHAR;
  char_array array_t := array_t('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
  res varchar2(3);
  targetBase INTEGER := char_array.count;
begin
  LOOP
      res = char_array[REMAINDER(numericId, targetBase)] + result;
      numericId = numericId / targetBase;
  EXIT WHEN (numericId = 0);

  RETURN res;
end;

我得到的错误是:

Error(2,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following:     begin function pragma procedure subtype type <an identifier>    <a double-quoted delimited-identifier> current cursor delete    exists prior external language The symbol "begin" was substituted for "DECLARE" to continue. 

我猜是我将声明贴到了错误的地方,但我不知道它应该放在哪里。

只需删除声明的

根据语法规则(例如here)它不属于那里。

您的代码中有太多语法错误。

  1. oracle 中的赋值是使用 := 而不是 =

  2. 数组索引使用 () 而不是 []

  3. 不能给 IN 变量赋值numericId = numericId / targetBase

  4. 检查 loop statement 的语法 - 您缺少结束循环

  5. 要获取数组计数,请使用 COUNT()

    正如评论所暗示的那样

  6. 删除声明

除了此处的语法问题外,还有一些要点:

在循环前检查输入变量(避免无限循环)

使用 MOD 和 FLOOR 而不是 REMAINDER which is using ROUND

这是一个示例解决方案(没有数组 - 可以轻松添加)

create or replace function generateId(numericId IN NUMBER) RETURN VARCHAR2 AS
  v_num NUMBER;
  res varchar2(100);
begin
  v_num := numericId;
  if (v_num < 0 OR v_num != trunc(v_num)) then 
     return NULL; /* or raise exeption */
  end if;

  LOOP
     res := chr(ascii('A')  + MOD(v_num, 26)) || res;
     v_num := FLOOR(v_num/26);
  EXIT WHEN (v_num = 0);
  END LOOP;
  RETURN res;
end;
/



select generateId(35286) code from dual;

CODE     
-----
CAFE 

无需在CREATE OR REPLACE后写声明。您的声明部分已经从 create 关键字开始。 如果您不想将其置于无限循环中,则应该再次结束循环。