ORA-02020 too many database links in use重现

本文探讨了在数据库连接管理中遇到的ORA-2020错误,详细介绍了OPEN_LINKS和OPEN_LINKS_PER_INSTANCE参数的作用及调整方法,并通过实验展示了如何通过修改参数值来解决数据库连接数限制的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   在A库上建DB_link,更新B库。报ORA-2020 too many database links in use,是要设置OPEN_LINKS和OPEN_LINKS_PER_INSTANCE两个参数,它们的默认值都是4。
alter system set open_links=200 scope=both;
alter system set open_links_per_instance=200 scope=both;
问题来了,是修改A库中的参数还是B库,是修改A库的。
修改这类参数数据库要重启。

ORA-02020: too many database links in use
Cause: The current session has exceeded the INIT.ORA open_links maximum.
Action: Increase the open_links limit, or free up some open links by committing or rolling back the transaction and canceling open cursors that reference remote databases.
  
        
OPEN_LINKS specifies the maximum number of concurrent open connections to remote databases in one session.

OPEN_LINKS_PER_INSTANCE specifies the maximum number of migratable open connections globally for each database instance.

OPEN_LINKS_PER_INSTANCE is different from OPEN_LINKS, which indicates the number of connections from a session. The OPEN_LINKS parameter is not applicable to XA applications.

OPEN_LINKS_PER_INSTANCE跟OPEN_LINKS的区别是,前者是对于XA事务的。


做个试验重现一下:

在A库上:
SQL> show parameter open_link
NAME                          TYPE        VALUE
----------------------------- ----------- --------
open_links                    integer      4
open_links_per_instance       integer      4

create database link DBLINK_1
  connect to TEST IDENTIFIED BY test
  using '(DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.15.150)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = orcl)
    )
  )';
--按照同种方式建5个dblink  

SQL> set serveroutput on
SQL>  declare
  2       v_i number;
  3       v_sql varchar(500);
  4    begin
  5      for i in 1..5
  6       loop
  7        v_sql:='select count(*) from dual@DBLINK_'||i;
  8        execute immediate v_sql into v_i;
  9        dbms_output.put_line('DBLINK_'||i);
 10        commit;
 11       end loop;
 12    end;
 13  /
 
DBLINK_1
DBLINK_2
DBLINK_3
DBLINK_4
DBLINK_5
 
PL/SQL procedure successfully completed
 
SQL> 
SQL>  declare
  2       v_i number;
  3       v_sql varchar(500);
  4    begin
  5      for i in 1..5
  6       loop
  7        v_sql:='select count(*) from dual@DBLINK_'||i;
  8        execute immediate v_sql into v_i;
  9        dbms_output.put_line('DBLINK_'||i);
 10        --commit;
 11       end loop;
 12    end;
 13  /
 
DBLINK_1
DBLINK_2
DBLINK_3
DBLINK_4
 
declare
     v_i number;
     v_sql varchar(500);
  begin
    for i in 1..5
     loop
      v_sql:='select count(*) from dual@DBLINK_'||i;
      execute immediate v_sql into v_i;
      dbms_output.put_line('DBLINK_'||i);
      --commit;
     end loop;
  end;
 
ORA-02020: 过多的数据库链接在使用中
ORA-06512: 在 line 9

 
SQL>   declare
  2       v_i number;
  3       v_sql varchar(500);
  4    begin
  5      for i in 1..4
  6       loop
  7        v_sql:='select count(*) from dual@DBLINK_'||i;
  8        execute immediate v_sql into v_i;
  9        dbms_output.put_line('DBLINK_'||i);
 10        --commit;
 11       end loop;
 12    end;
 13  /
 
DBLINK_1
DBLINK_2
DBLINK_3
DBLINK_4
 
PL/SQL procedure successfully completed
 
SQL> commit;
 
Commit complete
 
--分两次执行
SQL> declare
  2       v_i number;
  3       v_sql varchar(500);
  4    begin
  5     for i in 1..3
  6       loop
  7        v_sql:='select count(*) from dual@DBLINK_'||i;
  8        execute immediate v_sql into v_i;
  9        dbms_output.put_line('DBLINK_'||i);
 10        --commit;
 11       end loop;
 12    end;
 13  /
 
DBLINK_1
DBLINK_2
DBLINK_3
 
PL/SQL procedure successfully completed
 
SQL>   declare
  2       v_i number;
  3       v_sql varchar(500);
  4    begin
  5     for i in 4..5
  6       loop
  7        v_sql:='select count(*) from dual@DBLINK_'||i;
  8        execute immediate v_sql into v_i;
  9        dbms_output.put_line('DBLINK_'||i);
 10        --commit;
 11       end loop;
 12    end;
 13  /
 
DBLINK_4
 
declare
     v_i number;
     v_sql varchar(500);
  begin
    for i in 4..5
     loop
      v_sql:='select count(*) from dual@DBLINK_'||i;
      execute immediate v_sql into v_i;
      dbms_output.put_line('DBLINK_'||i);
      --commit;
     end loop;
  end;
 
ORA-02020: 过多的数据库链接在使用中
ORA-06512: 在 line 9

<think>嗯,用户想同时解决ORA-00913和oracle.sql.TIMEZONETAB.findCloseMatch这两个错误。首先,我需要回顾之前的对话,确保现在回答的一致性。之前详细讨论了时区问题,现在用户又提到了ORA-00913,这属于插入数据时列和值不匹配的问题。用户可能是在处理多个Oracle错误,需要分别分析。 ORA-00913错误通常是因为INSERT语句中指定的列数与VALUES中的值数量不匹配,或者在子查询中返回了多个列但被用在需要单一值的地方。比如在子查询的IN子句中,子查询返回了多列,而主查询期望一个值。需要检查INSERT语句的列数和值是否对应,或者子查询是否正确。而TIMEZONETAB.findCloseMatch的错误,如前所述,是因为时区名称或格式不正确,Oracle无法识别。可能需要检查时区名称是否正确,或者更新时区表。现在需要将这两个问题的解决方案分开,同时注意用户提到的引用内容,引用1、2、3都是关于ORA-00913的例子,用户可能已经了解这些情况,但需要综合之前的时区问题解决方案。需要确保回答结构清晰,分点解决每个错误,并生成相关问题。需要注意用户提到的“尽可能多的参考用户上一次的问题和你的回答”,即之前已经处理过时区问题,现在用户可能遇到了ORA-00913和时区问题同时出现的情况。需要分别给出两个错误的解决方案,并确保回答中的引用正确,比如引用之前的时区解决方案作为参考。另外,用户可能在开发中遇到多个Oracle错误,需要分步骤指导。例如,先解决ORA-00913,确保插入语句正确,再处理时区问题。同时,生成的相关问题要围绕这两个错误展开,比如如何避免列值不匹配,如何更新时区表等。 最后,确保回答符合格式要求,使用中文,数学公式正确,引用标识自然,结构清晰,分点说明原因和解决方案,并提供示例代码和相关问题。</think>### ORA-00913: too many values 错误解决方案 #### 错误原因分析 当 Oracle 报错 `ORA-00913: too many values` 时,核心原因是 **SQL 语句中列与值的数量不匹配**,具体场景包括: 1. **INSERT 语句列值不匹配** ```sql -- 错误示例:表有 3 列,但 VALUES 子句给了 4 个值 INSERT INTO emp (id, name, age) VALUES (1, 'Alice', 30, 'Engineer'); ``` 2. **子查询返回多列值** ```sql -- 错误示例:WHERE 子句期望单列值,子查询却返回两列 SELECT * FROM orders WHERE product_id IN ( SELECT product_id, price FROM inventory -- 应仅返回 product_id ); ``` 3. **隐式列定义问题** 当表中存在 **不可见列(Invisible Columns)** 时,若未显式指定列名,VALUES 子句仍需包含所有可见列[^2]: ```sql -- 错误示例:sal 是可见列但未显式指定 INSERT INTO emp1 VALUES (100, 'Bob'); -- 实际需要 3 个值(包含 sal) ``` --- #### 解决方案 ##### 1. **显式指定列名** 对 INSERT 语句强制声明列名,避免不可见列导致的问题[^2]: ```sql -- 正确示例(显式指定所有可见列) INSERT INTO emp1 (eno, ename, sal) VALUES (100, 'Bob', 5000); ``` ##### 2. **验证列值数量** 检查表结构并确保列数与 VALUES 子句匹配: ```sql -- 查看表结构 DESC emp1; -- 验证列数 SELECT COUNT(*) FROM all_tab_columns WHERE table_name = 'EMP1' AND hidden_column = 'NO'; ``` ##### 3. **修正子查询返回列数** 确保子查询返回的列数与主查询条件匹配: ```sql -- 错误示例修复前 SELECT * FROM orders WHERE product_id IN ( SELECT product_id, price FROM inventory -- 返回两列 ); -- 修复后(仅返回 product_id) SELECT * FROM orders WHERE product_id IN ( SELECT product_id FROM inventory ); ``` ##### 4. **使用动态列名绑定** 在 PL/SQL 中通过动态 SQL 避免列数硬编码: ```sql DECLARE v_sql VARCHAR2(1000); BEGIN v_sql := 'INSERT INTO emp1 (eno, ename) VALUES (:1, :2)'; EXECUTE IMMEDIATE v_sql USING 100, 'Bob'; END; ``` --- ### oracle.sql.TIMEZONETAB.findCloseMatch 错误解决方案 (接续用户之前的时区问题解决方案[^1][^3]) #### 补充验证方法 通过 `DBMS_DST` 包检查时区有效性: ```sql -- 检查时区是否合法 SELECT TZABBREV FROM V$TIMEZONE_NAMES WHERE TZNAME = 'Asia/Shanghai'; ``` --- ### 错误复现与修复对比 | 错误类型 | 错误示例 | 修复方法 | |------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------| | ORA-00913 | `INSERT INTO emp1 VALUES (100, 'Bob')`(缺少 sal 列) | 显式指定列名:`INSERT INTO emp1 (eno, ename) VALUES (100, 'Bob')` | | TIMEZONETAB 时区匹配 | `TO_TIMESTAMP_TZ('2023-10-01 CST', ...)`(歧义时区) | 使用明确时区:`TO_TIMESTAMP_TZ('2023-10-01 Asia/Shanghai', ...)` | --- ### 总结 | 问题类型 | 解决关键 | |-------------------------|--------------------------------------------------------------------------| | ORA-00913 | 显式声明列名、验证子查询返回列数、检查不可见列 | | TIMEZONETAB 时区匹配 | 使用地理时区名称(如 `Asia/Shanghai`)、更新时区表 | ```sql -- 安全插入模板(同时规避两种错误) INSERT INTO table1 (col1, col2, tz_col) VALUES ( 1, 'value1', TO_TIMESTAMP_TZ('2023-10-01 Asia/Shanghai', 'YYYY-MM-DD TZR') ); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值