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。虽然看起来它“解决”了一些问题,但它带来了另一个问题。代码难以维护和调试。基本上,天下没有免费的午餐。有好处,也有坏处。
我有一个程序,它运行良好,其他应用程序也想使用。
如您所见,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。虽然看起来它“解决”了一些问题,但它带来了另一个问题。代码难以维护和调试。基本上,天下没有免费的午餐。有好处,也有坏处。