SQL Server varbinary(max)到Oracle LONG RAW

时间:2014-02-07 21:13:17

标签: sql-server oracle integration

我正在尝试将二进制数据从SQL Server推送到Oracle LONG RAW列。我在SQL Server上创建了一个连接到Oracle服务器的链接服务器。我在Oracle端有一个存储过程,我试图从SQL Server调用。我似乎无法将二进制文件传递给存储过程。我试过改变from和to类型;但是,数据最终需要在LONG RAW列中结束。我可以控制Oracle存储过程和SQL Server代码,但是我无法控制预定义的Oracle表结构。

varbinary(max) - >长原始      ORA-01460:请求未实现或无理转换

varbinary(max) - >斑点      PLS-00306:调用'ADDDOC'时错误的参数数量

varbinary - >长原始     没有错误,但会导致数据截断或损坏

如果我设置@doc = null。

,varbinary(max)可以工作

以下是Oracle过程和SQL Server。

甲骨文:

CREATE OR REPLACE
PROCEDURE ADDDOC (param1 IN LONG RAW)
AS
BEGIN
  -- insert param1 into a LONG RAW column
  DBMS_OUTPUT.PUT_LINE('TEST');
END ADDDOC;

SQL Server:

declare @doc varbinary(max)
select top 1 @doc = Document from Attachments

execute ('begin ADDDOC(?); end;', @doc) at ORACLE_DEV

-- tried this too, same error
--execute ('begin ADDDOC(utl_raw.cast_to_raw(?)); end;', @doc) at ORACLE_DEV

我也尝试在Oracle Documents表中创建记录,然后从SQL Server更新LONG RAW字段而不调用存储过程,但查询似乎只是运行并运行并运行并运行...

--already created record and got the Id of the record I want to put the data in
--hard coding for this example
declare @attachmentId, @documentId
set @attachmentId = 1
set @documentId = 1

update ORACLE_DEV..MYDB.Documents
set Document = (select Document from Attachments where Id = @attachmentId)
where DocumentId=@documentId

1 个答案:

答案 0 :(得分:1)

正如评论中所述,LONG RAW很难合作;不幸的是,我们的供应商正在他们的产品中使用数据类型,我别无选择,只能使用它。我发现我无法将二进制数据从SQL Server传递到Oracle存储过程参数。我最终必须为LONG RAW字段创建一个具有NULL值的新记录,然后使用OPENQUERY更新将字段设置为VARBINARY(MAX)字段;我确实尝试使用带有四部分标识符的更新,如我的代码示例中所述,但单次更新花费了超过11分钟,这种新方法在不到3秒的时间内完成。我在这里使用Oracle存储过程,因为在我的真实世界场景中,我在多个表中创建了多个记录,并且编码了与docId一起将它们绑定在一起的业务逻辑。

这更像是一种解决方法,而不是一种解决方案,但实际上它可以在可接受的性能下工作。

甲骨文:

create or replace procedure ADDDOC(docId OUT Number)
as
begin
    select docseq.nextval into docId from dual;

    -- insert new row, but leave Document LONG RAW field null for now
    insert into DOC (Id) values(docId);
end ADDDOC;

SQL Server:

declare @DocId float, @AttachmentID int, @Qry nvarchar(max)
set @AttachmentID = 123 -- hardcoded for example

execute('begin ADDDOC(?); end;', @DocId output) at ORACLE_DEV

-- write openquery sql that will update Oracle LONG RAW field from a SQL Server varbinary(max) field
set @Qry = '
    update openquery(ORACLE_DEV, ''select Document from Documents where Id=' + cast(@DocId as varchar) + ''')
    set Document = (select Document from Attachments where Id = ' + cast(@AttachmentID as varchar) + ')
    '
execute sp_executesql @Qry