EXECUTE IMMEDIATE SELECT INTO语句中缺少关键字 - Oracle PL/SQL

Tho*_*ind 1 sql oracle plsql dynamic-sql oracle11g

下面的查询是我试图运行的PL/SQL的简化版本,它只显示了一般结构.简而言之,我试图从SPECIAL_TABLE变量中提取信息c, d.

DECLARE
  c NUMBER;
  d NUMBER;
BEGIN
  FOR all_tab IN
  (SELECT * FROM all_tables)
  LOOP
    BEGIN
      EXECUTE IMMEDIATE 'SELECT a, d INTO c, d
      FROM ' || :name || '.SPECIAL_TABLE WHERE name = '''
      :name || ''' AND table_name = ''' || all_tab.table_name || ''';

    ...

    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('ERROR OCCURRED');
    END;
END;
Run Code Online (Sandbox Code Playgroud)

上面的查询不起作用(通过上面的查询我的意思是EXECUTE IMMEDIATE),而Oracle声明905 missing keyword.据我所知,遵循这里的流程.注意,'''这样我可以'SELECT语句转义单个,然后一起完成整个字符串.有什么奇怪的,我可以按照下面的代码进行操作,没有错误:

DECLARE
  c NUMBER;
  d NUMBER;
BEGIN
  FOR all_tab IN
  (SELECT * FROM all_tables)
  LOOP
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*)
      FROM ' || :name || '.SPECIAL_TABLE WHERE name = '''
      :name || ''' AND table_name = ''' || all_tab.table_name || ''' INTO c;

    ...

    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('ERROR OCCURRED');
    END;
END;
Run Code Online (Sandbox Code Playgroud)

唯一改变的是我正在使用MAX(...),并且似乎不再遵循上述超链接中的指定语法.我不确定语法部分以及为什么这样做有效,并且MAX(...)确保只返回一行.看起来这可能是问题的根源,但是当我自己执行SELECT查询时,它只返回指定了两列的单行.该表的主键是PRIMARY KEY (a, b)这样,它不应该返回多行.

我在这里缺少什么,如何让我的初始语句将查询结果分配给Oracle 11g中的多个变量?

Ed *_*bbs 6

您提供的链接用于SELECT INTO声明.使用EXECUTE IMMEDIATEEXECUTE IMMEDIATE规则进行变量选择时,必须按照EXECUTE IMMEDIATE的规则进行操作.

所以不是这样的:

EXECUTE IMMEDIATE 'SELECT x FROM myTable INTO y';
                                         ^ Incorrect: INTO is inside the string
Run Code Online (Sandbox Code Playgroud)

你必须这样做:

EXECUTE IMMEDIATE 'SELECT x FROM myTable' INTO y;
                                          ^ Correct: INTO is an EXECUTE IMMEDIATE keyword
Run Code Online (Sandbox Code Playgroud)

您的查询将是这样的:

EXECUTE IMMEDIATE 'SELECT a, d '
  || 'FROM ' || :name || '.SPECIAL_TABLE '
  || 'WHERE name = ''' || :name || ''' AND table_name = ''' || all_tab.table_name || ''''
INTO c, d;
Run Code Online (Sandbox Code Playgroud)