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

时间:2019-02-02 03:05:01

标签: sql oracle plsql oracle11g dynamic-sql

下面的查询是我尝试运行的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;

上面的查询不起作用(上面的查询我的意思是EXECUTE IMMEDIATE),Oracle声明了905 missing keyword。据我所知,遵循流程here。请注意,'''是为了让我可以为'语句转义一个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;

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

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

1 个答案:

答案 0 :(得分:6)

您提供的链接用于SELECT INTO语句。使用EXECUTE IMMEDIATE选择变量时,您必须遵循EXECUTE IMMEDIATE的规则。

所以代替这个:

EXECUTE IMMEDIATE 'SELECT x FROM myTable INTO y';
                                         ^ Incorrect: INTO is inside the string

您必须这样做:

EXECUTE IMMEDIATE 'SELECT x FROM myTable' INTO y;
                                          ^ Correct: INTO is an EXECUTE IMMEDIATE keyword

您的查询将如下所示:

EXECUTE IMMEDIATE 'SELECT a, d '
  || 'FROM ' || :name || '.SPECIAL_TABLE '
  || 'WHERE name = ''' || :name || ''' AND table_name = ''' || all_tab.table_name || ''''
INTO c, d;