首页 > 解决方案 > 在 PL/SQL 中执行外部函数时出错

问题描述

我已经SET EXTPROC_DLLS = Anyextproc.ora文件中设置

CREATE OR REPLACE DIRECTORY oraclelib AS 'D:\Oracle\db_home\bin';

CREATE OR REPLACE LIBRARY clib AS 'ConsoleApplication2.dll' IN oraclelib;
/

CREATE OR REPLACE FUNCTION addition(
    a   NUMBER,
    b   NUMBER
)RETURN NUMBER AS EXTERNAL LIBRARY clib NAME "addfoo" LANGUAGE C;
/

DECLARE
    c NUMBER;
BEGIN
    c := addition(4, 8);
END;

我收到一个错误

Error report -
ORA-06520: PL/SQL: Error loading external library
ORA-06512: at "HRCOPY.ADDITION", line 1
ORA-06512: at line 4
06520. 00000 -  "PL/SQL: Error loading external library"
*Cause:    An error was detected by PL/SQL trying to load the external
           library dynamically.
*Action:   Ensure that the dynamic library exists, that it is installed
           correctly and that it is not corrupt or otherwise unreadable by
           the operating system.  Also, ensure that the library path in the
           LIBRARY object is correct, including the values of any environment
           variables used in the library path and the directory path values
           of any DIRECTORY objects used by the LIBRARY object.

文件中只有一个DLL名为 addfoo 的函数。谁能告诉创建外部函数的正确步骤是什么?谢谢。

标签: oracledllplsql

解决方案


亲爱的,我最近将我们的应用程序从 10g 迁移到 19c 并遇到了这个挑战。以下是我修复它的完整解决方案:-

  • 在 Linux 服务器中重新创建外部库(.so 文件)。
  • 从 /opt/oracle/appdir/product/19.0.0/rdbms/ 位置拉取 demo_rdbms.mk 和 env_rdbms.mk 文件并放入 /opt/appfilepath 位置。
    - 在 demo_rdbms.mk 文件中添加一个链接以调用 env_rdbms.mk 文件。- 转到 /opt/appfilepath 位置并运行此命令以生成 sofilename.so(外部 .so 文件)文件:-

    make -f demo_rdbms.mk sofilename 2>&1
  • 在 tnsname.ora 文件中添加条目:-
  EXTPROC_CONNECTION_DATA_APPNAME = 
  (DESCRIPTION = 
       (ADDRESS_LIST = 
   (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC8)) 
       ) 
      (CONNECT_DATA = 
       (SID = PLSExtProcAppname) 
   (PRESENTATION = RO) 
       ) 
    )
  • 在 tnsname.ora 文件中添加条目:-
SID_LIST_EXTAPPNAME_LISTENER =
  (SID_LIST =
    (SID_DESC =
       (SID_NAME = PLSExtProcAppname)
       (ORACLE_HOME = /opt/oracle/dbdir/product/19.0.0/db1)
       (TNS_ADMIN = /opt/Appname/extproc)
       (PROGRAM = extproc)
       (ENVS = 
       "EXTPROC_DLLS=ANY:/opt/appfilepath/sofilename.so,
       LD_LIBRARY_PATH=/opt/oracle/dbdir/product/19.0.0/db1/lib:$LD_LIBRARY_PATH")
       )
       )
  • 使用指向外部库位置的代理子句创建数据库链接

      宣布
         l_inst VARCHAR2(20);
      开始
         l_inst := sys_context('USERENV','DB_NAME');
    
        立即执行
         '创建或替换库 extfile_cmd 为 ''/opt/appname/' || l_inst ||
         '/apppath/sofilename.so'' AGENT ''extproc_link_appname''';
      结尾;
    
  • 使用以下测试脚本测试外部程序如果它工作正常:-

      创建或替换函数 new_fun_2 (ip_Cmd IN VARCHAR2) RETURN VARCHAR2
      作为
        外部库 extfile_cmd
        名称“sh”
        语言 C;
         /
       宣布
            l_java_return varchar2(100);
        开始
          l_java_return :=new_fun_2('ls');
          dbms_output.put_line(l_java_return);
        结尾;
    

推荐阅读