DB LINK работа с LOB полями и ORA-22992
DB LINK - специальный механизм СУБД ORACLE который позволяет взаимодействовать с другими базами данных
примечательно что DB LINK могут использоваться не только для взаимодействия с базами данных ORACLE
но и с другими СУБД , такими как MS SQL или MY SQL
для создания DB link пользователь должен иметь соответсвующую системную привилегию
create database link
рассмотрим несколько примеров создания db_link
CREATE DATABASE LINK MTEST connect to userdb1 identified by password1 USING 'sservise'; --так же синтaксис может быть и таким create database link MTEST connect to userdb1 identified by password1 using '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = test.test.ru)(PORT = 1521)) ) (CONNECT_DATA = (SERVER = DEDICATED) (SID = mtest1) ))';
DB_Link может быть shared и pulic
-- удалить db_link можно использую следующую команду
DROP DATABASE LINK MTEST1;
создадим в УДАЛЕННОЙ базе данных следующую таблицу
create table Table_Clob(PID NUMBER,PCLOB CLOB); -- добавим в нашу созданную таблицу несколько строк insert into Table_Clob(pid,pclob) values (1,'это поле1 clob, хотя и непохоже'); insert into Table_Clob(pid,pclob) values(2,'это поле2 clob, хотя и непохоже'); insert into Table_Clob(pid,pclob) values(3,'это поле3 clob, хотя и непохоже'); commit; -- напишем select [more] select pid, cast(pclob as varchar2(100)) textclob from Table_Clob;
данные действительно в базе
-- PID PCLOB
-- 1 это поле1 clob, хотя и непохоже
-- 2 это поле2 clob, хотя и непохоже
-- 3 это поле3 clob, хотя и непохоже
обратите внимание на преобразование cast - в данном случае оно допустимо, но когда в поле clob будет
более 4000 символов , такое преобразование будет некорректными
пробуем обратится к нашей удаленной Table_Clob таблице через DB_LINK
для этого создадим DB_LINK на удаленную базу, синтаксис я приводил выше
select * from Table_Clob@dl_test_load
-- ORA-22992: невозможно использовать указатели LOB, выбранные из удаленных таблиц
-- ORA-22992: cannot use LOB locators selected from remote table
данная ошибка связана с тем что напрямую получить lob данные , написав такой запрос нельзя
что же делать??!?
-- создадим временную таблицу
create global temporary table t_clob(pid number,pclob clob);
-- напишем следующий запрос вставки
insert into t_clob(pid,pclob) select pid,pclob from Table_Clob@dltest
-- данные находятся в нашей временной таблице в чем легко убедится
-- выполнив запрос , перед выполнением commit
select * from t_clob
для работы с lob полями на удаленной базе данных, необходимо использовать временную таблицу
после вставки данных из удаленной с помощью Insert в эту таблицу
мы уже легко сможем работать с данными из lob полей , которые находились в таблице на удаленном сервере