DBMS_OUTPUT.PUT_LINE 抛出“PL/SQL:数字或值错误”

Posted

技术标签:

【中文标题】DBMS_OUTPUT.PUT_LINE 抛出“PL/SQL:数字或值错误”【英文标题】:DBMS_OUTPUT.PUT_LINE throws "PL/SQL: numeric or value error" 【发布时间】:2021-05-25 11:24:00 【问题描述】:

我想使用DBMS_OUTPUT.PUT_LINE 在 oracle pl/sql 中测试我的一个函数。我遇到的问题是,当我在我的函数中写一个点号时,我收到以下错误:

错误

ORA-06502: PL/SQL: numerischer oder Wertefehler: Fehler beim Konvertieren von Zeichen zu Zahl
ORA-06512: in Zeile 4 // line 4 is "v_net := pricecalculator(120.09)"
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.

这行得通

CREATE OR REPLACE FUNCTION Pricecalculator(net IN NUMBER, vat IN NUMBER DEFAULT 0.19)
    RETURN NUMBER
    IS
        Result NUMBER;
    BEGIN
        Result := net * (1 + vat);
        RETURN Result;
    END;
/

SET SERVEROUTPUT ON

DECLARE
    v_net NUMBER;
BEGIN
    v_net := Pricecalculator(120);
    DBMS_OUTPUT.PUT_LINE(v_net); // Prints (142.8)
END;
/

这不起作用(见错误)

SET SERVEROUTPUT ON

DECLARE
    v_net NUMBER;
BEGIN
    v_net := Pricecalculator(120.09);
    DBMS_OUTPUT.PUT_LINE(v_net); // When I delete this, v_net gets compiled but I wont see the result
END;
/

我是 oracle pl/sql 的新手,并且零线索为什么第二种方法不起作用。

【问题讨论】:

Seems to work OK...? 也检查了 SQL Developer(20.4,针对 12cR1 DB)。 在我的 sql_developer 0.o (20.2) 中不起作用。我的DBMS_OUTPUT.PUT_LINE(v_net) 显示为灰色 我的猜测:您的语言环境,检查您的 sql 客户端 NLS_NUMERIC_CHARACTERS。数据库似乎带有点小数分隔符,我猜您的客户正在使用逗号小数分隔符。在您的 PLSQL client 块中尝试 v_net := Pricecalculator(120,09); 我不能写Pricecalculator(120, 09),因为那样我只需将vat 参数更改为9,输出将是1200 @Zilog80 没有;所有参数和变量都是数字,NLS 字符仅用于与字符串之间的转换。数字文字总是必须使用小数点。 Pricecalculator(120,09) 将把它视为两个参数,net 的 120 和 vat 的 9。但你是对的,至少在 SQL Developer 中是这种设置破坏了它。 【参考方案1】:

这似乎是 SQL Developer 中的一个错误。查看语句日志,您的块正在转换为:

DECLARE SqlDevBind1Z_1 VARCHAR2(32767):=:SqlDevBind1ZInit1;  BEGIN DECLARE
    v_net NUMBER;
BEGIN
    v_net := Pricecalculator(TO_NUMBER( SqlDevBind1Z_1));
    DBMS_OUTPUT.PUT_LINE(v_net);
END;
 :AUXSQLDBIND1:=SqlDevBind1Z_1;  END;

这部分:

TO_NUMBER( SqlDevBind1Z_1)

正在执行隐式转换。正如@Zilog80 建议的那样,这将使用您的 NLS_NUMERIC_CHARTACTERS 设置,因此只有将其设置为 ',.' 时才会出现问题 - 即使用逗号作为小数分隔符。

您可以通过以下方式解决它:

alter session set nls_numeric_characters = '.,'

但是你的隐式转换输出将是142.9071 而不是142,9071。如果您希望在输出中使用逗号分隔符,则需要进行显式转换:

DBMS_OUTPUT.PUT_LINE(TO_CHAR(v_net, '99990.9999', 'nls_numeric_characters='',.'''));

...除了 SQL Developer 也很无聊;这就是为什么您在问题中显示句号的原因。希望这就是你想看到的......

【讨论】:

如果我没记错的话,可以直接用TO_CHAR函数指定NLS_NUMERIC_CHARTACTERS,语法:TO_CHAR(number,format,'NLS_NUMERIC_CHARACTERS = '',.''') 这成功了,谢谢。不知道如何向我的教授解释这个解决方案,但是是的。 SQL Developer 是愚蠢的边缘 @Zilog80 - 谢谢,是的,我已经开始展示这一点,并以某种方式发布了一些缺失的内容。

以上是关于DBMS_OUTPUT.PUT_LINE 抛出“PL/SQL:数字或值错误”的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 中的dbms_output.put_line

Oracle 中的dbms_output.put_line

dbms_output.put_line 的替代方案

dbms_output.put_line 不能与游标一起正常工作

错误(357,1):PLS-00201:必须声明标识符“DBMS_OUTPUT.PUT_LINE”

存储过程的dbms_output.put_line问题