【问题标题】:How to pass a NUMBER with decimal values as a parameter to a FUNCTION or PROCEDURE如何将带有十进制值的 NUMBER 作为参数传递给 FUNCTION 或 PROCEDURE
【发布时间】:2018-02-04 22:12:46
【问题描述】:

我正在创建一些过程和函数来简化插入、删除或更新行的任务。 我的问题可能听起来很傻,因为肯定有我遗漏的东西。

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

ORA-06502:PL/SQL:数字或值错误:字符到数字的转换错误

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

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 在将数据作为参数引入之前转换数据的方式。

【问题讨论】:

  • 所有输出的来源是相同的代码,但改变了 test1(num1 NUMBER) 的输入
  • 无法重现您的问题。如果将 DBMS_OUTPUT.PUT_LINE('Function Number: '|| test1(2.1)); 替换为 DBMS_OUTPUT.PUT_LINE('Function Number: '|| to_char(test1(2.1))); 会发生什么?

标签: sql oracle stored-procedures oracle11g oracle-sqldeveloper


【解决方案1】:

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

我有 Oracle 11.2.0.3.0 64bit,当我在 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 Developer 中测试

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 特定文化 numeric literals?我不是 Oracle 专家,但你确定吗?
    • 我很确定。看看输出:Function Number: 2,1
    • 我希望test1(2,1) 会引发关于参数数量的错误
    【解决方案3】:

    也许问题取决于您的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));
    
    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    相关资源
    最近更新 更多