sql - SQL 适用于 for 循环,但不适用于动态 sql,您能帮我找出原因吗?
问题描述
不是重复的,谢谢
我正在尝试重写一些 sql 以使用动态 SQL。仅使用游标循环的版本返回值。我已尽我所能切换它,但始终出现以下错误:
ORA-00904: "TOTAL_ROW_COUNT": invalid identifier
这按预期工作,返回 dbms_output:
SET SERVEROUTPUT ON;
SET TIMING ON;
DECLARE
--variables
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);
TOTAL_ROW_COUNT NUMBER;
TOT_OBJECT_SIZE_MB NUMBER;
FULL_TABLE_COUNT NUMBER;
EST_ONE_ROW_MB NUMBER;
C_TOTAL_ROW_COUNT NUMBER;
SPACE_REQUIRED NUMBER;
v_total_driver_only NUMBER := 0;
v_total_add_joins NUMBER := 0;
v_unjoined_all NUMBER := 0;
v_complete_space_req NUMBER := 0;
--NEW VARIABLES FOR DYN-SQL:
v_sql VARCHAR2 (1100);
cur SYS_REFCURSOR;
owner VARCHAR2 (100);
table_name VARCHAR2 (100);
BEGIN
SELECT tablename
INTO v_csv_name
FROM table_tracker
WHERE CREATED_AT = (SELECT MAX (CREATED_AT) FROM table_tracker);
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 BOB1.MV_PDU_TABLE;
v_sql :=
'SELECT /*+ monitor parallel (4)*/ a.owner,
a.table_name,
b.driver_table,
b.mandatory_join,
sum(c.sum_bytes) TOT_OBJECT_SIZE_MB,
trunc(TOT_OBJECT_SIZE_MB / FULL_TABLE_COUNT,7) EST_ONE_ROW_MB,
(EST_ONE_ROW_MB * TOTAL_ROW_COUNT) SPACE_REQUIRED
FROM dba_tables@DB1 a, MV_PDU_TABLE b, MV_PRD_SEG_DATA c
WHERE a.table_name IN ( SELECT table_name
FROM MV_PDU_TABLE
WHERE driver_table IS NOT NULL
AND additional_joins IS NULL
)
AND a.owner IN ( SELECT DISTINCT productionschema FROM MV_PDU_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';
--main loop
OPEN cur FOR v_sql;
LOOP
FETCH cur INTO OWNER, TABLE_NAME;
EXIT WHEN cur%NOTFOUND;
EXECUTE IMMEDIATE
' select /*+parallel (10)*/ count(*) from '
|| owner
|| '.'
|| table_name
|| '@'
|| dblink
INTO TOTAL_ROW_COUNT;
EXECUTE IMMEDIATE
' select /*+monitor parallel (10)*/ count(*) from '
|| owner
|| '.'
|| table_name
|| '@'
|| dblink
INTO C_TOTAL_ROW_COUNT;
END LOOP;
DBMS_OUTPUT.put_line (TOTAL_ROW_COUNT);
DBMS_OUTPUT.put_line (C_TOTAL_ROW_COUNT);
END;
/
这是我收到以下错误的时候:
ERROR at line 1:
ORA-00904: "TOTAL_ROW_COUNT": invalid identifier
ORA-06512: at line 63
它似乎以与 for 循环不同的方式处理某些列别名,也许这就是问题所在,但我不能完全指出什么是错误的或如何正确重写它
--
在进行其他查询之后,代码现在已更改,我正在逐个删除它,最终得到:
ERROR at line 1:
ORA-00932: 不一致的数据类型: 预期 - 得到 -
这是我根据用户“APC”的要求发布的当前代码
declare
--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);
--ROW_COUNT NUMBER;
TOTAL_ROW_COUNT varchar2(100);
TOT_OBJECT_SIZE_MB NUMBER;
--FULL_TABLE_COUNT NUMBER;
--EST_ONE_ROW_MB NUMBER;
--C_TOTAL_ROW_COUNT NUMBER;
--SPACE_REQUIRED NUMBER;
--v_total_driver_only NUMBER := 0;
--v_total_add_joins NUMBER := 0;
--v_all_tabs NUMBER := 0;
--v_unjoined_all NUMBER := 0;
--v_complete_space_req 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);
--
--
begin
SELECT tablename into v_csv_name
FROM table_tracker
WHERE
CREATED_AT = (select MAX(CREATED_AT) from table_tracker);
SELECT mv_name into v_Mv_name
FROM table_tracker_mv
WHERE
CREATED_AT = (select MAX(CREATED_AT) from 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 pdu01.MV_PDU_TABLE;
v_sql1 := 'SELECT /*+ monitor parallel (4)*/ a.owner,
a.table_name,
b.driver_table,
b.mandatory_join,
sum(c.sum_bytes) TOT_OBJECT_SIZE_MB
--trunc(TOT_OBJECT_SIZE_MB / FULL_TABLE_COUNT,7) EST_ONE_ROW_MB
--trunc(TOT_OBJECT_SIZE_MB) EST_ONE_ROW_MB
--(EST_ONE_ROW_MB * :TOTAL_ROW_COUNT)
FROM dba_tables@DB1 a, MV_PDU_TABLE b, MV_PRD_SEG_DATA c
WHERE a.table_name IN ( SELECT table_name
FROM MV_PDU_TABLE
WHERE driver_table IS NOT NULL
AND additional_joins IS NULL
)
AND a.owner IN ( SELECT DISTINCT productionschema FROM MV_PDU_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 PDU document:');
--UTL_FILE.PUT_LINE(file_handle, ' ');
--utl_file.put_line(file_handle, 'OWNER,TABLE_NAME,TOT_OBJECT_SIZE_MB,TOTAL_ROW_COUNT,EST_ONE_ROW_MB');
--main loop
open cur for v_sql1;
loop
fetch cur into OWNER;--,TABLE_NAME;--,TOT_OBJECT_SIZE_MB;--,EST_ONE_ROW_MB;
--exit when cur%NOTFOUND;
-- execute immediate' select /*+parallel (4)*/ count(*) from '||owner||'.'||table_name || '@' || l_dblink into TOTAL_ROW_COUNT;
--utl_file.put_line(file_handle,
-- OWNER || ',' ||
-- TABLE_NAME || ',' ||
-- TOT_OBJECT_SIZE_MB || ',' ||
-- TOTAL_ROW_COUNT || ',' ||
-- round(TOT_OBJECT_SIZE_MB / TOTAL_ROW_COUNT,5)
-- );
--v_unjoined_all := v_unjoined_all + TOT_OBJECT_SIZE_MB;
end loop;
--UTL_FILE.PUT_LINE(file_handle, ' ');
--utl_file.put_line(file_handle,
-- 'Total estimated space required for your unjoined tables '|| round(v_unjoined_all,0) ||' MB'
--);
close cur;
--
--
--utl_file.fclose(file_handle);
end;
/
解决方案
该变量TOTAL_ROW_COUNT
只存在于PL/SQL上下文中,除非传入,否则SQL语句是看不到的。
要使代码正常工作,请更改:
(EST_ONE_ROW_MB * TOTAL_ROW_COUNT) SPACE_REQUIRED
至:
(EST_ONE_ROW_MB * :TOTAL_ROW_COUNT) SPACE_REQUIRED
然后改变:
open cur for v_sql;
至:
open cur for v_sql using TOTAL_ROW_COUNT;
但是我有一种感觉,它只会修复语法错误并创建一个新的错误。 TOTAL_ROW_COUNT
在填充之前正在使用。也许您的意思是改用该列NUM_ROWS
?
推荐阅读
- c# - Akamai Rest Api 如何从 Asp.net Core HttpClient 调用
- javascript - 目标高度未知(不固定)时如何实现元素高度过渡
- python - View Docker Swarm CMD Line Output
- css - 当存在太多列的水平滚动垫表时,左粘性列消失
- apache-superset - Apache Superset - 交互式标记不起作用/ javascript 被超集忽略
- onload - 使用浏览器后退按钮时如何禁用正文加载
- css - 如何让 div 表格单元格中包含的 div 填充?
- reactjs - React .map 不是函数但不能传递数组
- python-3.x - Space Invaders bug pygame
- python - Pandas:选择具有列数据类型的行