为什么具有扩展varchar2限制的12c仍将sql server varchar(max)转换为long

时间:2019-04-05 14:14:59

标签: sql-server oracle oracle12c

Oracle版本12.1.0.2 max_string_size =扩展

我正在使用sql server ODBC通过Oracle网关连接到sql server的sql server数据库,该连接工作正常,并且能够访问sql server表。

但是,根据Oracle文档从12c开始并具有对varchar2数据类型的扩展限制,只有在sql服务器数据的长度大于32k时,才会将sqlserver varchar(max)转换为oracle Long。

我的sql server表中有几列定义为varchar(max),当我尝试通过dblink描述该表时,我看到的所有列都将转换为LONG。 我需要将数据从sql server加载到oracle,由于无法通过dblink复制多个以上的长列,因此上述问题非常困难。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我在SQL Server端创建了一个视图,该视图使用substr(column,1,4000)来适应旧的Oracle max 4000字符长度。这在Oracle 11上效果很好。

我正在迁移到使用字符集AL32UTF8而不是WE8MSWIN1252的新Oracle 18实例。现在正在获得完全相同的SQL:

ORA-28500: connection from ORACLE to a non-Oracle system returned this message:
[Microsoft][ODBC Driver Manager] Program type out of range {HY003}
ORA-02063: preceding 2 lines from CEAV195

幸运的是,我没有一个紧迫的期限来解决这个问题。

评论:我现在得到

  

[错误]执行(8:17):ORA-00997:非法使用LONG数据类型

尽管在SQL Server一侧的视图中使用以下内容:

  

cast(substring(cr.response,1,2000)as varchar(2000))响应

正如我之前所说,这与Oracle 11和WE8MSWIN1252字符集完美配合。

答案 1 :(得分:0)

我遇到了同样的问题,并在其他地方找到了该解决方案

set serverout on
DECLARE
  l_cursor    BINARY_INTEGER;
  l_id VARCHAR2(60);
  l_temp      VARCHAR2(250);
  l_notes     VARCHAR2(32767);
BEGIN
  l_cursor := DBMS_HS_PASSTHROUGH.open_cursor@remotedb;
  DBMS_HS_PASSTHROUGH.parse@remotedb(
  l_cursor,
  'select "RecId","Notes" from "MySqlServerTable"'
);

LOOP
  DBMS_HS_PASSTHROUGH.get_value@remotedb(l_cursor, 1, l_id);
  DBMS_HS_PASSTHROUGH.get_value@remotedb(l_cursor, 2, l_notes);
  DBMS_OUTPUT.put_line(l_id || ' ' || l_notes);
END LOOP;

exception
  when others then
  DBMS_HS_PASSTHROUGH.close_cursor@remotedb(l_cursor);
  raise;
END;
/