【问题标题】:Datawarehousing Automation using stored procedure使用存储过程的数据仓库自动化
【发布时间】:2014-06-17 13:32:29
【问题描述】:

我正在尝试编写一个程序,在该程序中我可以验证所有记录是否从源移动到目标,前提是该特定列之间不涉及转换逻辑。我的方法是按源列和目标列的计数分组并匹配它们的计数。如果计数为 0,则该特定列的所有记录都与目标表匹配。

按计数从 2 个数据组中再减去一个减号将提供缺失的数据。

任何人都可以在这方面进一步帮助我。

存储过程:

   create or replace
PROCEDURE MOVE_CHECK 
(SCHEMA_SOURCE IN VARCHAR2,SCHEMA_TARGET IN VARCHAR2, TABLE_SOURCE IN VARCHAR2, TABLE_TARGET IN VARCHAR2, COLUMN_SOURCE IN VARCHAR2,
COLUMN_TARGET IN VARCHAR2)
AS

 A varchar2 (30);
 B varchar2 (30);
 C varchar2 (30);
 D varchar2 (30);
 E varchar2 (30);
 F varchar2 (30);
 COUNT_SOURCE number(38);
 TEMP_1 VARCHAR2(500);
 TEMP_2 VARCHAR2(500);
 TEMP_3 VARCHAR2(500);
 TEMP_4 VARCHAR2(500);
 COUNT_QUERY number(38);

BEGIN 

A:=SCHEMA_SOURCE;
B:=SCHEMA_TARGET;
C:=TABLE_SOURCE;
D:=TABLE_TARGET;
E:=COLUMN_SOURCE;
F:=COLUMN_TARGET;

-- checking the count of the source records 

TEMP_1 :='select count ( '|| E ||' ) from ' || C;
EXECUTE  IMMEDIATE TEMP_1 INTO COUNT_SOURCE;
DBMS_OUTPUT.PUT_LINE ('source_count:'||Count_source);
TEMP_2 :='CREATE GLOBAL TEMPORARY TABLE SET_SOURCE AS (SELECT COUNT(1) AS COUNT_SOURCE, '|| E ||'  from ' || C || ' GROUP BY ' || E||' )';
EXECUTE  IMMEDIATE TEMP_2;
TEMP_3 :='CREATE GLOBAL TEMPORARY TABLE SET_TARGET AS (SELECT COUNT(1) AS COUNT_TARGET, ' || F||'FROM '||D||' GROUP BY ' ||D ||' )';
EXECUTE  IMMEDIATE TEMP_3;
TEMP_4:= 'SELECT COUNT(1) FROM SET_SOURCE INTERSECT SET_TARGET '; 
EXECUTE  IMMEDIATE TEMP_4 INTO COUNT_QUERY;
DBMS_OUTPUT.PUT_LINE ('OUTPUT:'||COUNT_QUERY);

IF COUNT_QUERY <> 0
THEN DBMS_OUTPUT.PUT_LINE ('PLEASE CHECK');
ELSE DBMS_OUTPUT.PUT_LINE ('DONE- NO MISMATCH');
END IF;

END MOVE_CHECK;

我无法运行执行 Temp_2,Temp_3,Temp_4

错误:

 ORA-00955: name is already used by an existing object
ORA-06512: at "YDSCST.MOVE_CHECK", line 35
ORA-06512: at line 16
source_count:7
Process exited.

【问题讨论】:

  • 嗯,你不认为显示错误信息会有帮助吗?
  • 这些执行的前两个错误是不言自明的。在过程中创建 GTT 无论如何都不是一个好主意,您应该将其作为单独的任务创建一次,然后将其填充到过程中。
  • 当您修复错误并继续下一个问题时,您似乎正在更新问题,这很烦人;但不一定要使代码和错误保持一致。此时您似乎已经修复了代码中的 ORA-6502,但您仍然显示该错误。我不知道您是否真的仍然收到错误 - 例如来自F||'from。似乎您能够解决所有这些问题,这很好,但我不确定您为什么要在这里问这些问题。

标签: sql oracle stored-procedures


【解决方案1】:

如果您打印出动态 SQL 并尝试手动运行它通常会有所帮助;它可以使语法错误更容易被发现。在这种情况下,如果您调用 DUAL 表的原始过程,您会看到:

CREATE GLOBAL TEMPORARY TABLE SET_SOURCE AS (SELECT COUNT(1), DUMMY )
from DUAL GROUP BY DUMMY )

如果你运行它,你会得到相同的 ORA-00923,这表明问题可能出现在 from 之前。查看代码很明显,在列名之后有一个额外的右括号。但是您自己发现了这一点,现在已经转到下一个错误。

之后的下一个错误应该是ORA-00998: must name this expression with a column alias,因为你没有指定临时表的列应该被调用。您可以在selectcreate 中执行此操作:

TEMP_2 :='CREATE GLOBAL TEMPORARY TABLE SET_SOURCE (ROW_COUNT, COLUMN_NAME) '
  || 'AS (SELECT COUNT(1), ' || E || ' from ' || C || ' GROUP BY ' || E || ')';

但您似乎也发现并修复了这个问题,因为您现在得到了 ORA-06502,这是因为您的 TEMP 变量小于您现在需要的查询字符串。但是您现在自己也修复了这个问题,将它们设为 500 个字符而不是 100 个。

您的TEMP_3 在其from 之前缺少一个空格; F 的值当前直接连接到该值,使其成为无效语句。而group by 使用的是D(表名)而不是F(列名)

TEMP_3 :='CREATE GLOBAL TEMPORARY TABLE SET_TARGET (ROW_COUNT, COLUMN_NAME) '
  || 'AS (SELECT COUNT(1), ' || F || ' FROM ' || D || ' GROUP BY ' || F ||' )';

如果您使用过程参数名称而不是无意义(和无意义)的局部变量,那将更加明显。

在过程中创建全局临时表或任何结构通常不是一个好主意。您第二次调用它时,它们将已经存在,并且会出错。如果你真的需要它们,你应该在过程之外创建临时表作为一个单独的任务,然后在过程中填充它们。

【讨论】:

  • 谢谢普尔。我会按照你的建议去做。实际上我正在学习存储过程,并且我必须完成一项任务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 2017-01-04
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多