Oracle在SQL Plus文件x中调用PL/SQL问题。SQL表示my_函数“可能不是函数”

Oracle在SQL Plus文件x中调用PL/SQL问题。SQL表示my_函数“可能不是函数”,oracle,function,plsql,sqlplus,Oracle,Function,Plsql,Sqlplus,很简单,如果我以create或REPLACE函数MD5_ENCODE的形式创建函数,它将顺利运行,但是如果它以PL/SQL->的形式在SQL Plus块中匿名运行,则可能不是函数错误 Oracle的这个功能是什么 DECLARE FUNCTION MD5_ENCODE(CLEARTEXT IN VARCHAR2) RETURN VARCHAR2 IS CHK VARCHAR2(16); HEX VARCHAR2(32); I INTEGER;

很简单,如果我以create或REPLACE函数MD5_ENCODE的形式创建函数,它将顺利运行,但是如果它以PL/SQL->的形式在SQL Plus块中匿名运行,则可能不是函数错误

Oracle的这个功能是什么

DECLARE

FUNCTION MD5_ENCODE(CLEARTEXT IN VARCHAR2) RETURN VARCHAR2 IS    
    CHK VARCHAR2(16);   
    HEX VARCHAR2(32);  
    I   INTEGER;  
    C   INTEGER;  
    H   INTEGER;  
BEGIN
    IF CLEARTEXT IS NULL THEN
        RETURN '';
    ELSE
        CHK := DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING
=> CLEARTEXT);
        FOR I IN 1 .. 16 LOOP
            C := ASCII(SUBSTR(CHK, I, 1));
            H := TRUNC(C / 16);
            IF H >= 10 THEN
                HEX := HEX || CHR(H + 55);
            ELSE
                HEX := HEX || CHR(H + 48);
            END IF;
            H := MOD(C, 16);
            IF H >= 10 THEN
                HEX := HEX || CHR(H + 55);
            ELSE
                HEX := HEX || CHR(H + 48);
            END IF;
        END LOOP;  
        RETURN HEX;  
    END IF;  

END;  

BEGIN  
    UPDATE ADDRESSES_T SET STREET = MD5ENCODE(STREET) ;  

-- etc...  
END   

为了在SQL语句中调用函数,它需要作为函数对象存在于数据库中。SQL语句是与PL/SQL代码分开解析和执行的,因此它不能访问本地定义的函数


如果确实不想创建函数对象,可以使用光标在表中的行上循环,在PL/SQL语句中执行函数,并在执行过程中更新每一行。

您的第一个问题是输入错误

函数MD5_在中编码明文 VARCHAR2返回VARCHAR2为

更新地址\u T SET STREET= MD5街

update语句中的函数调用缺少下划线

您将遇到的下一个错误是:

PLS-00231: function 'MD5_ENCODE' may not be used in SQL
因此,您可以简单地将函数结果分配给一个变量,并在Update语句中使用它

可能有很多事情

我的第一个候选者是,我们只能在SQL语句中使用公共函数,即在包规范中声明的函数。即使是在同一个包体中执行的SQL语句也是如此。原因是SQL语句由另一个引擎执行,该引擎只能看到公开声明的函数


长话短说,函数必须在包中定义,就像创建或替换函数MD5ENCODEIN_TEXT in VARCHAR2 RETURN VARCHAR2 IS…

正如上面提到的注释,这可能很有用

DECLARE
  V NUMBER := 0;
  FUNCTION GET_SQ(A NUMBER) RETURN NUMBER AS
  BEGIN
    RETURN A * A;
  END;
BEGIN
  V := GET_SQ(5);
  --DBMS_OUTPUT.PUT_LINE(V);
  UPDATE MYTABLE A SET A.XCOL = V;
END;

但我在手术中也做了同样的事情,取得了成功。为什么程序和功能不同?你必须给我举一个你所做的例子。据我所知,您根本无法在SQL语句中调用过程。检测到原因,如:它可能有很多方面。我的第一个候选者是,我们只能在SQL语句中使用公共函数,即在包规范中声明的函数。即使是在同一个包体中执行的SQL语句也是如此。原因是SQL语句是由另一个引擎执行的,它只能看到公开声明的函数,而不是输入错误。我纠正了它。PLS-00231函数“md5encode”不能在SQL-1中使用不正确。您可以从SQL调用函数,它不必在包规范中。与@JeffreyKemp相矛盾,这解决了我的问题。我将我的函数添加到规范中,突然我停止获取函数FOO,因为它可能不会在SQL中使用。如果函数不在规范中,那么只能从pl/sql而不是sql调用它。SQL只能调用公共函数,因此它必须在规范中。@Gabriel,我以前是错的,但这次不是。我说过可以从SQL调用函数,它不必在包规范中。请尝试创建函数myfunc RETURN NUMBER BEGIN RETURN 1;终止然后运行SELECT myfunc FROM DUAL;。它会工作的。换句话说,如果你想把函数放在一个包中,但从SQL调用它,你必须在包规范中声明它。但是,如果你不想,你不必把函数放在包中。您可以在包的外部单独创建一个模式对象。在你看来,OP没有提到软件包,所以@yli的评论不是100%的代表性。谢谢你的跟进。