PL/SQL 在插入语句的子查询中使用别名和函数

Posted

技术标签:

【中文标题】PL/SQL 在插入语句的子查询中使用别名和函数【英文标题】:PL/SQL Using aliases and functions in the subquery of an insert statement 【发布时间】:2013-05-15 09:52:53 【问题描述】:

我对 PL/SQL 很陌生,但我想知道是否有办法实现以下目标:

   INSERT  INTO aTable (
   SELECT  FN_TO_VALUE(b.field1, b.field2, b.field3) as alias1,
           FN_TO_VALUE(b.field1, b.field2, b.field3) as alias2,
           FN_TO_VALUE(b.field1, b.field2, b.field3) as alias3,
           c.field1, c.field2
   FROM    bTable b, cTable c
   WHERE   b.alias1= c.field3
   );

鉴于 FN_TO_VALUE 是一个函数,它返回 aTable 中的相应数据类型。

我收到以下错误声明:

PL/SQL : SQL Statement ignored (that's located at the INSERT INTO line)
PL/SQL : ORA-00904: "B"."ALIAS1" invalid identifier

勘误表:

我不得不将 where 子句从 WHERE b.alias1= c.field1 修改为 WHERE b.alias1= c.field3,因为 @ 提供的解决方案之一Bob Jarvis 不会考虑链接表 bTable 和 cTable 可能需要的其他字段。

解决方案:

我选择了以下解决方案:

 INSERT  INTO aTable (
   SELECT b.alias1,
          b.alias2,
          b.alias3,
          c.field1,
          c.field2
   FROM cTable c, 
   (
     SELECT FN_TO_VALUE (field1, field2, field3) AS alias1,
            FN_TO_VALUE (field1, field2, field3) AS alias2,
            FN_TO_VALUE (field1, field2, field3) AS alias3
     FROM bTable 
   ) b
   WHERE b.alias1 = c.field3
);

【问题讨论】:

您要么必须使用子选择(使该别名成为 WHERE 子句列)或 WHERE FN_TO_VALUE(b.field1, b.field2, b.field3) = c.field1 而不是 WHERE b.alias1= c.field1 【参考方案1】:
INSERT  INTO aTable (
SELECT inner.alias1,
       inner.alias2,
       inner.alias3,
       inner.field1,
       inner.field2
  FROM (SELECT FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias1,
               FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias2,
               FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias3,
               c.field1,
               c.field2
          FROM bTable b, cTable c
         ) inner
 WHERE inner.alias1 = inner.field1
)

INSERT  INTO aTable (
SELECT FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias1,
       FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias2,
       FN_TO_VALUE (b.field1, b.field2, b.field3) AS alias3,
       c.field1,
       c.field2
  FROM bTable b, cTable c
 WHERE FN_TO_VALUE (b.field1, b.field2, b.field3) = c.field1
   );

【讨论】:

在第一个示例中,在我看来应该从内部 SELECT 中删除 WHERE 子句,因为 b 仍然没有名为 alias1 的字段(据我所知在这个人为的例子中)。第二个看起来应该可以工作,尽管 WHERE 子句中的函数调用让我感到紧张。 @BobJarvis:是的,谢谢你纠正我的第一个例子,甚至我也不建议第二个例子,每行调用两次函数不是一个好习惯。 关于第一个示例,我还没有测试过代码,但在我看来,连接发生在子选择子句之后,即:inner WHERE inner.alias1 = iner.field1 之后是合乎逻辑的吗?我的意思是......我从来没有以这种方式使用过 INNER,除了 INNER JOINs @dfive:inner 是内联视图的别名,如果我们在这个查询中使用两个内联视图并且都有列列,那么告诉 oracle 哪个列来自哪个视图,我们需要给出不同的名称.它就像表别名,不要与KEYWORD INNER混淆 @BobJarvis,我只是想知道那个 INNER 技巧,它叫什么,我在哪里可以找到有关它的文档?据我所知,inner 被视为关键字......还是您只是使用 inner 作为别名?

以上是关于PL/SQL 在插入语句的子查询中使用别名和函数的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 中的子查询返回 NO_DATA_FOUND

pl/sql 块中的子选择上的 Oracle 8i 动态 SQL 错误

Oracle-视图,约束

错误(12,1):PL/SQL:语句被忽略错误(12,15):PLS-00405:在此上下文中不允许子查询

PL/SQL查询,字段名添加中文别名,查询结果的字段名会显示问号,处理方法:

在SQL Server的子查询视图内联函数等数据库对象中,不应该单独使用ORDER BY语句