我刚刚开始学习PL/SQL.在stackoverflow中发布帖子后,我编写了一个脚本来搜索Oracle中的某个值,如下所示:
DECLARE
match_count INTEGER;
v_owner VARCHAR2(255);
v_search_value NUMBER;
BEGIN
v_owner:='USERA USERB';
v_search_value:=4823.0;
EXECUTE IMMEDIATE
'INSERT INTO TMP SELECT owner, table_name, column_name FROM all_tab_cols WHERE instr(:1, owner)>0 AND data_type like ''%NUMBER%''' USING v_owner;
commit;
FOR t IN (SELECT owner, table_name, column_name FROM TMP) LOOP
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM '||t.owner||'.'||t.table_name||' WHERE '||t.column_name||'= :1'
INTO match_count
USING v_search_value;
IF match_count > 0 THEN
EXECUTE IMMEDIATE
'INSERT INTO RESULT VALUES(:1, :2, :3, :4)'
USING t.owner, t.table_name, t.column_name, match_count;
commit;
END IF;
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
在执行脚本之前已正确创建表TMP和RESULT.但是,当我运行脚本时,我收到一个ORA-01788错误,说第12行说"需要连接by子句".我想知道为什么代码会导致此错误以及如何更改脚本以便正确执行.谢谢!
你可能有一个带有一个列的表level(正如Florin在我不看时所建议的那样),这是一个保留字.
它可能在任何情况下 - 不只是level,但是LEVEL,或Level- 所以检查你可以这样做:
select owner, table_name, column_name
from all_tab_columns
where upper(column_name) = 'LEVEL';
Run Code Online (Sandbox Code Playgroud)
或者查找正在使用的任何保留字(尽管这并不总能找到所有潜在的问题):
select atc.owner, atc.table_name, atc.column_name, vrw.keyword
from all_tab_columns atc
join v$reserved_words vrw on vrw.keyword = upper(atc.column_name);
Run Code Online (Sandbox Code Playgroud)
您可以对其他地方运行类似的查询all_tables或all_objects查找潜在问题.
如果我运行您的查询的修改版本而不打扰TMP表 - 不知道为什么你想要那个; 不使用动态SQL进行插入; 不提交(这在块中是一件奇怪的事情 - 你不需要在每次插入后都这样做); 只是为了我的利益只显示匹配而不是需要构建results表:
declare
match_count integer;
v_owner varchar2(255);
v_search_value number;
begin
v_owner := 'USERA USERB';
v_search_value := 4823.0;
for t in (
select owner, table_name, column_name
from all_tab_cols
where instr(v_owner, owner) > 0
and data_type like '%NUMBER%'
) loop
execute immediate
'select count(*) from ' || t.owner ||'.'|| t.table_name
|| ' where ' || t.column_name || ' = :1'
into match_count using v_search_value;
if match_count > 0 then
-- insert into results values (t.owner, t.table_name,
-- t.column_name, match_count);
dbms_output.put_line('Matched ' || t.owner ||'.'|| t.table_name
||'.'|| t.column_name ||': '|| match_count);
end if;
end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)
......这成功完成了.如果我添加一个包含level列的表:
create table t42 ("LEVEL" number);
Run Code Online (Sandbox Code Playgroud)
...然后再次运行相同的块然后我也得到:
ORA-01788: CONNECT BY clause required in this query block
ORA-06512: at line 14
01788. 00000 - "CONNECT BY clause required in this query block"
*Cause:
*Action:
Run Code Online (Sandbox Code Playgroud)
除了避免在对象名称中保留单词之外,您可以通过将所有对象名称括在双引号中来完成此工作:
execute immediate
'select count(*) from "' || t.owner ||'"."'|| t.table_name
|| '" where "' || t.column_name || '" = :1'
into match_count using v_search_value;
Run Code Online (Sandbox Code Playgroud)
这也将处理混合大小写的对象名称,您也应该避免使用它们.
| 归档时间: |
|
| 查看次数: |
7167 次 |
| 最近记录: |