【问题标题】:Oracle PL/SQL: Help resolving "PLS-00103: Encountered the symbol "LOOP" when expecting one of the following: if"Oracle PL/SQL:帮助解决“PLS-00103:在预期以下情况之一时遇到符号“LOOP”:如果”
【发布时间】:2017-10-09 18:37:13
【问题描述】:

参见第二次编辑。新编码得到不同的错误。

我收到“预期 if 时遇到循环”错误。我的目标是返回由特定 project_id 更新的表列表。 project_id 存储在每个表上标有 project_id 的列中。

我使用 with 语句创建了 2 个表。一个表 (sb_table) 是我要查看的所有表的单列。还有更多的桌子,但我认为如果我先缩小列表范围会加快速度。我正在创建的另一个表(项目)返回一个值,将提供的 prjt_name 转换为实际的项目编号(不要问我为什么,但这是我公司的设置方式,用户创建了一个 prct_name 并且从不知道项目编号)。

然后我尝试遍历这些表以查看它们的 project_id 列中是否有项目编号。如果没有,我将它们从 sb_table 中删除。

最终,我想从所有更新的表中获取所有更新的行,但我目前无法获取更新表的列表。

declare
query varchar2(10000);
table_count NUMBER;
update_count number;
prjt_name varchar2 not null := "01213264B";
cursor my_cur is select sbt.table_name from sb_table sbt;

begin

with sb_tables as (select table_name from all_tab_columns@db2 where 
                    column_name = 'PROJECT_ID' and owner = 'SANDBOX'),
    project as (select project_id from sandbox.sb_project@db2 where 
               project_name = upper(prjt_name))

--select sbt.table_name
--from sb_table sbt
    for tableName in my_cur loop

  query := 'select count(t.project_id) as "CNT" '||
                'from sandbox.' || tableName || '@db2 t, project p '||
                ' where  t.project_id = p.project_id  ';
Execute immediate query
 into update_count;

if update_count <= 0 then
     query := 'DELETE FROM sb_tables where table_name = ' || tableName;
     execute immediate query ;


end loop;
end;

编辑 1:每个 cmets,将 select 语句移到 declare 中,现在正在循环 my_cur。我仍然得到同样的错误。

编辑 2:根据建议更新了编码。我现在收到一条不同的错误消息。

NEW ERROR: ORA-06550: line 12, column 16:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 12, column 7:

编辑 3:我的子查询中缺少一个 =,这会产生错误“第 13 行缺少表达式”。

编辑 4:现在我得到了一些结果,然后出现以下错误消息

ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04040: file ext_qsp_benefit.dat in DATA_DIR not found
ORA-02063: preceding 3 lines from ADHOC_POS15
ORA-06512: at line 13

编辑 5:成功!显然我无法查询某些表。所以我把那些桌子拿出来了。

最终编码为:

declare
  query varchar2(10000);
  update_count integer := 0;
  prjt_name varchar2(100) := '01213264B';
  cursor my_cur is (select table_name from all_tab_columns@db2 where column_name = 'PROJECT_ID' and owner = 'SANDBOX' and table_name in ('X') );
  tableName  varchar2(100);
begin
  open my_cur;
    loop
    fetch my_cur into tableName;
    exit when my_cur%NOTFOUND;
        update_count := 0;
        execute immediate
        'select count(project_id) as "CNT" from sandbox.' || tableName || '@db2  '
        || ' where project_id = (select project_id from sandbox.sb_project@db2 where project_name = ''' || prjt_name || ''' ) '
        into update_count;
    if update_count > 0 then
      dbms_output.put_line (tableName);
    end if;
  end loop;
  close my_cur;
end;

这并不完全符合我的要求。它将结果发送到 dbms_output。但这是一个开始!谢谢大家的帮助!

【问题讨论】:

  • 您在select 声明右侧之前 缺少; for
  • 将您的选择放入声明部分的命名游标中(declare...cursor my_cur is select ...)然后在开始块循环中通过它(begin...for rec in my_cur LOOP。 ..)
  • 感谢 Tbone。不幸的是,这并没有解决我的问题。我仍然得到同样的错误。在原始评论中查看我的更新代码。
  • @tparker 如果这是该块的当前版本,它看起来并没有关闭它的IF。您是否尝试在 execute immediate query; 之后添加和 END IF;
  • @tbone - 我明白你现在在说什么。我没有正确执行。我已经修复它并更新了我上面的代码。

标签: oracle plsql


【解决方案1】:
DECLARE
    update_count integer := 0;
    prjt_name varchar2(100) := 'tttt';
    mysql varchar2(100);
                   tablename  varchar2(100);

    cursor my_cur is 
         select 'DUAL' 
            from dual
           where 'PROJECT_ID' = 'PROJECT_ID' and 'SANDBOX' = 'SANDBOX';

begin
    open my_cur;
    LOOP
    FETCH  my_cur into tablename;
      EXIT WHEN my_cur%NOTFOUND;
        update_count := 0;
        mysql := 'select count(*)  ' || ' from '
        || tablename
        || ' where  ''TTTT'' = upper('''
        || prjt_name
        || ''')' ;
      Execute immediate mysql INTO update_count;
        dbms_output.put_line (mysql);

  dbms_output.put_line (update_count);
  END LOOP;
CLOSE my_cur;
end;

我试过一个和你一样的。这执行成功


declare
    query varchar2(10000);
    update_count integer := 0;
    prjt_name varchar2(100) := '01213264B';
    cursor my_cur is 
           select table_name 
             from all_tab_columns@adhoc_pos15 
             where column_name = 'PROJECT_ID' and owner = 'SANDBOX';
    tableName  varchar2(100);
begin
  open my_cur;
    loop
    fetch my_cur into tableName;
    exit when my_cur%NOTFOUND;
        update_count := 0;
        query := 'select count(t.project_id) as ''CNT'' from sandbox.'
        || tableName
        || '@adhoc_pos15 t'
        || ' where  t.project_id = (select project_id from sandbox.sb_project@adhoc_pos15 where project_name = ''' || prjt_name || ''') ' ;
   execute immediate query into update_count;
     dbms_output.put_line (query);
     dbms_output.put_line (update_count);
  end loop;
close my_cur;
end;

【讨论】:

  • 非常感谢您在我的两个问题上为我提供帮助。对于这个。更新您获取和使用 dbms_output 的建议让我回到原来的错误消息。现在我回到 PLS-00103:遇到符号循环。
  • 你现在运行的是哪一个?第一个脚本中没有“end if”
  • 我收回之前说的话。这越来越接近了。我现在在第 19 行得到 SQL 命令没有正确结束。这是对 update_count 执行立即查询;
  • query := 'select count(t.project_id) as "CNT" from sandbox.' ||表名 || '@db2 t,项目 p '|| 'where t.project_id = (select project_id from sandbox.sb_project@db2 where project_name = upper(''' || prjt_name || '''))'
  • 是的!非常感谢!引号是关键。切换到获取是一个巨大的帮助。我在原始问题中发布了我的更新代码。
【解决方案2】:

我已尝试执行您的代码,但在此之前您需要更正您的 with 子句查询。以下代码已执行,除了 with 子句,请根据您的要求进行一些更改。

**code :**

declare
query varchar2(10000);
table_count NUMBER;
update_count number;
prjt_name varchar2 not null := '01213264B';

cursor my_cur is 
    select sbt.table_name from sb_table sbt;

begin
   /* with sb_tables as (select table_name from all_tab_columns@db2 where 
    column_name = 'PROJECT_ID' and owner = 'SANDBOX'),
    project as (select project_id from sandbox.sb_project@db2 where 
    project_name = upper(prjt_name))*/


for tableName in my_cur
loop
  query := 'select count(t.project_id) into '|| update_count || 'from sandbox.' || tableName || '@db2 t, project p '||' where  t.project_id = p.project_id  ';
  Execute immediate query;
--into update_count;

if update_count <= 0 then
    query := 'DELETE FROM sb_tables where table_name = ' || tableName;
    execute immediate query ;
end if;

end loop;
end;

【讨论】:

  • 如果我这样做,我仍然会得到同样的错误,但我现在也得到了额外的文本。见下文:ORA-06550:第 25 行,第 4 列:PLS-00103:在预期以下情况之一时遇到符号“IF”:. ( * @ % & = - + ; at in is mod 余数不是 rem return 返回 or != or ~= >= and or like like2 like4 likec between使用 || multiset bulk member submultiset 符号“;”被替换为“IF”以继续。
【解决方案3】:

如果您在 sql-developer 中运行,请注意,运行查询(绿色三角形)和运行脚本(白色文档上的绿色小三角形)有不同的按钮。使用“运行脚本”按钮

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2014-09-18
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多