首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PL/SQL After-After模式

PL/SQL After-After模式
EN

Stack Overflow用户
提问于 2012-01-09 18:11:57
回答 2查看 412关注 0票数 0

我想对PL/SQL (伪代码)使用一种事前-事后模式的方法:

Pattern方法:

代码语言:javascript
复制
procedure doIt(DO_SOMETHING)
is
  l_cnt                     pls_integer := 1;
begin
   loop
      begin
        DO_SOMETHING;
        exit;

      exception
        when exception changed then
          if l_cnt = 2 then
            --raise exception...
          else
            l_cnt := l_cnt + 1;
          end if;
       end;
    end loop;
end;  

并像这样执行它:

代码语言:javascript
复制
begin
  doIt(execute immediate sql_statement using in or out);
end;

正如您所看到的,我希望使用不同的动态sql语句(使用一个或多个in和out变量执行immediate ),但始终使用相同的“前后模式”方法。

有没有人知道我该如何解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-09 23:21:11

这个解决方案不是很好,但它是有效的。也许你可以从它开始,让它变得更好:

我在doIt函数中使用了两个参数-

1)立即执行的命令

2)参数作为anydata类型

在execute immediate命令中,我放置了将anydata转换为某种类型的所有逻辑,这些类型是我为包装In OUT参数而创建的。

代码如下:

应该为每个不同的命令创建这样的类型:

代码语言:javascript
复制
create or replace type some_type as object(a number, b number);
/

步骤如下:

代码语言:javascript
复制
create or replace procedure doIt(aa in varchar2, param IN OUT anydata) is
begin
  execute immediate aa using in out param;
end doIt;
/ 

这就是我如何调用它的(在这个例子中,我刚刚从dual中选择了count(*)到一些OUT参数中):

代码语言:javascript
复制
declare
  i number;
  prm some_type;
  ad anydata;
  a number;
  b number;
begin

  prm := new some_type(a,b);
  ad := anydata.convertobject(prm);

  doIt('declare prmAd anydata := :0; prm1 some_type; x number; begin x := prmAd.getobject(prm1); select count(*) into prm1.a from dual; :0 := anydata.convertobject(prm1); end;', ad);

  i := ad.GetObject(prm);
  dbms_output.put_line(prm.a);
end;

基本上,您可以向doIt过程添加任何您想要的内容,并使用它运行任何命令。

我猜你可以把一些execute immediate字符串移到doIt过程中,或者更好地声明类型,等等。

票数 1
EN

Stack Overflow用户

发布于 2012-01-09 19:38:50

我找不到太多关于之前/之后模式的信息,但看看你想要实现什么,可能是这样的:

代码语言:javascript
复制
create or replace
procedure doIt(stmt in varchar2, param in varchar2)
is
  l_cnt pls_integer := 1;
begin
   loop
      begin
        execute immediate stmt using param;
        exit;

      exception
        when others then
          if l_cnt = 2 then
            raise;
          else
            l_cnt := l_cnt + 1;
          end if;
       end;
    end loop;
end;  
/

-- run it 
exec doIt('insert into my_table (col1) values ( :val1 )', 'richard' );

这里的问题是,如果你想传递两个参数,那么你必须覆盖'doIt‘,例如:

代码语言:javascript
复制
procedure doIt(stmt in varchar2, param1 in varchar2, param2 in varchar2)
... 
using param1, param2

另外,另一个注意事项是将不同的数据类型传递给param。同样,您可以用正确的数据类型覆盖该过程-注意,这可能会与多个数据类型或多个参数一起变得混乱。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8786791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档