在 oracle 中编写一个通用过程
Posted
技术标签:
【中文标题】在 oracle 中编写一个通用过程【英文标题】:writing a generic procedure in oracle 【发布时间】:2009-12-10 10:57:50 【问题描述】:我想编写以 2 个表的名称作为参数的过程,然后比较 2 个表的数量或行数。 我也想要两列的每个字段。有不匹配的行应该是 移动到另一个错误表。
任何人都可以提供一个 PL/SQL 过程来执行此操作。 我想在 oracle 9 中实现这一点
【问题讨论】:
这两个表是否总是具有完全相同的列定义,是所有表共享一个错误表还是每个表对一个错误表? @david:是的,它们确实有相同的语法 【参考方案1】:Pablos 的例子行不通,但这个想法是正确的。
像这样做吧。
create or replace PROCEDURE COMPARE_ROW_COUNT(T1 IN VARCHAR2, T2 IN VARCHAR2) AS
v_r1 number;
v_r2 number;
v_sql1 varchar2(200);
v_sql2 varchar2(200);
BEGIN
v_sql1 := 'select count(1) from ' || T1;
v_sql2 := 'select count(1) from ' || T2;
EXECUTE IMMEDIATE v_sql1 into v_r1;
EXECUTE IMMEDIATE v_sql2 into v_r2;
dbms_output.put_line(T1 || ' count = ' || v_r1 || ', ' || T2 || ' count = ' || v_r2);
END;
【讨论】:
@all :感谢您的回复,这是很大的帮助。你能告诉我如何比较这两张表的字段吗?【参考方案2】:DBMS_SQL 是此类操作的好帮手。
【讨论】:
@ammo: 你能帮我解释一下我的朋友吗?【参考方案3】:您可以在 PL/SQL 中使用dynamic sql。 EXECUTE IMMEDIATE
是你的朋友。
因此,如果您使用两个表名并尝试比较它们的行数,您会执行以下操作:
CREATE OR REPLACE PROCEDURE COMPARE_ROW_COUNT(T1 IN VARCHAR2(200), T2 IN VARCHAR2(200)) AS
v_cursor integer;
v_r1 integer;
v_r2 integer;
v_sql varchar2(200);
BEGIN
v_sql := "select count(1) into :1 from " || T1;
EXECUTE IMMEDIATE v_sql USING v_r1;
v_sql := "select count(1) into :1 from " || T2;
EXECUTE IMMEDIATE v_sql USING v_r2;
-- compare v_r1 and v_r2
END;
不能 100% 确定 PL/SQL 语法。距离我上次编写出色的 PL/SQL 代码已经有一段时间了!
您可以使用DBMS_SQL
以类似的方法获得相同的结果。不过语法有点复杂。
【讨论】:
绑定变量不能提供表名。【参考方案4】:我在这里发帖只是为了注意所有答案都围绕动态 SQL,不要将注意力转移到使用它的隐含问题上。 考虑将以下字符串作为第一个或第二个参数传递:
dual where rownum = 0 intersect
SELECT 0 FROM dual WHERE exists (select 1 from user_sys_privs where UPPER(privilege) = 'DROP USER')
我就这样吧。
回答您的问题 - Oracle 实际上将这些值存储在数据字典中,所以如果您可以访问它:
CREATE OR REPLACE PROCEDURE COMPARE_ROW_COUNT(T1 IN VARCHAR2, T2 IN VARCHAR2) AS
v_text varchar2(1000);
BEGIN
select listagg(owner || ' ' || table_name || ' count = ' || num_rows, ',')
into v_text
from all_tables --user, all or dba tables depends on requirements
where table_name in (T1, T2);
dbms_output.put_line(v_text);
exception
when others then raise; -- Put anything here, as long as you have an exception block
END COMPARE_ROW_COUNT;
【讨论】:
以上是关于在 oracle 中编写一个通用过程的主要内容,如果未能解决你的问题,请参考以下文章
spring jdbcTemplate 封装调用存储过程的通用方法(oracle数据库)
如何编写通用 SQL 查询以与所有 RDBMS(Oracle、SQL 服务器、MySql、DB2 等等)兼容的 (YYYY-MM-DD) 形式提取日期