Oracle PL/SQL:帮助解决“PLS-00103:在预期以下情况之一时遇到符号“循环”:如果

Oracle PL/SQL:帮助解决“PLS-00103:在预期以下情况之一时遇到符号“循环”:如果,oracle,plsql,Oracle,Plsql,请参见第二次编辑。新编码会产生不同的错误 我在等待if错误时遇到了一个循环。我的目标是返回一个由特定项目id更新的表列表。项目id存储在每个表上标记为项目id的列中 我使用with语句创建了两个表。一个table sb_table是我要查看的所有表的一列。还有更多的表格,但我想如果我先缩小列表的范围,会加快进度。我正在创建的另一个表project返回一个值,将提供的prjt_名称转换为实际的项目编号。不要问我为什么,但我的公司就是这样设置的,用户创建了一个prct_名称,并且从不知道项目编号 然

请参见第二次编辑。新编码会产生不同的错误

我在等待if错误时遇到了一个循环。我的目标是返回一个由特定项目id更新的表列表。项目id存储在每个表上标记为项目id的列中

我使用with语句创建了两个表。一个table sb_table是我要查看的所有表的一列。还有更多的表格,但我想如果我先缩小列表的范围,会加快进度。我正在创建的另一个表project返回一个值,将提供的prjt_名称转换为实际的项目编号。不要问我为什么,但我的公司就是这样设置的,用户创建了一个prct_名称,并且从不知道项目编号

然后,我尝试遍历这些表,看看它们的project\u id列中是否有项目编号。如果没有,我将从sb_表中删除它们

最终,我想从所有更新的表中获取所有更新的行,但我目前一直在获取更新表的列表

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;
编辑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_输出。但这是一个开始!谢谢大家的帮助

我已经尝试了执行您的代码,但在此之前,您需要更正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;

我已经尝试过执行您的代码,但在此之前,您需要更正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;
我试过像你一样的。这将成功执行

我试过像你一样的。这将成功执行



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

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

您缺少一个脚本;在声明前的select语句中,将select放入声明部分的命名游标declare…cursor my\u cur is select。。。然后在begin block循环中通过begin…在我的cur循环中进行rec…谢谢Tbone。不幸的是,这并没有解决我的问题。我仍然会犯同样的错误。请在原始注释中查看我的更新代码。@t标记器如果这是块的当前版本,则它看起来没有关闭其If。您是否尝试添加并结束IF;就在执行即时查询的行之后@我明白你现在说的话了。我没有正确地执行。我已经修复并更新了上面的代码;在声明前的select语句中,将select放入声明部分的命名游标declare…cursor my\u cur is select。。。然后在begin block循环中通过begin…在我的cur循环中进行rec…谢谢Tbone。不幸的是,这并没有解决我的问题。我仍然会犯同样的错误。请在原始注释中查看我的更新代码。@t标记器如果这是块的当前版本,则它看起来没有关闭其If。您是否尝试添加并结束IF;就在执行即时查询的行之后@我明白你现在说的话了。我没有正确地执行。我已经修复并更新了上面的代码。如果我这样做,我仍然会得到相同的错误,但我现在也会得到额外的文本。请参见以下内容:ORA-06550:第25行第4列:PLS-00103:在预期以下情况时遇到符号:.*@%&=-+;at in是mod剩余值不是rem返回值还是!=或者~=>=如果我这样做,我仍然会得到相同的错误,但我现在也会得到额外的文本。请参见以下内容:ORA-06550:第25行第4列:PLS-00103:在预期以下情况时遇到符号:.*@%&=-+;at in是mod剩余值不是rem返回值还是!=或者~=>=我真的很感谢你在这两个问题上帮助我。为了这个。更新您关于获取和使用dbms_输出的建议会使我返回到原始错误消息。现在我回到PLS-00103:遇到符号循环。您现在运行的是哪一个?在你的第一个剧本中没有“如果结束”我收回了我之前说过的话。就快到了。我现在发现SQL命令在第19行没有正确结束。即执行即时查询到update_count;查询:='选择公司
untt.project_id作为来自sandbox的CNT。“| | tableName | |”@db2t,project p'| |”,其中t.project_id=从sandbox.sb中选择project_id_project@db2其中project|u name=upper'|| prjt|u name |是!非常感谢你!这件事很关键。转向抓取是一个巨大的帮助。我在原始问题中发布了我的更新代码。我非常感谢你在这两个问题上帮助我。为了这个。更新您关于获取和使用dbms_输出的建议会使我返回到原始错误消息。现在我回到PLS-00103:遇到符号循环。您现在运行的是哪一个?在你的第一个剧本中没有“如果结束”我收回了我之前说过的话。就快到了。我现在发现SQL命令在第19行没有正确结束。即执行即时查询到update_count;query:=“选择countt.project_id作为来自sandbox的CNT。”| | tableName | |“@db2 t,project p'| |”,其中t.project_id=从sandbox.sb中选择项目_id_project@db2其中project|u name=upper'|| prjt|u name |是!非常感谢你!这件事很关键。转向抓取是一个巨大的帮助。我在原始问题中发布了我的更新代码。
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;