首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以使用dblink进行选择,不能使用dblink插入

可以使用dblink进行选择,不能使用dblink插入
EN

Stack Overflow用户
提问于 2016-04-27 15:44:01
回答 1查看 1.7K关注 0票数 0

我继承了一个代码,它帮助我从外部系统获取数据。它有点搞砸了,但我必须按原样使用。

代码语言:javascript
复制
   SELECT NVL (
                (
                  SELECT TRIM (alias.SERV_CD)
                   FROM schema.CX_SER@db_link alias
                  WHERE     row_id =
                                          (
                                           SELECT mix.par_row_id
                                              FROM schema.CX_SER_MI_XM@db_link mix
                                             WHERE     mix.bill = SA.BILL_AC
                                          AND ROWNUM < 2
                                          )
                        AND ROWNUM < 2
                        ),
                (
                    SELECT TRIM (ba.SERV_CD)
                     FROM schema.s_some_table@db_link ba
                     WHERE ba.row_id = sa.BILL_AC AND ROWNUM < 2
                )
            ) REQUIRED_CODE,                   --NVL ends here
             COUNT (*) order_count,
             TRUNC (ia.CREATED_DATE) CREATED_DATE_date,
             TRUNC (ia.CREATED_DATE + 1) inserted_date
        FROM schema.s_some_table@db_link sa, schema.action_table@db_link ia, schema.s_order@db_link ord
       WHERE     ia.CREATED_DATE >= TRUNC (SYSDATE - 1)
             AND ia.CREATED_DATE < TRUNC (SYSDATE)
             AND ord.status = 'Done'
    GROUP BY SA.BILL_AC, TRUNC (ia.CREATED_DATE), TRUNC (IA.CREATED_DATE + 1); 

当我按原样运行select时,上述代码将返回结果。但是,当我尝试在我的模式中插入这些记录时(使用简单的insert into(columns) <this select statement>,我得到以下错误消息:

  1. 错误: ORA-00904:"SA"."BILL_ACC“:无效标识符.Ora-02063:来自db_link的前一行。

select语句,如:

代码语言:javascript
复制
  with c as(
      SELECT NVL (
                    (
                      SELECT TRIM (alias.SERV_CD)
                       FROM schema.CX_SER@db_link alias
                      WHERE     row_id =
                                              (
                                               SELECT mix.par_row_id
                                                  FROM schema.CX_SER_MI_XM@db_link mix
                                                 WHERE     mix.bill = SA.BILL_AC
                                              AND ROWNUM < 2
                                              )
                            AND ROWNUM < 2
                            ),
                    (
                        SELECT TRIM (ba.SERV_CD)
                         FROM schema.s_some_table@db_link ba
                         WHERE ba.row_id = sa.BILL_AC AND ROWNUM < 2
                    )
                ) REQUIRED_CODE,                   --NVL ends here
                 COUNT (*) order_count,
                 TRUNC (ia.CREATED_DATE) CREATED_DATE_date,
                 TRUNC (ia.CREATED_DATE + 1) inserted_date
            FROM schema.s_some_table@db_link sa, schema.action_table@db_link ia, schema.s_order@db_link ord
           WHERE     ia.CREATED_DATE >= TRUNC (SYSDATE - 1)
                 AND ia.CREATED_DATE < TRUNC (SYSDATE)
                 AND ord.status = 'Done'
        GROUP BY SA.BILL_AC, TRUNC (ia.CREATED_DATE), TRUNC (IA.CREATED_DATE + 1)) 
    select * from c where REQUIRED_CODE IS NOT NULL; 

也以相同的错误失败。但是,当我使用上述with子句语句中的其他列进行查询时,我能够获得结果,例如,where order_count>2 给出结果。所以问题是在REQUIRED_CODE部分,也许,在组中。

请指导行动方针。我需要插入流到我的架构中的记录。

注意事项:所有列都是varchar2或date

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-27 17:35:54

如果我复制该问题的尝试接近于您的问题,则可以通过添加 hint来避免CTE中的错误。

代码语言:javascript
复制
with c as (
   SELECT /*+ DRIVING_SITE (sa) */ NVL (
...

这样可以防止查询以混淆优化器的方式编写和分发;我认为它被子查询中对SA的嵌套引用绊倒了,最终导致太多的级别下降,无法识别。

不过,这个提示对插入没有任何影响。

正如注释中提到的,为了避免子查询,我已经快速地重写了查询。这有点粗糙,我不确定我是否理解你目前正在做的一切,部分原因是表名的更改等等。但是你想看到它,它可能会给你一些工作。

代码语言:javascript
复制
   INSERT INTO t42
  SELECT NVL (TRIM(MIN(t.SERV_CD) KEEP (DENSE_RANK FIRST ORDER BY NULL)),
           TRIM(MIN(ba.SERV_CD) KEEP (DENSE_RANK FIRST ORDER BY NULL))
         ) REQUIRED_CODE,  --NVL ends here
         COUNT (*) order_count,
         TRUNC (ia.CREATED_DATE) CREATED_DATE_date,
         TRUNC (ia.CREATED_DATE + 1) inserted_date
    FROM schema.s_some_table@db_link sa
    LEFT JOIN (
      SELECT mix.bill, alias.SERV_CD
        FROM schema.CX_SER_MI_XM@db_link mix
        JOIN schema.CX_SER@db_link alias
          ON alias.row_id = mix.par_row_id
      ) t
      ON t.bill = SA.BILL_ACC
    LEFT JOIN schema.s_some_table@db_link ba
      ON ba.row_id = sa.BILL_ACC
    CROSS JOIN schema.action_table@db_link ia
    CROSS JOIN schema.s_order@db_link ord
   WHERE     ia.CREATED_DATE >= TRUNC (SYSDATE - 1)
         AND ia.CREATED_DATE < TRUNC (SYSDATE)
         AND ord.status = 'Done'
GROUP BY SA.BILL_ACC, TRUNC (ia.CREATED_DATE), TRUNC (IA.CREATED_DATE + 1);

如果无法使其工作,那么您可以使用PL/SQL块中的原始查询,或者作为游标并逐行插入,或者最好(特别是如果它将返回大量数据)使用带有bulk collectforall插入的集合。

如果您搜索我对ORA-02063和ORA-00904的Oracle支持,您将看到相当多的bug,其中一些似乎适用于11g,但应该已经被我的11.2.0.4版本修复了;快速浏览没有发现任何匹配的地方,但可能您正在访问其中的一个,或者确实是一个还没有报告的错误。可能值得提出一个SR来调查您的具体情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36894664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档