在 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)它不属于那里。
您的代码中有太多语法错误。
oracle 中的赋值是使用 := 而不是 =
数组索引使用 () 而不是 []
不能给 IN 变量赋值numericId = numericId / targetBase
检查 loop statement 的语法 - 您缺少结束循环
要获取数组计数,请使用 COUNT()
正如评论所暗示的那样
删除声明
除了此处的语法问题外,还有一些要点:
在循环前检查输入变量(避免无限循环)
使用 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 关键字开始。
如果您不想将其置于无限循环中,则应该再次结束循环。
我正在尝试创建一个 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)它不属于那里。
您的代码中有太多语法错误。
oracle 中的赋值是使用 := 而不是 =
数组索引使用 () 而不是 []
不能给 IN 变量赋值
numericId = numericId / targetBase
检查 loop statement 的语法 - 您缺少结束循环
要获取数组计数,请使用 COUNT()
正如评论所暗示的那样
删除声明
除了此处的语法问题外,还有一些要点:
在循环前检查输入变量(避免无限循环)
使用 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 关键字开始。 如果您不想将其置于无限循环中,则应该再次结束循环。