Oracle 比较两个没有主键列的表的plsql过程
必须比较以下两个表之间的数据差异。我通过写一个减号查询实现了这一点,但这不适合当前的任务。因为很少有表有50-60列,每次执行前都必须提到这些列 我遵循了,但没有成功地实现目标。基本上,我想写一个过程,其中:Oracle 比较两个没有主键列的表的plsql过程,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,必须比较以下两个表之间的数据差异。我通过写一个减号查询实现了这一点,但这不适合当前的任务。因为很少有表有50-60列,每次执行前都必须提到这些列 我遵循了,但没有成功地实现目标。基本上,我想写一个过程,其中: 接受两个表名作为参数 获取CustomerTable的所有列 然后在CustomerTable和StagingCustTable之间减去查询,只使用步骤2中获取的列 记录任何差异 可定制 卡斯特罗默号码 地址 订单号 接触 国家 邮政编码 数量 StagingCustTable 卡斯
- 卡斯特罗默号码
- 地址
- 订单号
- 接触
- 国家
- 邮政编码
- 数量
- 卡斯特罗默号码
- 地址
- 订单号
- 接触
- 国家
- 邮政编码
- 数量
- 运行Id
- 记录Id
一种动态SQL。
简单示例-假设我们有以下表格和数据:
CREATE TABLE CustomerTable(
Custromer_Number int,
Address varchar2(100),
order_Number int,
Contact int,
Country varchar2(10),
Post_Code varchar2(10),
Amount number
);
INSERT ALL
INTO CustomerTable VALUES (1, 'aaa', 1, 1, 'AA', '111', 111.11 )
INTO CustomerTable VALUES (2, 'bbb', 2, 2, 'BB', '222', 222.22 )
SELECT 1 FROM dual;
CREATE TABLE StagingCustTable
AS SELECT t.*, 1 As run_id, 1 as record_id
FROM CustomerTable t
WHERE 1=0;
INSERT ALL
INTO StagingCustTable VALUES (1, 'aaa', 1, 1, 'AA', '111', 111.11, 1, 1 )
INTO StagingCustTable VALUES (3, 'ccc', 3, 3, 'CC', '333', 333.33, 3, 3 )
SELECT 1 FROM dual;
commit;
现在,当您运行此简单查询时:
SELECT 'SELECT ' || listagg( column_name, ',' ) WITHIN GROUP ( ORDER BY column_id )
|| chr(10) || ' FROM ' || max( table_name )
|| chr(10) || ' MINUS '
|| chr(10) || 'SELECT ' || listagg( column_name, ',' ) WITHIN GROUP ( ORDER BY column_id )
|| chr(10) || ' FROM StagingCustTable ' as MySql
FROM user_tab_columns
WHERE table_name = upper( 'CustomerTable' );
您将得到以下结果:
MYSQL
-------------------------------------------------------------------------
SELECT CUSTROMER_NUMBER,ADDRESS,ORDER_NUMBER,CONTACT,COUNTRY,POST_CODE,AMOUNT
FROM CUSTOMERTABLE
MINUS
SELECT CUSTROMER_NUMBER,ADDRESS,ORDER_NUMBER,CONTACT,COUNTRY,POST_CODE,AMOUNT
FROM StagingCustTable
现在只需复制上述查询,将其粘贴到您的SQL客户机上,运行它-任务在几分钟内完成。run\u Id和Record\u Id可以被忽略以获得差异。最后的减去查询的结果将如何使用?对于
executeimmediate
,您必须选择需要事先了解结构的变量或集合。您可以使用dbms\u sql
打开一个基于表列构造的查询的ref游标,但是需要处理该ref游标。(这可以像SQL*Plus'print
命令一样简单,但取决于您的意图)。除非您真的需要将其作为一个过程,否则krokodilko的方法会简单得多。实际上,我必须将此代码组合到包中以完成一组验证。因此,也可以将差异写入文件或控制台的过程或函数。是,与上面的动态查询一起使用。