SQL Server varbinary (max) в Oracle LONG RAW

Я пытаюсь передать двоичные данные из SQL Server в столбец Oracle LONG RAW. У меня есть связанный сервер, созданный на SQL Server, который подключается к серверу Oracle. У меня есть хранимая процедура на стороне Oracle, которую я пытаюсь вызвать с SQL Server. Кажется, я не могу передать двоичный файл в хранимую процедуру. Я пробовал менять типы с и на; однако данные в конечном итоге должны оказаться в столбце LONG RAW. У меня есть контроль над хранимой процедурой Oracle и кодом SQL Server, но у меня нет контроля над предопределенной структурой таблицы Oracle.

varbinary (max) -> long raw ORA-01460: запрошено нереализованное или необоснованное преобразование

varbinary (max) -> blob PLS-00306: неправильное количество или типы аргументов при вызове ADDDOC

varbinary -> long raw Без ошибок, но происходит усечение или повреждение данных

Varbinary (max) работает, если я установил @doc = null.

Ниже представлена ​​процедура 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, а затем обновить поле LONG RAW с SQL Server без вызова хранимой процедуры, но запрос просто запускается, запускается, запускается и запускается ...

--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

person Kacey    schedule 07.02.2014    source источник
comment
LONG и LONG RAW были отключены с Oracle 8.0 дней ~ 20 лет назад. Они были обесценены, потому что поддерживать их было королевской головной болью, и относительно небольшое количество API-интерфейсов способно с ними справиться. Возможно, кто-нибудь сможет прийти и предложить способ подключения к связанному серверу для поддержки LONG RAW, но я не был бы шокирован, если бы вам пришлось использовать другой подход.   -  person Justin Cave    schedule 08.02.2014
comment
Не используйте LONG или LONG RAW. Единственное разумное совпадение для varbinary SQL Server - BLOB.   -  person a_horse_with_no_name    schedule 08.02.2014
comment
Я вижу, что LONG RAW - настоящая боль. Структура таблиц Oracle - это серверная часть стороннего продукта, с которым мне нужно интегрироваться, поэтому изменение типа данных не в моих руках. Я попытался изменить параметр хранимой процедуры на BLOB, но получил неправильное количество или типы аргументов.   -  person Kacey    schedule 08.02.2014


Ответы (1)


Как отмечалось в комментариях, с LONG RAW очень сложно работать; К сожалению, наш поставщик использует этот тип данных в своем продукте, и у меня нет другого выбора, кроме как работать с ним. Я обнаружил, что не могу передавать двоичные данные из SQL Server в параметр хранимой процедуры Oracle. В итоге мне пришлось создать новую запись со значением NULL для поля LONG RAW, а затем использовать обновление 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
person Kacey    schedule 10.02.2014