【问题标题】:Missing Keyword in EXECUTE IMMEDIATE SELECT INTO Statement - Oracle PL/SQLEXECUTE IMMEDIATE SELECT INTO 语句中缺少关键字 - Oracle PL/SQL
【发布时间】:2019-06-26 15:02:38
【问题描述】:

下面的查询是我尝试运行的 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 中的多个变量?

【问题讨论】:

  • 在执行即时查询时,禁止使用INTO。它只能出现在字符串之后:EX IM 'SELECT a,d FROM...' INTO c ,b

标签: sql oracle plsql oracle11g dynamic-sql


【解决方案1】:

您提供的链接用于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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2021-11-20
    • 2021-04-15
    • 2020-01-27
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 2015-04-17
    相关资源
    最近更新 更多