【问题标题】:Insert into select to remote database using DB_link使用 DB_link 插入选择到远程数据库
【发布时间】:2022-01-22 18:33:30
【问题描述】:

我正在尝试使用 DB_LINKS 更新远程数据库表,但出现错误

SQL Error: ORA-00907: missing right parenthesis
00907. 00000 -  "missing right parenthesis"
*Cause:    
*Action:

案例场景-

  1. 来自本地数据库 - 以 sysdba 身份连接

    sqlplus / as sysdba
    
  2. 使用从本地数据库获取的值更新远程数据库

    INSERT INTO username.D_BackupStatus@db_link_name
    (SELECT    ''''
        || (SELECT DECODE (db_unique_name, NULL, name, db_unique_name)
              FROM v$database)
        || ''','''
        || TO_CHAR (START_TIME, 'dd-mon-rr hh24:mi:ss')
        || ''','''
        || TO_CHAR (END_TIME, 'dd-mon-rr hh24:mi:ss')
        || ''','''
        || time_taken_display
        || ''','''
        || TRIM (STATUS)
        || ''','''
        || INPUT_TYPE
        || ''','''
        || DECODE (TO_CHAR (start_time, 'd'),
                   1, 'Sunday',
                   2, 'Monday',
                   3, 'Tuesday',
                   4, 'Wednesday',
                   5, 'Thursday',
                   6, 'Friday',
                   7, 'Saturday')
        || ''','''
        || (SELECT host_name FROM v$instance)
        || ''''
    FROM V$RMAN_BACKUP_JOB_DETAILS
    WHERE     TO_DATE (TO_CHAR (START_TIME, 'dd-mon-rr'), 'dd-mon-rr') >=
            TO_DATE (TO_CHAR (SYSDATE - 6, 'dd-mon-rr'), 'dd-mon-rr')
        AND input_type IN
               ('DB FULL', 'DB INCR')                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
               order      by   START_TIME);
    

输出

Error starting at line : 1 in command -
insert into username.D_BackupStatus@db_link_name 
(select '''' ||
(select decode(db_unique_name,NULL,name,db_unique_name) from v$database)||''','''||
to_char(START_TIME,'dd-mon-rr hh24:mi:ss') || ''','''||to_char(END_TIME,'dd-mon-rr hh24:mi:ss') 
|| ''',''' || time_taken_display|| ''',''' ||trim(STATUS) || ''',''' || INPUT_TYPE||''','''
||decode(to_char(start_time, 'd'), 1, 'Sunday', 2, 'Monday',3, 'Tuesday', 4, 'Wednesday',5, 'Thursday', 6,
'Friday',7, 'Saturday')||''','''||(select host_name from v$instance) ||''''
from V$RMAN_BACKUP_JOB_DETAILS
where to_date(to_char(START_TIME,'dd-mon-rr'),'dd-mon-rr')>=to_date(to_char(sysdate-6,'dd-mon-rr'),'dd-mon-rr')
and input_type in ('DB FULL','DB INCR')
order by START_TIME)

Error at Command Line : 11 Column : 1
Error report -
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 -  "missing right parenthesis"
*Cause:    
*Action:

谁能帮我查询一下,有什么问题吗??

【问题讨论】:

  • SELECT 部分是否独立工作?
  • 顺便说一下,to_char()'d' 格式掩码众所周知地依赖于 NLS_TERRITORY,因此例如,您的解码表达式在此处给出星期一(西欧),在北美给出周二,在大部分时间给出周三中东(见DBFiddle)。无论如何,已经有一个格式掩码:to_char(start_time, 'fmDay', 'nls_language=English')
  • 另外,to_date(to_char(start_time, 'DD-MON-RR'), 'DD-MON-RR') 是一个定时炸弹 - 尝试使用 2050 年的日期。改为使用 trunc(start_time)
  • 您为什么要尝试将所有选定的列连接成一个字符串?目标表没有匹配的列吗?为什么,在您的 WHERE 子句中,您要将 DATE 类型(sysdate 和 - 大概 - start_time)转换为字符串,只是为了将它们转换回 DATE?为什么要使用“RR”日期掩码重新创建 Y2k 问题?
  • @WilliamRobertson 是的,选择部分本身工作正常。该项目是一个全球项目,我们在所有服务器上都有标准时间格式,仅适用于 CET 时区。所以这不包括从解码表达式中获取不同的值。现在,我也在使用 trunc(start_time)

标签: sql oracle ora-00907


【解决方案1】:

从子查询中删除ORDER BY 子句;在那种情况下它是无效的

       AND input_type IN ('DB FULL', 'DB INCR')
       -- ORDER BY start_time
                                               );

不知道接下来会发生什么,除了您本可以使用 q-quoting 机制并避免使用那么多单引号这一事实。

【讨论】:

  • 删除 order by 子句后。我收到一个新错误。错误报告 - SQL 错误:ORA-00947:没有足够的值
    00947. 00000 - “没有足够的值”
    *原因:
    *操作:
  • 它不是子查询,只是一个常规的 INSERT-SELECT,由于某种原因在 SELECT 周围有括号。
  • “没有足够的值”,@Ravi,意味着您应该指定所有列名(在 INSERT 中),然后必须匹配 SELECT 返回的所有列名。
  • 在阅读了上述所有建议后,我做了一些更改并开始遇到 oracle 错误/错误 - ORA-2070 在远程插入数据库链接期间从本地字典视图(文档 ID 744219.1) 最终编写了文档 id 中提到的 PL/Sql 游标代码,现在它可以按要求工作了。
猜你喜欢
  • 1970-01-01
  • 2013-12-25
  • 2018-02-10
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2019-04-12
相关资源
最近更新 更多