Warm tip: This article is reproduced from stackoverflow.com, please click
oracle oracle11g

View to determine if a LOB column is NULL through a database link

发布于 2020-03-28 23:16:51

A new column (of BLOB type) has been added to a remote database table. The application I maintain reads that table through a view that's a simple select statement over a database link. I need to update the view so I have access to the new column.

Apparently, you can't read a LOB column through a database link:

ORA-22992: cannot use LOB locators selected from remote tables

So far I just need to know whether rows have data. This query works flawlessly:

select foo_id, foo_name, foo_date,
case
    when foo_binary is not null then 1
    else 0
end as has_foo_binary_data
from remote_table@remote_database;

Yet I can't create a view unless I remove the case expression:

create view remote_foo as
select foo_id, foo_name, foo_date,
case
    when foo_binary is not null then 1
    else 0
end as has_foo_binary_data
from remote_table@remote_database;

RA-22992: cannot use LOB locators selected from remote tables

DBMS_LOB.GETLENGTH(foo_binary) starts a cute catch-22:

ORA-02069: global_names parameter must be set to TRUE for this operation

alter session set global_names = true`;
create view ...

ORA-02085: database link remote_database connects to remote_sid

Cause: a database link connected to a database with a different name. The connection is rejected.

Action: create a database link with the same name as the database it connects to, or set global_names=false.

Not sure if I've hit a wall or I'm just making silly mistakes. Is there some way to obtain any of information about the CLOB (not the blob data) that works in a view?

Questioner
Álvaro González
Viewed
103
Littlefoot 2020-01-31 18:36

You've posted pretty much info already so I'm not going to repeat it all.

Here's an option you might want to consider; not the perfect one and it depends whether it is OK or not. Anyway:

Alter table in the remote database and add a new column:

alter remote_table add foo_binary_length number;

Populate it in a database trigger:

create or replace trigger trg_biu_remtab
  before insert or update on remote_table
  for each row
begin
  :new.foo_binary_length := dbms_lob.getlength(:new.foo_binary);
end;
/

Now it is a simple task to create a view in the local database:

create view remote_foo as
select foo_id, foo_name, foo_date,
case
    when foo_binary_length > 0 then 1      --> this
    else 0
end as has_foo_binary_data
from remote_table@remote_database;