我正在尝试创建一个pl / sql函数(我在pl / sql函数中的第一个函数),它将基数为10的数字转换为基数为26的字符串(我的基数26将是A..Z)。
private const string ROOT_DOCUMENT = "/default.aspx";
protected void Application_BeginRequest( Object sender, EventArgs e )
{
string url = Request.Url.LocalPath;
if ( !System.IO.File.Exists( Context.Server.MapPath( url ) ) )
Context.RewritePath( ROOT_DOCUMENT );
}
我得到的错误是:
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;
我的猜测是我将声明置于错误的地方,但我无法弄清楚它应该去哪里。
答案 0 :(得分:4)
代码中有太多语法错误。
numericId = numericId / targetBase
要获取数组计数,请使用COUNT()
正如评论所示
删除声明
答案 1 :(得分:2)
除了语法问题之外,还有一些额外的要点:
在循环之前检查输入变量(以避免无限循环)
使用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
答案 2 :(得分:1)
只需删除声明的。
根据语法规则(例如here),它不属于那里。
答案 3 :(得分:0)
在CREATE OR REPLACE之后无需写入声明。您的声明部分已从create关键字开始。 如果你不想把它放在无限循环中,那么应该有结束循环。