我想对PL/SQL (伪代码)使用一种事前-事后模式的方法:
Pattern方法:
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; 并像这样执行它:
begin
doIt(execute immediate sql_statement using in or out);
end;正如您所看到的,我希望使用不同的动态sql语句(使用一个或多个in和out变量执行immediate ),但始终使用相同的“前后模式”方法。
有没有人知道我该如何解决这个问题?
发布于 2012-01-09 23:21:11
这个解决方案不是很好,但它是有效的。也许你可以从它开始,让它变得更好:
我在doIt函数中使用了两个参数-
1)立即执行的命令
2)参数作为anydata类型
在execute immediate命令中,我放置了将anydata转换为某种类型的所有逻辑,这些类型是我为包装In OUT参数而创建的。
代码如下:
应该为每个不同的命令创建这样的类型:
create or replace type some_type as object(a number, b number);
/步骤如下:
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参数中):
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过程中,或者更好地声明类型,等等。
发布于 2012-01-09 19:38:50
我找不到太多关于之前/之后模式的信息,但看看你想要实现什么,可能是这样的:
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‘,例如:
procedure doIt(stmt in varchar2, param1 in varchar2, param2 in varchar2)
...
using param1, param2另外,另一个注意事项是将不同的数据类型传递给param。同样,您可以用正确的数据类型覆盖该过程-注意,这可能会与多个数据类型或多个参数一起变得混乱。
https://stackoverflow.com/questions/8786791
复制相似问题