如何将带有十进制值的 NUMBER 作为参数传递给 FUNCTION 或 PROCEDURE

How to pass a NUMBER with decimal values as a parameter to a FUNCTION or PROCEDURE

我正在创建一些过程和函数来简化插入、删除或更新行的任务。 我的问题听起来可能很愚蠢,因为我确实遗漏了什么。

每当我尝试将十进制值作为参数传递给过程或函数时,我都会收到错误消息。

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

下一个代码不是功能性的,而是一种显示问题的方式。

CREATE OR REPLACE FUNCTION test1(num1 NUMBER)
    RETURN NUMBER IS
        BEGIN
        RETURN num1;
        END;
/
SET SERVEROUTPUT ON;
DECLARE
    numVar NUMBER;
BEGIN
numVar:= 2.1;
DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar);

                      /***********Calling test1*************/
            DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(2.1));

END;
/

一些输出是西班牙语,但大部分是英语。

Function TEST1 compilado

Raw Number: 2,1


Error que empieza en la línea: 8 del comando :
DECLARE
    numVar NUMBER;
BEGIN
numVar:= 2.1;
DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar);
    DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(2.1));

END;
Informe de error -
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 6
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.

当我调用函数时,没有小数参数,我没有遇到任何麻烦

          /***********Calling test1*************/
DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(2));

输出

Function TEST1 compilado

Raw Number: 2,1
Function Number: 2

如果我传递一个变量而不是原始十进制数,我也不会遇到任何问题而且我实际上可以使用一个十进制数,但它对我来说意义不大创建一个过程来插入需要定义一个变量以将其作为参数传递的数据

         /***********Calling test1*************/
DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(numVar));

输出

Function TEST1 compilado
Raw Number: 2,1
Function Number: 2,1

我想了解为什么我不能将原始十进制数作为参数传递,也许我不太了解 Oracle 在将数据作为参数引入之前转换数据的方式。

如您的输出所示,您设置中的小数点分隔符是逗号(西班牙文化)而不是点。所以,你必须写 TO_NUMBER('2,1') 而不是 2.1

可能问题取决于您的 NLS_NUMERIC_CHARACTERS 参数。

尝试

select value
    from nls_session_parameters
    where parameter = 'NLS_NUMERIC_CHARACTERS';

VALUE                                  
----------------------------------------
,. 

检查这个值。更改参数,如 ;

alter session set NLS_NUMERIC_CHARACTERS = '.,';

更改“.”和','命令。我为会话更改了你可以为它更改系统。

总之;

alter session set NLS_NUMERIC_CHARACTERS = '.,';
DECLARE
    numVar NUMBER;
BEGIN
numVar:= 2.1;
DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar);
    DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(2.1));

这个问题似乎是 Oracle SQL Developer 特有的。

我有 Oracle 11.2.0.3.0 64 位,当我在 TOAD 12.0.0.61 中测试它时一切正常,但是不在 Oracle SQL Developer 17.2.0.188.

我是如何测试的:

首先,创建过程:

CREATE OR REPLACE FUNCTION test_function(x$n in NUMBER)
RETURN NUMBER IS
BEGIN  
    RETURN x$n;
END;

在 TOAD 中测试

测试 #1,.:

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,';

DECLARE
    numVar$n NUMBER;
BEGIN
    numVar$n:= 2.1;
    DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar$n);
    DBMS_OUTPUT.PUT_LINE('Function Number: '||test_function(2.1));
END;

输出:

Raw Number: 2.1
Function Number: 2.1

测试 #2,,:

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.';

DECLARE
    numVar$n NUMBER;
BEGIN
    numVar$n:= 2.1;
    DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar$n);
    DBMS_OUTPUT.PUT_LINE('Function Number: '||test_function(2.1));
END;

输出:

Raw Number: 2,1
Function Number: 2,1

在 Oracle 中测试 SQL 开发人员

Oracle SQL Developer 测试 #1 工作正常,但测试 #2 引发 ORA-06502 - 这是你的情况。

解决方案 #1:使用 to_number('2,1') 而不是 2.1

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.';

DECLARE
    numVar$n NUMBER;
BEGIN
    numVar$n:= 2.1;
    DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar$n);
    DBMS_OUTPUT.PUT_LINE('Function Number: '||test_function(to_number('2,1')));
END;

输出:

Raw Number: 2,1
Function Number: 2,1

解决方案 #2:在执行期间更改 NLS_NUMERIC_CHARACTERS

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.';

DECLARE
    numVar$n NUMBER;
    nnc$c VARCHAR2(255);
BEGIN
    numVar$n:= 2.1;

    SELECT value
    INTO   nnc$c
    FROM   nls_session_parameters
    WHERE  parameter = 'NLS_NUMERIC_CHARACTERS';

    EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS=''.,''';

    DBMS_OUTPUT.PUT_LINE('Raw Number: '||numVar$n);
    DBMS_OUTPUT.PUT_LINE('Function Number: '||test_function(2.1));

    EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS='''||nnc$c||'''';
END;

输出:

Raw Number: 2.1
Function Number: 2.1