oracle 如何使我的存储过程在每次调用它时都要求值

4xrmg8kj  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(119)

我是MySql/Oracle中的新手,我试图创建一个请求2个值的过程,比较它们并返回大的一个,但我在调用它的时候遇到了麻烦
下面是我创建过程的代码:

CREATE OR REPLACE PROCEDURE NUMAYOR AS
   Num1 int;
   Num2 int;
BEGIN

   DBMS_OUTPUT.PUT_LINE('Ingrese el primer número:');
   Num1 := TO_NUMBER(&VAR1);
   
   DBMS_OUTPUT.PUT_LINE('Ingrese el segundo número:');
   Num2 := TO_NUMBER(&VAR2);
   IF Num1 > Num2 THEN
      DBMS_OUTPUT.PUT_LINE(Num1 || ' es mayor que ' || Num2);
   ELSIF Num2 > Num1 THEN 
      DBMS_OUTPUT.PUT_LINE(Num2 || ' es mayor que ' || Num1);
   ELSE 
      DBMS_OUTPUT.PUT_LINE('Los números son iguales, por favor introduce dos números diferentes');
   END IF;
END;

这工作得很好,但是当我用

BEGIN 
NUMAYOR;
END;

控制台返回我在存储过程中输入的数字,但我想在每次执行它时再次请求新数字。
我会很感激如果有人帮助我与此,我觉得这是比我想象的更容易,但我尝试了很多事情,我找不到解决办法。
对不起,我的英语im西班牙语,所以不要判断我太多哈哈
我试了很多语法

watbbzwu

watbbzwu1#

实际上,不-你不会想那样做的。
你需要的是一个返回所需结果的**函数。下面是一个例子,它展示了一种方法:

SQL> CREATE OR REPLACE FUNCTION numayor (num1 IN NUMBER, num2 IN NUMBER)
  2     RETURN NUMBER
  3  IS
  4  BEGIN
  5     RETURN GREATEST (num1, num2);
  6  END;
  7  /

Function created.

测试:

SQL> SELECT numayor (-1, 8) res1, numayor (0, 4) res2, numayor (5, 9) res3 FROM DUAL;

      RES1       RES2       RES3
---------- ---------- ----------
         8          4          9

SQL>

因此,任何时候你想使用它,只需调用函数,传递两个参数,就可以了。当然,你可以改进代码(如果参数没有传递给函数(即,如果参数没有传递给函数)该怎么办)。你传递null),等等)。
您创建的过程要求替换变量的值,并使用您提供的值创建过程,仅此而已-未来不可能更改,除非您(再次)使用新代码/值创建或替换过程。
看看你的代码在做什么:

Create procedure; I'm being asked to provide two values:

SQL> CREATE OR REPLACE PROCEDURE NUMAYOR AS
  2     Num1 int;
  3     Num2 int;
  4  BEGIN
  5
  6     DBMS_OUTPUT.PUT_LINE('Ingrese el primer número:');
  7     Num1 := TO_NUMBER(&VAR1);
  8
  9     DBMS_OUTPUT.PUT_LINE('Ingrese el segundo número:');
 10     Num2 := TO_NUMBER(&VAR2);
 11     IF Num1 > Num2 THEN
 12        DBMS_OUTPUT.PUT_LINE(Num1 || ' es mayor que ' || Num2);
 13     ELSIF Num2 > Num1 THEN
 14        DBMS_OUTPUT.PUT_LINE(Num2 || ' es mayor que ' || Num1);
 15     ELSE
 16        DBMS_OUTPUT.PUT_LINE('Los números son iguales, por favor introduce dos números diferentes');
 17     END IF;
 18  END;
 19  /
Enter value for var1: 2
old   7:    Num1 := TO_NUMBER(&VAR1);
new   7:    Num1 := TO_NUMBER(2);
Enter value for var2: 6
old  10:    Num2 := TO_NUMBER(&VAR2);
new  10:    Num2 := TO_NUMBER(6);

Procedure created.

如果我执行它,它总是返回相同的结果:

SQL> exec numayor
Ingrese el primer número:
Ingrese el segundo número:
6 es mayor que 2

PL/SQL procedure successfully completed.

SQL> exec numayor
Ingrese el primer número:
Ingrese el segundo número:
6 es mayor que 2

PL/SQL procedure successfully completed.

为什么?看看程序代码。我标记了显示使用相同值的行,总是

SQL> select text from user_source where name = 'NUMAYOR';

TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PROCEDURE NUMAYOR AS
   Num1 int;
   Num2 int;
BEGIN

   DBMS_OUTPUT.PUT_LINE('Ingrese el primer número:');
   Num1 := TO_NUMBER(2);                                     --> here

   DBMS_OUTPUT.PUT_LINE('Ingrese el segundo número:');
   Num2 := TO_NUMBER(6);                                     --> here
   IF Num1 > Num2 THEN
      DBMS_OUTPUT.PUT_LINE(Num1 || ' es mayor que ' || Num2);
   ELSIF Num2 > Num1 THEN
      DBMS_OUTPUT.PUT_LINE(Num2 || ' es mayor que ' || Num1);
   ELSE
      DBMS_OUTPUT.PUT_LINE('Los números son iguales, por favor introduce dos números diferentes');
   END IF;
END;

18 rows selected.

SQL>

因此,不-你不想这样做。如果一定是一个程序,那么

  • 声明两个in参数(就像我的函数一样)
  • 创建一个out参数(这将是结果)
  • 无论何时调用它,都必须使用PL/SQL块,因为必须将out参数的值 * 放在某个地方 *
  • 注意,dbms_output.put_line调用仅对支持它们的工具(SQL*Plus、SQL Developer、TOAD等)可见。Oracle Apex、Forms和类似的应用程序将 * 忽略 * 它,你不会看到任何结果)。

大概是这样的:

SQL> CREATE OR REPLACE PROCEDURE numayor (num1 IN NUMBER, num2 IN NUMBER, result OUT NUMBER)
  2  IS
  3  BEGIN
  4     result := GREATEST (num1, num2);
  5  END;
  6  /

Procedure created.

SQL> DECLARE
  2     l_result  NUMBER;
  3  BEGIN
  4     numayor (1, 8, l_result);
  5     DBMS_OUTPUT.put_line (l_result);
  6  END;
  7  /
8

PL/SQL procedure successfully completed.

SQL>

如果你真的,真的,真的想被要求值,使用匿名PL/SQL块:

SQL> BEGIN
  2     DBMS_OUTPUT.put_line (GREATEST (&num1, &num2));
  3  END;
  4  /
Enter value for num1: 1
Enter value for num2: 5
5

PL/SQL procedure successfully completed.

SQL> /
Enter value for num1: -2
Enter value for num2: 7
7

PL/SQL procedure successfully completed.

SQL>
j13ufse2

j13ufse22#

因此,替换变量-那些前缀为& -的变量是特定于sqlplus和其他PL/SQL IDE(如sqldeveloper,pl/sql developer,TOAD)的,但不能在PL/SQL存储过程中使用。过程应该有参数。而且,从IDE(sqlplus或其他)调用的参数应该是替代变量。因此,您的程序应该是这样的:

CREATE OR REPLACE PROCEDURE NUMAYOR(num1 number, num2 number) AS
  Num1 int;
  Num2 int;
BEGIN

  IF Num1 > Num2 THEN
    DBMS_OUTPUT.PUT_LINE(Num1 || ' es mayor que ' || Num2);
  ELSIF Num2 > Num1 THEN 
    DBMS_OUTPUT.PUT_LINE(Num2 || ' es mayor que ' || Num1);
  ELSE 
    DBMS_OUTPUT.PUT_LINE('Los números son iguales, por favor introduce dos números diferentes');
  END IF;
END;

而过程调用应该是:

begin
  NUMAYOR(&num1, &num2);
end;
/

但是,您编写的过程做了SQL函数greatest所做的事情,只有greatest更好,因为它允许两个以上的参数。此外:注意dbms_output。它实际写入一个只能容纳不超过1000000个字符的缓冲区。并且该缓冲区的内容仅在过程完成后才显示在支持dbms_output的IDE中。如果发生了一些未处理的异常,那么您将看不到dbms_output中的任何内容。dbms_output不用于Java或.NET或Python或其他语言开发的应用程序。dbms_output仅用于调试目的是相当不错的-我说相当不错,但往往还不够好...

相关问题