Skip to Main Content
  • Questions
  • after insert trigger with clobs and perl works different

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Sebastian.

Asked: March 27, 2005 - 11:27 pm UTC

Last updated: March 28, 2005 - 9:03 pm UTC

Version: 10g

Viewed 1000+ times

You Asked

Hello Tom,

we are using oracle 10g, perl dbi to connect to oracle,with 2 tables with clob's columns, and the trigger that after insert concatenates a varchar2 and a clob, and inserts the new concatenated value to a clob field in the second table.

CREATE OR REPLACE TRIGGER QUERY_SEQUENCE_TR5 AFTER
INSERT ON QUERY_SEQUENCE FOR EACH ROW
BEGIN
insert into blistxt.query_seq_txt values(:new.seq_id,:new.name||' '||:new.description);
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END ;

this works perect if we insert a row thru sqlplus, but when we insert a row trhu the application written in perl, the clob doesn't get propagated correctly, in fact it doesn't get propagated at all, but when we inspect the original row after the insert, all the values are there.

for values:
seq_id=17170598
name='622_at'
description='622_at; gb|M28212; SEBASTIAN AND CHRIS Homo sapiens GTP-binding protein (RAB6)mRNA, complete cds'

here is the part of the perl code for the insert

my $query = qq{
insert into query_sequence (seq_id, user_id, name, description, moltype, seq_data, seq_len, time, link, org_id, realm_id, datasource_id, datasource_id_original, query_seq_load_id)
values (null, ?, ?, ?, ?, ?, ?, sysdate, ?, ?, ?, ?, ?, ?)
};

my $sth = $self->prepare($query);

$sth->bind_param(1, $self->user_id);
$sth->bind_param(2, $name);
$sth->bind_param(3, $desc, { ora_type => ORA_CLOB, ora_field=>'description'});
$sth->bind_param(4, $moltype);
$sth->bind_param(5, $seq_data, { ora_type => ORA_CLOB, ora_field=>'seq_data'});
$sth->bind_param(6, $length);
$sth->bind_param(7, undef);
$sth->bind_param(8, $org_id);
$sth->bind_param(9, $realm_id);
$sth->bind_param(10, $source_id);
$sth->bind_param(11, $source_id);
$sth->bind_param(12, $load_id);

my $result = $sth->execute();

this is the result

SQL> l
1* select seq_id,name,description from query_sequence where seq_id=17170598
SQL> /

SEQ_ID
----------
NAME
--------------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------
17170598
622_at
622_at; gb|M28212; SEBASTIAN AND CHRIS Homo sapiens GTP-binding protein (RAB6) m



1* select * from query_seq_txt where seq_id=17170598
SQL> /

SEQ_ID QUERY_TEXT
---------- ----------------------------------------------------------
17170598 622_at



do you know any limitation or exception with triggers and clobs being inserted thru perl/dbi?

Any help will be great.

Tahnks a lot

Sebastian

and Tom said...

working with lobs in a trigger will be problematic -- period.

most of the times, lobs are populated using logic like this:


insert into t ( ..., clob_col ) values ( ...., empty_clob() );
dbms_lob...... ( that clob col ) to populate it.


and that is probably what perl is doing under the covers, putting a empty clob in there and streaming the data in after the insert.

In fact, you can modify the contents of a clob without firing a single trigger! select it out, dbms_lob.write it and no triggers will fire.


This is not a perl/dbi issue, this is LOBS in general.

Suggest that if this is a requirement -- to have the lob in two places, you utilize a stored procedure API to access this and have it "do the right thing".

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

LOBS and triggers

Sebastian, March 28, 2005 - 2:43 pm UTC

Thanks Tom for the quick response, very informative an useful.

I guess sqlplus is doing it different, because it works in that circumstance.

the goal was to propagate that lob to another table for application requeirements purpose, and triggers was the natural choice, but any form of simple replication will do it.

Sebastian

Tom Kyte
March 28, 2005 - 6:15 pm UTC

it worked in sqlplus because you didn't insert an empty_clob and stream to it. if you trace the perl, I'll bet you that is what is really happening.

perl dbi doc

bob, March 28, 2005 - 9:03 pm UTC

If you read the DBD::Oracle docs, it states that this is the magic Tim uses underneath to make a clob insert a single statement in perl.

Tom,
I know you aren't really a fan of perl for Oracle development, but if you needed another reason to not like it, did you know that the Oracle DBI doesn't support array inserts or batching.

I know it was in Tim Bunce's queue of things to add to the DBI a couple years ago, but I don't believe it has happened yet.

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here