Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / DB2 Topics / March 2007

Tip: Looking for answers? Try searching our database.

Retrieving identity value

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
gunnar.sigurjonsson@gmail.com - 13 Mar 2007 10:18 GMT
I´m having some problem retrieving identity value from my newly
inserted row into a view.

I have two tables T1 and T2 which I define as following

CREATE TABLE T1
(
 id BIGINT GENERATED ALWAYS AS IDENTITY
 (
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    NO CYCLE
    NO ORDER
    CACHE 20
 ),
 t1name VARCHAR(10),
 CONSTRAINT c_k2_column_reference_id_pk PRIMARY KEY(id)
);

CREATE TABLE T2
(
 id BIGINT GENERATED ALWAYS AS IDENTITY
 (
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    NO CYCLE
    NO ORDER
    CACHE 20
 ),
 t2name VARCHAR(10),
 t1id BIGINT,
 CONSTRAINT c_k2_column_reference_id_pk PRIMARY KEY(id)
);
ALTER TABLE T2
ADD CONSTRAINT t1id_fk
FOREIGN KEY( id )
REFERENCES t1 (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION ;

I created view V 1to combine those two table as following
CREATE VIEW V1 AS
 SELECT  t1.id,
         t1.t1name,
         t2.id,
         t2.t2name
 FROM    t1

 JOIN t2
 ON   t2.id = t1.id;

At last I created insert trigger T1 to be able to insert into my view
CREATE TRIGGER t1
INSTEAD OF INSERT ON v1
REFERENCING NEW AS v1new
FOR EACH ROW
MODE DB2SQL
BEGIN ATOMIC
   INSERT INTO t1(t1name)
   VALUES (v1new.t1name);

   INSERT INTO t1( t2name, t1id)
   VALUES (v1new.t2name, IDENTITY_VAL_LOCAL()) ;

END;

Now I can insert into my view by doing

INSERT INTO v1 (t1name, t2name) value('test1', 'test2');

but when I call IDENTITY_VALUE_LOCAL() i get null value but I´m
interested in to retrieve id value of table T2 which I´m interested
in.

Can anyone help me on how I can retriveve the identity value of newly
created row by the trigger outside the trigger scope?

regards,
Gunnar
Knut Stolze - 13 Mar 2007 11:28 GMT
> I´m having some problem retrieving identity value from my newly
> inserted row into a view.
[quoted text clipped - 76 lines]
> Can anyone help me on how I can retriveve the identity value of newly
> created row by the trigger outside the trigger scope?

How about this:

BEGIN ATOMIC
  DECLARE new_value INT;
  SELECT id
  INTO   new_value
  FROM   NEW TABLE ( INSERT
                     INTO   t1(t1name)
                     VALUES ( v1new.t1name ) ) AS t;
  INSERT
  INTO   t1(t2name, tlid)
  VALUES v1new.t2name, new_value);
END

Signature

Knut Stolze
DB2 z/OS Admin Enablement
IBM Germany

Serge Rielau - 13 Mar 2007 12:21 GMT
>> I´m having some problem retrieving identity value from my newly
>> inserted row into a view.
[quoted text clipped - 90 lines]
>    VALUES v1new.t2name, new_value);
> END

I don't think that will work.
NEW TABLE contains NULL values for the identity column in the view.
Theory has it that NEW TABLE would pick up SET-ing of new transition
variables in the INSTEAD OF trigger. But that is yet to be implemented
(no plans so far).

Does anything speak against using a SEQUENCE instead of IDENTITY?

PREVIOUS VALUE FOR <s> should work where IDENTITY_VAL_LOCAL let's you down.

Cheers
Serge
Signature

Serge Rielau
DB2 Solutions Development
IBM Toronto Lab

Brian Tkatch - 13 Mar 2007 15:11 GMT
>>> I´m having some problem retrieving identity value from my newly
>>> inserted row into a view.
[quoted text clipped - 103 lines]
>Cheers
>Serge

Do you think this is a good case for Oracle's RETURNING...INTO clause?
It should work in such a case, where NEW() won't.

B.
Serge Rielau - 13 Mar 2007 17:02 GMT
>>>> I´m having some problem retrieving identity value from my newly
>>>> inserted row into a view.
[quoted text clipped - 105 lines]
> Do you think this is a good case for Oracle's RETURNING...INTO clause?
> It should work in such a case, where NEW() won't.
No. conceptually NEW TABLE/OLD TABLE is a true superset of RETURNING INTO.
This is about a pothole in INSTEAD OF triggers.

Signature

Serge Rielau
DB2 Solutions Development
IBM Toronto Lab

Brian Tkatch - 14 Mar 2007 16:29 GMT
>>>>> I´m having some problem retrieving identity value from my newly
>>>>> inserted row into a view.
[quoted text clipped - 107 lines]
>No. conceptually NEW TABLE/OLD TABLE is a true superset of RETURNING INTO.
>This is about a pothole in INSTEAD OF triggers.

It's not a bug, it's a feature! :)

So, conceptually, NEW is better.... well, yeah, i actually understand
that. But RETURNING...INTO is just  more convenient and easy to
understand. I wonder then, if it would work here.

B.
Serge Rielau - 23 Mar 2007 13:36 GMT
> It's not a bug, it's a feature! :)
>
> So, conceptually, NEW is better.... well, yeah, i actually understand
> that. But RETURNING...INTO is just  more convenient and easy to
> understand. I wonder then, if it would work here.
You can see RETURNING INTO as SYNTACTIC SUGAR for a straight SELECT FROM
INSERT. As such it cannot do anything SELECT FROM INSERT can't.

Cheers
Serge
Signature

Serge Rielau
DB2 Solutions Development
IBM Toronto Lab

Brian Tkatch - 23 Mar 2007 17:47 GMT
>> It's not a bug, it's a feature! :)
>>
[quoted text clipped - 6 lines]
>Cheers
>Serge

Including bulk INSERTS? RETURNING INTO allows a host variable to
retrieve an array after a bulk INSERT. Very convenient for knowing the
new ids assigned in an operation.

B.
Serge Rielau - 23 Mar 2007 22:12 GMT
> Including bulk INSERTS? RETURNING INTO allows a host variable to
> retrieve an array after a bulk INSERT. Very convenient for knowing the
> new ids assigned in an operation.
That is not a feature of INSERT RETURNING that is a feature of having
ARRAYs.
The SQL would look like:
SELECT ARRAY_AGG(myphones) FROM NEW TABLE(INSERT ....)

It's all about orthogonality. Like playing LEGO (classic)

Cheers
Serge
Signature

Serge Rielau
DB2 Solutions Development
IBM Toronto Lab

Brian Tkatch - 26 Mar 2007 17:12 GMT
>> Including bulk INSERTS? RETURNING INTO allows a host variable to
>> retrieve an array after a bulk INSERT. Very convenient for knowing the
[quoted text clipped - 8 lines]
>Cheers
>Serge

Good point. :)

B.
Knut Stolze - 13 Mar 2007 18:12 GMT
>>> I´m having some problem retrieving identity value from my newly
>>> inserted row into a view.
[quoted text clipped - 105 lines]
> Cheers
> Serge

Actually, it does because I was selecting the generated identity value from
the underlying base table.  It's just that you can't use SELECT INTO in the
trigger body.  Resorting to a SET ... = ( SELECT ... ) fixes that:

CREATE TABLE t1 (
  a INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  b INT
)@
CREATE TABLE t2 (
  a INT NOT NULL,
  c INT,
  CONSTRAINT a_fk FOREIGN KEY(a) REFERENCES t1(a)
     ON DELETE CASCADE
)@

CREATE VIEW v AS
  SELECT b, c
  FROM   t1 JOIN t2 ON t1.a = t2.a@

CREATE TRIGGER t INSTEAD OF INSERT ON v
  REFERENCING NEW AS n
  FOR EACH ROW
  BEGIN ATOMIC
     DECLARE id INT;
     SET id = ( SELECT a
                FROM   NEW TABLE ( INSERT INTO t1(b) VALUES (n.b) ) AS t );
     INSERT INTO t2 VALUES (id, n.c);
  END@

INSERT INTO v VALUES (2, 3)@

SELECT * FROM t1@

A           B
----------- -----------
         1           2

 1 record(s) selected.

SELECT * FROM t2@

A           C
----------- -----------
         1           3

 1 record(s) selected.

Signature

Knut Stolze
DB2 z/OS Admin Enablement
IBM Germany

Serge Rielau - 13 Mar 2007 21:13 GMT
>>>> I´m having some problem retrieving identity value from my newly
>>>> inserted row into a view.
[quoted text clipped - 108 lines]
> the underlying base table.  It's just that you can't use SELECT INTO in the
> trigger body.  Resorting to a SET ... = ( SELECT ... ) fixes that:
Knut,

You are missing the point. The OP wants to retrieve the generated
identity value from the VIEW.
So in that example of yours "ID" needs to be the column in the new
transition variable which is not allowed.
We thought long and hard whether it's worth providing that support and
decided against it in the end... for now

Cheer
Serge
Signature

Serge Rielau
DB2 Solutions Development
IBM Toronto Lab

Knut Stolze - 14 Mar 2007 09:58 GMT
> You are missing the point. The OP wants to retrieve the generated
> identity value from the VIEW.

Right, I missed that.

Signature

Knut Stolze
DB2 z/OS Admin Enablement
IBM Germany

gunnar.sigurjonsson@gmail.com - 14 Mar 2007 11:07 GMT
Thanks for your replies.  I?ll probably just use stored procedure
instead of trigger to insert directly into the tables behind the view
instead of using trigger. Then I retrieve the id as an OUT parameter
in the procedure.  But it would have been much cleaner to make the
trigger do the job.

CREATE PROCEDURE v_instert
(
 OUT out_t2id BIGINT,
 IN in_t1name VARCHAR(10),
 IN in_t2name VARCHAR(10)
)

LANGUAGE SQL
SPECIFIC v_instert
NOT DETERMINISTIC
MODIFIES SQL DATA
CALLED ON NULL INPUT

BEGIN

   INSERT INTO t1(t1name)
   VALUES (in_t1name);

   INSERT INTO t1( t2name, t1id)
   VALUES (in_t2name, IDENTITY_VAL_LOCAL()) ;

   SET out_t2id = IDENTITY_VAL_LOCAL ();

END;
Brian Tkatch - 14 Mar 2007 16:35 GMT
>Thanks for your replies.  I´ll probably just use stored procedure
>instead of trigger to insert directly into the tables behind the view
[quoted text clipped - 26 lines]
>
>END;

Once you're going to do that, why not use a SEQUENCE and pop the value
yourself? That could even be done in a TRIGGER.

B.
Brian Tkatch - 13 Mar 2007 15:24 GMT
>I´m having some problem retrieving identity value from my newly
>inserted row into a view.
[quoted text clipped - 79 lines]
>regards,
>Gunnar

Bear with me, i'm just thinking out loud.

At first i was thinking to try to figure out which was the new record.
Being the IDENTITY is always going up, a MAX() before and after the
INSERT might do it, but that might run into concurrency issues.

Ultimately, the IDENTITY is reliant on a SEQUENCE, and that value can
be grabbed from the SYSIBM VIEW, but that's pretty much unsupported,
but perhaps useful in a bind.

As Serge pointed out, CREATEing your own SEQUENCE would give complete
control over it. Then, the TRIGGER could pop the next value off the
sequence into a local variable, and use it for both TABLEs.

B.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.