ORA-01722:PL / SQL动态SQL代码出现无效数字错误

时间:2019-06-06 03:21:41

标签: sql oracle plsql

在运行下面的代码时,我得到了说明的错误。据我所知,该错误将表明存在一个将非数字值转换(或至少试图转换)为数字值的过程。我看不到这种情况。

*
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at "BOB.ESTIMATE_BOB01", line 72
ORA-06512: at line 1    

create or replace procedure ESTIMATE_BOB01 is

--variables

l_dblink varchar2(100) := 'db1';
file_handle UTL_FILE.file_type;
v_ts_name varchar2(30);
v_link_name varchar2(10);
v_csv_name varchar2(100);
EST_ONE_ROW_MB NUMBER := 0;
TOTAL_ROW_COUNT NUMBER := 0;
SPACE_REQUIRED NUMBER := 0;
TOT_OBJECT_SIZE_MB NUMBER := 0;
v_Mv_name varchar2(100);
v_sql1 varchar2(1500);
cur SYS_REFCURSOR;
owner varchar2(100);
table_name varchar2(100);
driver_table varchar2(100);
mandatory_join varchar2(100);
C_TOTAL_ROW_COUNT NUMBER := 0;
v_total_driver_only varchar2(100);
--

begin


SELECT tablename into v_csv_name
FROM BOB01.BOB_new_table_tracker
WHERE
CREATED_AT = (select MAX(CREATED_AT) from BOB01.BOB_new_table_tracker);

SELECT mv_name into v_Mv_name
FROM BOB01.BOB_new_table_tracker_mv
WHERE
CREATED_AT = (select MAX(CREATED_AT) from BOB01.BOB_new_table_tracker_mv);

select link_name into v_link_name from link_and_mail where mdate = (select max(mdate) from link_and_mail);
select distinct targetschema into v_ts_name from BOB01.MV_BOB_TABLE;

v_sql1 := 'SELECT /*+ monitor parallel (4)*/ a.owner,
                        a.table_name,
                        b.driver_table,
                        b.mandatory_join,
                        sum(c.sum_bytes) AS "TOT_OBJECT_SIZE_MB",
                        (sum(c.sum_bytes)) / (:C_TOTAL_ROW_COUNT) AS "EST_ONE_ROW_MB",
                        ((sum(c.sum_bytes)) / (:C_TOTAL_ROW_COUNT)) * (:TOTAL_ROW_COUNT)AS "SPACE_REQUIRED"
                 FROM dba_tables@db1 a, MV_BOB_TABLE b, '|| v_Mv_name ||' c
                 WHERE a.table_name IN ( SELECT table_name
                                       FROM MV_BOB_TABLE
                                       WHERE driver_table IS NOT NULL
                                             AND   additional_joins IS NULL
                                     )
                 AND   a.owner IN ( SELECT DISTINCT productionschema FROM MV_BOB_TABLE c  )
                 and a.table_name = b.table_name
                 and a.table_name = c.segment_name
                 group by a.owner,a.table_name,b.driver_table,b.mandatory_join
               ORDER BY table_name';

file_handle := utl_file.fopen('ESTIMATES_CSV', v_csv_name||'_EST_PROC.csv', 'w', 32767);

--
UTL_FILE.PUT_LINE(file_handle, ' ');
UTL_FILE.PUT_LINE(file_handle, 'The below report shows total row counts in PROD');
UTL_FILE.PUT_LINE(file_handle, ' for unjoined tables in the BOB document:');
UTL_FILE.PUT_LINE(file_handle, ' ');
utl_file.put_line(file_handle, 'OWNER,TABLE_NAME,MANDATORY_JOIN,TOT_OBJECT_SIZE_MB,EST_ONE_ROW_MB,TOTAL_ROW_COUNT,SPACE_REQUIRED');
--main loop
--open cur for v_sql1 using TOTAL_ROW_COUNT,C_TOTAL_ROW_COUNT;
open cur for v_sql1 using C_TOTAL_ROW_COUNT, C_TOTAL_ROW_COUNT, TOTAL_ROW_COUNT;
   loop
      fetch cur into OWNER,TABLE_NAME,MANDATORY_JOIN,TOT_OBJECT_SIZE_MB,EST_ONE_ROW_MB,TOTAL_ROW_COUNT,SPACE_REQUIRED;--,EST_ONE_ROW_MB;
      exit when cur%NOTFOUND;
      execute immediate' select /*+parallel (4)*/ count(*) from '||owner||'.'||table_name || '@' || l_dblink into TOTAL_ROW_COUNT;

execute immediate' select /*+monitor parallel (10)*/ count(*) from ' ||owner||'.'||table_name || '@' || l_dblink||' b '||','||
driver_table || '@' || l_dblink||' a ' ||' where ' ||mandatory_join into TOTAL_ROW_COUNT;

execute immediate' select /*+monitor parallel (10)*/ count(*) from ' ||owner||'.'||table_name || '@' || l_dblink into C_TOTAL_ROW_COUNT;

utl_file.put_line(file_handle,
                      OWNER || ',' ||
                      TABLE_NAME || ',' ||
                      TOT_OBJECT_SIZE_MB || ',' ||
                      EST_ONE_ROW_MB || ',' ||
                      TOTAL_ROW_COUNT || ',' ||
                      C_TOTAL_ROW_COUNT || ',' || /* This is actually FULL_TABLE_COUNT*/
                      (TOT_OBJECT_SIZE_MB / C_TOTAL_ROW_COUNT)|| ',' ||
                      (TOT_OBJECT_SIZE_MB / C_TOTAL_ROW_COUNT) * round(TOTAL_ROW_COUNT)
                      );


v_total_driver_only := v_total_driver_only + round(TOT_OBJECT_SIZE_MB / C_TOTAL_ROW_COUNT,7) * round(TOTAL_ROW_COUNT,0);

end loop;

UTL_FILE.PUT_LINE(file_handle, ' ');
utl_file.put_line(file_handle,
                     'Total Estimated Space Required '|| round(v_total_driver_only,0) ||' MB'
                     );

utl_file.fclose(file_handle);

end ESTIMATE_BOB01;

为帮助我了解正在发生的事情,我将所有数字值都默认设置为零,直觉和错误,似乎是在告诉我这里出了点问题:

fetch cur into OWNER,TABLE_NAME,MANDATORY_JOIN,TOT_OBJECT_SIZE_MB,EST_ONE_ROW_MB,TOTAL_ROW_COUNT,SPACE_REQUIRED;

但是我不认为这里应该依赖数据类型,只要在开始时在变量部分中正确声明了所有值并将相同的值传递给它们即可?

帮助表示赞赏。谢谢大家!

编辑:

主SQL(动态SQL)中有3个表,其中一个是DBA_TABLES,无需介绍。其他两个的结构是:

SQL> desc MV_BOB_TABLE;
 Name                                      Null?    Type
 ----------------------------------------- -------- --------------
 TARGETSCHEMA                                       VARCHAR2(200)
 PRODUCTIONSCHEMA                                   VARCHAR2(200)
 PRODUCTIONDATABASE                                 VARCHAR2(200)
 TABLE_NAME                                         VARCHAR2(200)
 DRIVER_TABLE                                       VARCHAR2(200)
 MANDATORY_JOIN                                     VARCHAR2(200)
 ADDITIONAL_JOINS                                   VARCHAR2(200)
 TABLE_COMPRESSED                                   VARCHAR2(200)
 BOB_ID                                        NOT NULL NUMBER(38)

SQL> desc <A_TABLE_THAT_CORRESPONDS_TO_v_Mv_name>;
 Name                                      Null?    Type
 ----------------------------------------- -------- -----------------
 LINK                                               CHAR(4)
 OWNER                                              VARCHAR2(90)
 SEGMENT_NAME                                       VARCHAR2(243)
 FLAG                                               CHAR(1)
 SUM_BYTES                                          NUMBER

编辑:

SUM_BYTES确实包含十进制值,例如0.375 ...等...不确定是否重要。

2 个答案:

答案 0 :(得分:2)

将您的查询与fetch语句进行比较。在您的代码中,以下列分配给这些变量:

a.owner, -> OWNER
a.table_name, -> TABLE_NAME
b.driver_table, -> MANDATORY_JOIN
b.mandatory_join, -> TOT_OBJECT_SIZE_MB -- << This does not match!
sum(c.sum_bytes) AS "TOT_OBJECT_SIZE_MB", -> EST_ONE_ROW_MB
(sum(c.sum_bytes)) / (:C_TOTAL_ROW_COUNT) AS "EST_ONE_ROW_MB", -> TOTAL_ROW_COUNT
((sum(c.sum_bytes)) / (:C_TOTAL_ROW_COUNT)) * (:TOTAL_ROW_COUNT)AS "SPACE_REQUIRED" -> SPACE_REQUIRED

答案 1 :(得分:0)

您是对的,错误已指向

fetch cur into OWNER,TABLE_NAME,MANDATORY_JOIN,TOT_OBJECT_SIZE_MB,EST_ONE_ROW_MB,TOTAL_ROW_COUNT,SPACE_REQUIRED;

但是,这正在执行查询,因此,从提供的有限信息中,我的最佳猜测将是您在计算中使用的字段之一中包含非数字字符。因此,要么c.sum_bytes要么:C_TOTAL_ROW_COUNT。

因为您可以控制:C_TOTAL_ROW_COUNT,所以我认为这种可能性较小。

我要检查的第一件事是sum_bytes的数据类型(如果不是数字(例如varchar2)),则该字段中存在非数字字符,也许有人输入了2000b,而不仅仅是2000)。

根据正在查看的记录数,您可以只看一下记录并查看有问题的数据,或者可能需要多做一些挖掘才能找到它。