Oracle 存储过程自动化
Posted
技术标签:
【中文标题】Oracle 存储过程自动化【英文标题】:Oracle Store Procedures Automation 【发布时间】:2010-12-03 06:57:33 【问题描述】:我目前正在研究在 oracle DB 中自动创建存储过程和函数的过程 我正在使用 java 来自动化创建存储过程的过程,这样当我给出表名时,java 代码将生成以下过程:
选择 插入 更新 删除并将它们放在文本文件中
例如
select * from emp where emp_id=i_emp_id and emp_nm=i_emp_nm and emp_dpt=i_emp_dpt
如果所有三个输入都不为空,它的功能应该像
select * from emp where emp_id=i_emp_id and emp_nm=i_emp_nm and emp_dpt=i_emp_dpt
如果我将 i_emp_id 作为 null 传递,那么查询应该像这样运行
select * from emp where emp_nm=i_emp_nm and emp_dpt=i_emp_dpt
如果我将 i_emp_id 作为 null 并将 i_emp_dpt 作为 null 传递,那么查询应该像这样运行
select * from emp where emp_nm=i_emp_nm
类似的更新等
我有already posted a question on this
你能不能给我一些一般性的查询 选择 插入 更新 并删除
我对存储过程的输入可能会变化为空值或实际值
【问题讨论】:
【参考方案1】:Table API 的问题是有问题的。一方面,它们可以防止 SQL 语句嵌入到整个应用程序中。另一方面,它们会导致一种不良实践文化,因为它们使开发人员无法真正了解数据库。
无论哪种方式,这都是您要完成的大量工作。它需要对 Oracle、SQL 和 PL/SQL 有很多了解才能正确完成。一个不完整的解决方案将毫无用处。也许比没用更糟糕。
所以,不要自己写这个。领先的 PL/SQL 专家 Steven Feuerstein 编写了一个复杂的实用程序来生成表 API:Quest Code Generation Utility(以前称为 QNXO)。它在 Quest 网站上是免费的。 Find it here。确实它不是用 Java 编写的,但那又怎样?
【讨论】:
但就我的知识和理解而言,我仍然需要知道这些事情。谢谢你的链接 @Aravind - 但首先您需要对 Oracle SQL 有足够的了解才能评估您收到的任何回复。这就是我在回答你的另一个问题时提出的观点。【参考方案2】:我不确定你想要的东西是否有用,但如果你想生成插入、更新或删除语句,最好了解视图 all_tab_columns 和 user_tab_columns。
插入示例:
select 'insert into ' || :table_name || ' (' qry
from dual
union all
select column_name || ', '
from user_tab_columns
where table_name = :table_name
union all
select ') values ('
from dual
union all
select ':' || column_name || ', '
from user_tab_columns
where table_name = :table_name
union all
select ')'
from dual
【讨论】:
【参考方案3】:有很多方法可以解决这个问题。
一种解决方案是overload different code,具体取决于参数的数量及其类型。
另一种解决方案是使用一组固定的参数,而不是过滤空值......
select *
from emp
where emp_id=NVL(i_emp_id, emp_id)
and emp_nm=NVL(i_emp_nm, emp_nm)
and emp_dpt=NVL(i_emp_dpt, emp_dpt);
或者您可以在 PL/SQL 中将查询创建为字符串并使用“EXECUTE IMMEDIATE”....
PROCEDURE finder (
i_emp_id IN emp.emp_id%TYPE,
i_emp_nm IN emp.emp_nm%TYPE DEFAULT NULL,
i_emp_dpt IN emp.emp_dpt%TYPE DEFAULT NULL,
....
)
IS
l_qry VARCHAR2(1000) := 'SELECT * FROM emp WHERE 1=1';
BEGIN
IF (i_emp_nm IS NOT NULL )
THEN
l_qry := l_qry || ' AND emp_nm=' || i_emp_nm;
IF (i_emp_dpt IS NOT NULL )
THEN
l_qry := l_qry || ' AND emp_dpt=' || i_emp_dpt;
EXECUTE IMMEDIATE l_qry;
....
【讨论】:
两种提议的解决方案都代表了不好的做法。如果任何谓词列包含 null,第一个将返回错误的结果。第二个不使用绑定变量,这会导致 OLTP 系统的性能非常差。请参阅我对 Aravind 的其他问题的回答,了解正确的方法。以上是关于Oracle 存储过程自动化的主要内容,如果未能解决你的问题,请参考以下文章