PLSQL过程逻辑

PLSQL过程逻辑,sql,oracle,plsql,Sql,Oracle,Plsql,如何编写PL/SQL函数: 仅使用数字数据类型和函数,无VARCHAR2、CHAR、CLOB、XML等。 “换句话说,在您的解决方案中不使用诸如REVERSE、SUBSTR等字符/字符串函数 接受PLS_整数参数 如果提供的值小于或等于零,则抛出应用程序错误-20001并提供良好的错误消息 返回一个PLS_整数值,该整数值与输入参数中的数字顺序相反。如果输入值以一个或多个零结尾,则这些零不会出现在返回的数值中,因为它们将是前导零 以下是我到目前为止所写的内容: create or replace

如何编写PL/SQL函数:

  • 仅使用数字数据类型和函数,无VARCHAR2、CHAR、CLOB、XML等。 “换句话说,在您的解决方案中不使用诸如REVERSE、SUBSTR等字符/字符串函数
  • 接受PLS_整数参数
  • 如果提供的值小于或等于零,则抛出应用程序错误-20001并提供良好的错误消息
  • 返回一个PLS_整数值,该整数值与输入参数中的数字顺序相反。如果输入值以一个或多个零结尾,则这些零不会出现在返回的数值中,因为它们将是前导零
  • 以下是我到目前为止所写的内容:

    create or replace function test_reverse
        (p_input in pls_integer) 
        return pls_integer 
    is
        p_num pls_integer := 0; 
        p_in_num pls_integer := 0; 
        p_out_num pls_integer := 0; 
    begin 
        p_num := p_input; 
        loop 
            exit when p_num p_in_num := mod(p_num,10); 
            p_out_num := (p_out_num * 10) + p_in_num;
            p_num := trunc(p_num / 10); 
        end loop; 
        return p_out_num; 
    end; 
    

    问题是如何将1234转换为4321。string-y解决方案(承认使用了一个未记录的内置程序)本身很简单:
    to_number(reverse(to_char(1234))
    。坚持数字数据类型更麻烦。我的解决方案非常程序化:毫无疑问,存在着更优雅的解决方案

    无论如何,要将1234转换为4321,我们需要生成1+20+300+4000。我的解决方案依次隔离每个值并乘以适当的十次幂。要隔离值,我们使用带有负值的
    trunc()
    。这将数字舍入小数点的左侧。因此,
    trunc(1234,-3)
    产生
    1000
    。要将其转换为所需的值,我们将其乘以10的负三次方。因此
    1000*10(-3)=1

    该函数遍历这些数字。将1000转换为1后,我们计算余数,
    1234-1000=234
    。因此,现在我们需要分离200并将其转换为20;即
    trunc(234,-2)
    power(200,-1)
    。因此我们可以将偏移量输入
    trunc()
    递减1,输入
    幂()的指数递增2

    下面是一个工作函数(非常松散地基于您发布的函数):

    这里是。虽然没有参数验证功能,但它非常简单:

    create or replace function test_reverse
        (p_input in pls_integer) 
        return pls_integer 
    is
        p_out_num pls_integer := 0;
        offset    pls_integer;
        tgt       pls_integer;
        rmdr      pls_integer;
        exp       pls_integer;
    begin 
        if p_input <= 0 then
             raise_application_error(-20001
                  'invalid input: ' || || ' must be greater than zero.'
             );
        end if; 
        rmdr := p_input;
        ....
    
    创建或替换功能测试\u反向
    (p_输入为pls_整数)
    返回pls\u整数
    是
    p_out_num pls_integer:=0;
    偏移pls_整数;
    tgt pls_整数;
    rmdr pls_整数;
    exp pls_整数;
    开始
    
    如果p_input我喜欢使用模函数作为op建议:

    CREATE OR REPLACE FUNCTION test_reverse (
        p_input IN PLS_INTEGER
    ) RETURN PLS_INTEGER 
    IS
        remain   PLS_INTEGER := p_input;
        retval   PLS_INTEGER := 0;
    BEGIN
        IF p_input < 1 THEN
            raise_application_error(-20001,'error: input must me greater than 0');
        END IF;
        LOOP
            retval := retval * 10 + MOD(remain,10);
            remain := trunc(remain / 10);
            EXIT WHEN remain = 0;
        END LOOP;
        RETURN retval;
    END;
    /
    
    创建或替换功能测试\u反向(
    p_输入为PLS_整数
    )返回PLS\u整数
    是
    保持PLS_整数:=p_输入;
    返回PLS_整数:=0;
    开始
    如果p_输入<1,则
    raise_应用程序_错误(-20001,“错误:输入必须大于0”);
    如果结束;
    环
    retval:=retval*10+MOD(剩余,10);
    剩余:=trunc(剩余/10);
    剩余=0时退出;
    端环;
    返回返回;
    终止
    /
    

    这也避免了使用length()函数,我觉得这个函数有点“严格”,即使它是对数字进行操作。

    欢迎您提前使用。到目前为止您尝试了什么。创建或替换函数TEST\u REVERSE(p\u输入为PLS\u INTEGER)返回PLS_INTEGER为P_NUM PLS_INTEGER:=0;P_IN_NUM PLS_INTEGER:=0;P_OUT NUM PLS_INTEGER:=0;开始P_NUM:=P_输入;P_NUM P_IN_NUM:=MOD(P_NUM,10)时循环退出;P_OUT_NUM:=(P_OUT_NUM*10)+P_IN_NUM;P_NUM:=TRUNC(P_NUM/10);END LOOP;RETURN P_OUT_NUM;END;请在您的问题中添加任何代码,而不是作为注释,并描述哪些代码不起作用。此外,如果您可以将其小写以提高可读性,这将非常有趣。显然这是一个家庭作业问题。但这是一个有趣的问题,需要一些不明显的Oracle SQL函数知识,因此值得一提也许还有什么办法可以把op的问题从落选的深渊中拯救出来呢?老实说,我认为落选的选民对他们认为是懒惰的“做我的功课”的问题没有多少反应。我已经回答了@williamrobertson的评论,但这是我感到舒服的所有修饰。这就是问题所在。
    CREATE OR REPLACE FUNCTION test_reverse (
        p_input IN PLS_INTEGER
    ) RETURN PLS_INTEGER 
    IS
        remain   PLS_INTEGER := p_input;
        retval   PLS_INTEGER := 0;
    BEGIN
        IF p_input < 1 THEN
            raise_application_error(-20001,'error: input must me greater than 0');
        END IF;
        LOOP
            retval := retval * 10 + MOD(remain,10);
            remain := trunc(remain / 10);
            EXIT WHEN remain = 0;
        END LOOP;
        RETURN retval;
    END;
    /