Oracle 重写了一个通用的过程

Oracle rewrite a procedure to be generic

我有一个程序,它运行良好,其他应用程序也想使用。

如您所见,table 和列名称被硬编码到过程中,这使得共享代码变得困难。有没有办法重写它以便共享。我想尽可能避免传递更多的值,因为这会使代码变得笨拙和笨拙。

如有任何建议,我们将不胜感激。

 SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';

CREATE table t(
seq_num integer  GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
c CLOB,
create_date DATE DEFAULT SYSDATE
);
/

insert into t (c) values (
      rpad('X',20,'X')
  );
/

create or replace procedure lob_append( p_id in number, p_text in varchar2 )
 as
 l_clob clob;
 l_text varchar2(32760);
 l_system_date_time VARCHAR2(50); 
begin

 select c into l_clob from t where seq_num = p_id for update;

SELECT TO_CHAR (SYSDATE, 'MMDDYYYY HH24:MI:SS') into l_system_date_time from dual;

-- newline each time code is appended for clarity.

 l_text := chr(10) || p_text || chr(10) || '['||l_system_date_time||']'||chr(10);

 dbms_lob.writeappend( l_clob, length(l_text), l_text );
 end;
/

exec lob_append(1, rpad('Z',20,'Z'));

exec lob_append(1, rpad('Y',10,'Y'));


select * from t;
 /

不要从程序中的 table 中 SELECT,而是将 CLOB 传递到程序中;这样你就不需要在过程中使用动态 SQL:

CREATE PROCEDURE lob_append(
  p_clob IN OUT CLOB,
  p_text IN     VARCHAR2
)
AS
  l_text varchar2(32760);
BEGIN
  -- newline each time code is appended for clarity.
  l_text := chr(10)
            || p_text || chr(10)
            || '['||TO_CHAR (SYSDATE, 'MMDDYYYY HH24:MI:SS')||']'||chr(10);

  dbms_lob.writeappend(p_clob, length(l_text), l_text );
END;
/

然后,当你想调用它时:

DECLARE
  l_clob CLOB;
BEGIN
  SELECT c INTO l_clob FROM t WHERE seq_num = 1 FOR UPDATE;

  lob_append(l_clob, rpad('Z',20,'Z'));
END;
/
DECLARE
  l_clob CLOB;
BEGIN
  SELECT c INTO l_clob FROM t WHERE seq_num = 1 FOR UPDATE;

  lob_append(l_clob, rpad('Y',10,'Y'));
END;
/

db<>fiddle here

我是这样理解这个问题的。


Is there a way this can be rewritten so it could be shared.

是的,通过使用 动态 SQL。您可以 将您需要的所有语句组合 到一个 varchar2 局部变量中,然后 运行 使用 execute immediate 它。这意味着您实际上必须将 table/column 名称传递到过程中,以便您能够以“通用”方式使用它们。

注意 SQL 注入,即 坏人 可能会尝试滥用该代码。详细了解 DBMS_ASSERT 套餐。


I want to avoid passing in more values if possible as it will make the code awkward and klunky.

好吧,这正是您必须做的相反。如果程序必须是“通用的”,您必须传递 table/column 名称(正如我已经说过的),这意味着比现在多 个参数。


值得吗?我不喜欢动态 SQL。虽然看起来它“解决”了一些问题,但它带来了另一个问题。代码难以维护和调试。基本上,天下没有免费的午餐。有好处,也有坏处。