views:

70

answers:

2

Hello guys, I want a stored procedure to return the primary key of the new record after it gets executed. I think it will be returned by OUT parameter in the procedure. But how to select the newly inserted row ID ? I don't want to use select MAX(row_id) as it is a multi user environment. Any procedure sample will be appreciated.

My platform is ISeries DB2 V5 R4. Thanks.

Edit

The row id Column is not an identity column. It uses a sequence for the key which gets generated via a trigger before insert on table.

Edit

Here is what I am trying to do

Begin Stored procedure
   Insert into Employees;
   (row id gets automatically generated by trigger) 
Return row id ;

I want to avoid a select in returning row id.

+2  A: 

just set the out parameter to the column that contains the PK.

CREATE PROCEDURE DB2TBL.DO_STUFF (IN Param1 INT, IN Param2 CHAR(32),OUT Param3 INT) 
/* Param1 is primary key */
LANGUAGE SQL
P1: BEGIN
DECLARE OUTPARAM INT;
/* Do the stored procedure */
SET OUTPARAM = Param1; 
controlfreak123
the column that contains the PK is generated automatically by a trigger before INSERT. Any clue mate ?
Popo
do a select on the PK after the trigger and insert is done and set that to your out var
controlfreak123
I would appreciate whoever decided to downvote me to put why they felt my answer was unsatisfactory. It's pretty cowardly otherwise.
controlfreak123
Hello mate your reply is not complete anyway. I can select the row but I did wrote 'multi user environment' in my question. Is your solution feasible in a 'multi user' environment ? I down voted you because you are not understanding the question but have reverted it back since it seems to annoy you. No offense.
Popo
well to start the purpose of SO isn't to provide perfect answers and do all the work for you! Secondly it would help if you provided more of an explanation what you are trying to achieve and more of the layout of the tables you are working with. In a multiuser environment it will still be ok because you are dealing with a PK which is unique.
controlfreak123
I always get correct answers from here maybe you don't understand the scenario. Insert + fetch means fetching the value of sequence once again. If the sequence gets regenerated (say by another user in case of a long transaction in a multi user environment) this would fetch the wrong sequence value and hence a wrong rowid is returned to the child records.
Popo
Sequence + trigger is a pretty common combo. Normally people avoid fetching the sequence again (as you advised).
Popo
Could you possibly generate the PK inside the stored procedure instead of using a trigger? I can see that as being feasible if you are only inserting on the table through the stored procedure. Then you would be able to return the PK from the stored procedure because it would be accessible inside it and then you could set it to an out var.
controlfreak123
Otherwise I'm not sure if it is possible to return a non-identity column like you are proposing. Going back to the point of SO issue the reason why i was upset was because usually absolute garbage answers get downvoted past zero. I understand that it needs to be valid in a multi-user environment. The biggest issue is that you cannot return a value from a trigger. hence the suggestion to get rid of the trigger if possible.
controlfreak123
Also, how exactly is the PK generated within the trigger? There are constructs in the identity generator to modify how column values get constructed. If it is something that construct could handle you could turn the PK into an identity column and use the identity retrieve coupled with an ATOMIC block to make sure multiple users don't blow away each other's values.
controlfreak123
Hiya, sorry for the delay. I got cold and cough. I am already using an atomic block and I guess I have to stick with selecting the sequence before the insert statement inside the stored procedure.
Popo
Thats kinda what I figured was the case after investigating it myself. Its pretty sucky that you are limited that much by the version of DB2. But I'm glad you seem to have found a solution!
controlfreak123
+1  A: 

--UPDATED---

Hi Popo,

First off could you give more detail on what you mean when you say the rowid is assigned by a trigger?

If you had a real identity column you would use the IDENTITY_VAL_LOCAL() function like this right after the INSERT: SELECT IDENTITY_VAL_LOCAL() INTO myrowid FROM SYSIBM.SYSDUMMY1; I'm not 100% on that syntax because I generally use embedded SQL and it works differently there so you might have to play with it. IBM documentation is at http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/db2/rbafzscaidentity.htm.

However since you are doing something more complicated, I think this alternate method might work. You'll need to re-format your INSERT to be wrapped in a SELECT.

SELECT myrowid
INTO myrowid
FROM FINAL TABLE (
   INSERT INTO myfile (myrowid, other_stuff) VALUES (default, 'blah')
)

You'll need to adjust for the proper field names and so on but I think this will do the trick. There's not much documentation but if you want to see it go to http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/db2/rbafzbackup.htm and scroll all the way down to the bottom of the page.

Cheers

Brandon Peterson
Thanks Brandon, you are right but that solution is for DB2 release V6 R1 and I am on V5 R4. I think I have to select the sequence before the insert statement.
Popo
That sucks. It's so annoying when your system isn't up to date and you can't use the latest features. I just got our system upgraded to 6.1 a few months ago so I know where you're at.
Brandon Peterson