从 PowerBuilder 执行 Oracle 函数

Posted

技术标签:

【中文标题】从 PowerBuilder 执行 Oracle 函数【英文标题】:Execute Oracle function from PowerBuilder 【发布时间】:2018-02-23 09:15:03 【问题描述】:

我有一个带有一个参数的 Oracle 函数。我需要从 PowerBuilder 调用它。这可能吗?如果是这样,怎么做?谢谢!

我的功能:

CREATE OR REPLACE FUNCTION OPEN.F_VALIDATION (f_date DATE)
   RETURN NUMBER
IS
v_an number;
v_debug_line varchar2(20);
BEGIN
/*some relevant code - delete, selects, updates, inserts*/

DBMS_OUTPUT.put_line ('OK');
   COMMIT;
   RETURN v_an;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('v_debug_line: ' || v_debug_line);
      DBMS_OUTPUT.put_line (
         'ERROR: ' || SQLERRM);
      ROLLBACK;

      DBMS_OUTPUT.put_line ('ERROR');
      RETURN v_an;
END F_VALIDATION ;

【问题讨论】:

【参考方案1】:

我不知道如何从 PowerBuilder 调用 Oracle 函数 - Google 知道,例如在 PowerBuilder: Calling Oracle Stored Procedures and Functions 上,这样说

... 一个好的方法是首先将其声明为外部函数,然后 然后根据该声明调用它。

我不想在此处复制/粘贴该内容,因为它很可能是错误的(正如我所说,我不使用该软件产品)。

但是,我对您发布的代码有一些反对意见。如果偏离主题,我深表歉意。

“一些相关的代码” - 这不会工作就像那样;您在该功能中执行什么 DML(以及为什么)?

SQL> create or replace function f_test
  2    return number
  3  is
  4  begin
  5    insert into dept (deptno, dname) values (99, 'test');
  6    return 1;
  7  end;
  8  /

Function created.

SQL> select f_test from dual;
select f_test from dual
       *
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "SCOTT.F_TEST", line 5

如果你想在函数中执行 DML,你会错过 PRAGMA AUTONOMOUS_TRANSACTION 并 COMMIT DML(虽然 COMMIT 已经存在,所以也许还有 pragma ass),但这很可能不是一个好主意。

SQL> create or replace function f_test
  2    return number
  3  is
  4    pragma autonomous_transaction;
  5  begin
  6    insert into dept (deptno, dname) values (99, 'test');
  7    commit;
  8    return 1;
  9  end;
 10  /

Function created.

SQL> select f_test from dual;

    F_TEST
----------
         1

SQL>

AskTom 说这样的事情是邪恶的,所以 - 考虑使用带有 OUT 参数的过程。

另外,您是否意识到这样的异常处理程序对最终用户毫无用处?他们永远看不到 DBMS_OUTPUT.PUT_LINE 结果。另一方面,看到“v_debug_line”表明您将其用于调试目的 - 在这种情况下,我对此没有异议。

但实际上,尽量不要在函数中使用 DML。

再次抱歉,如果它无关紧要,并且您坚持保持原样。

【讨论】:

这应该是评论而不是答案? 是的。如果 *** 更改了 600 个字符的限制并启用了漂亮的格式,我很乐意将其转换为评论。【参考方案2】:

在此示例中,Oracle 函数在与应用程序连接的相同模式中声明。

CREATE OR REPLACE FUNCTION F_VALIDATION(f_date DATE) RETURN NUMBER IS
  v_an number;
begin

  /* If f_date is today then 1 else 0 */
  select decode(to_date(sysdate), f_date, 1, 0) into v_an from dual;
  RETURN v_an;

EXCEPTION
  WHEN OTHERS THEN
    /* This will never happen */
    v_an := -1;
    RETURN v_an;
END F_VALIDATION;

将存储过程声明为用户对象的外部函数:

在用户对象绘制器的脚本视图中,从第一个列表中选择 [Declare],从第二个列表中选择 Local External Functions。

将光标放在“声明本地外部函数”视图中。 从弹出菜单或编辑菜单中,选择选择性粘贴>SQL>远程存储过程。

PowerBuilder 从您的数据库中加载存储过程并显示“远程存储过程”对话框。

选择一个或多个要声明为用户对象函数的存储过程的名称,然后单击“确定”。

PowerBuilder 从数据库中检索存储过程声明并将每个声明粘贴到视图中。

例如,这里是当您选择 F_VALIDATION 时显示在一行上的声明:

function double F_VALIDATION(datetime F_DATE) RPCFUNC ALIAS FOR "F_VALIDATION"

假设:

您的 SQLCA 连接到编译 F_VALIDATION 的同一架构。

PowerBuilder 代码存在于您声明 F_VALIDATION 的对象中。

这是一个如何调用函数的示例。

double ld_result
ad_date = datetime( today(), now() )

ld_result = F_VALIDATION( ad_date )

if sqlca.sqlcode = -1 then
    //Some error handling
    //messagebox("Unexpected error", "Error calling F_VALIDATION. database error message=" + sqlca.sqlerrtext )
    ld_result = -1
end if

【讨论】:

【参考方案3】:

在 PowerBuilder 中调用 Oracle 函数的另一种方法,假设您的应用已经连接到数据库:

long l_rc
date d_date = today()

SELECT open.f_validation( :d_date )
INTO :l_rc
FROM dual;

if sqlca.sqlcode <> 0 then
    messagebox( "Exception", "Unable to validate:~r~n" + sqlca.sqlerrtext )
end if

【讨论】:

以上是关于从 PowerBuilder 执行 Oracle 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Powerbuilder Query 转换为 Oracle

powerbuilder嵌套查询不能从单文本框中取值

如何从 PowerBuilder 应用程序播放哔声?

从 Powerbuilder 应用程序调用 .Net COM 程序集(无需注册)

powerbuilder 中pbl,pbt,pbd分别是做啥用的

PowerBuilder -- 调试(Debug)