I am getting ORA-01410 and ORA-06512 for the following block of code in a trigger I'm firing for deletion of a record in my table.
Are the calls correct ?
getlong ('xxx', 'YYY', :OLD.ROWID),
getlong ('XXX', 'yyy', :NEW.ROWID)
There seems to be a problem in the way I'm passing OLD.ROWID and NEW.ROWID; there are OLD.ROWID and NEW.ROWID in the tables that I'm updating once the triggers are fired.
Here is the getlong stored procedure:
CREATE OR REPLACE FUNCTION getlong (p_tname IN VARCHAR2, -- table name
p_cname IN VARCHAR2, -- column name
p_rowid IN ROWID)
RETURN VARCHAR2
AS
l_cursor INTEGER DEFAULT DBMS_SQL.open_cursor;
l_n NUMBER;
l_long_val VARCHAR2 (4000);
l_long_len NUMBER;
l_buflen NUMBER := 4000;
l_curpos NUMBER := 0;
BEGIN
-- Usage:
-- select getlong('TABLENAME', 'COLUMNNAME', rowid) from TABLENAME;
DBMS_SQL.
parse (l_cursor,
'select ' || p_cname || ' from ' || p_tname || ' where rowid = :x',
DBMS_SQL.native);
DBMS_SQL.bind_variable (l_cursor, ':x', p_rowid);
DBMS_SQL.define_column_long (l_cursor, 1);
l_n := DBMS_SQL.execute (l_cursor);
IF (DBMS_SQL.fetch_rows (l_cursor) > 0)
THEN
DBMS_SQL.column_value_long (l_cursor,
1,
l_buflen,
l_curpos,
l_long_val,
l_long_len);
END IF;
DBMS_SQL.close_cursor (l_cursor);
RETURN l_long_val;
END getlong;
/
Thanks for helping.
Best Answer
There seems to be a combination of more than one problem at work here.
First of all the pseudo-record
:NEW
is not available in a delete-trigger. You can only access the values of the deleted row via the pseudo-record:OLD
. Hence the second callgetlong ('XXX', 'yyy', :NEW.ROWID)
will not make much sense.Secondly you pass a row-ID to the procedure
getlong
which basically gets a value from an arbitrary table (hereXXX
), which is not necessarily the same table the deleted row came from. A row-ID by itself can only be used to retreive a row from the same table you got the row-ID from. For exampleThe row-ID from the statement above can only be used in a select-statement on the same table
table_name
, i.g.If you try to pass a row-ID of a different table to a select-statement, you will also receive an ORA-01410 error.
A row-ID can be invalid out of multiple reasons
The row-ID references a record which belongs to a different table than the statement accesses where that row-ID is used in.
The row-ID does not match oracles specific format, e.g. when passed as a string.
In this case the first point might be the problem encoutered here. If the table
XXX
is not the table your delete-trigger works on, you will get an ORA-01410.On the other hand, there is not much sense in calling
getlong
in the context of a trigger, if only a select on the same table makes sense, where the row-ID comes from, because you already have direct access to the value you are interested in via the pseudo-record:OLD
.