1

Good Morning. I have two tables, and one references the other. When I insert into the primary table, the primary key is auto-generated, viz Identity field. I need to insert this value into the second table.

I found out using the OUTPUT clause will give me the just inserted identity value, ans so I tried this.

insert into owners (pId) 
   insert into personal (firstName) 
   output inserted.pId 
   values ('fn')

It doesn't work though. I get an error:

Incorrect syntax near the keyword 'insert'

The personal table is the primary table, and the owners table contains the foreign key. How can I do the required in SQL Server?

I've got stuck-up here for the past two days...

2
  • can you post the structure of both the tables? Commented Jun 21, 2012 at 4:37
  • Would you like me to post the entire structure, or just the corresponding fields will do?? Commented Jun 21, 2012 at 4:44

6 Answers 6

4

I think you just have your syntax slightly off - you can definitely take values inserted into the main table and use the OUTPUT clause to insert those into a secondary table.

INSERT INTO dbo.personal(firstName) 
OUTPUT INSERTED.pId INTO dbo.owners(pId) 
VALUES('fn')

This will insert a new row into personal and set the column firstName to fn. From that insert, the inserted row's identity column pId is then inserted into the other table, owners, as that table's pId column.

See the MSDN documentation on the OUTPUT clause for more details - you can either output any of the inserted values to the console (e.g. SQL Server Mgmt Studio), or you can output those values into a temporary or a permanent table.

Update: as 'dradu' has pointed out - this approach won't work in your case here, since the column in the owners table is part of a FK constraint (I had missed that point from your question). So you'll need to use some other way to do this - probably outputting the necessary information into a temporary table / table variable in your code

Sign up to request clarification or add additional context in comments.

7 Comments

I don't think the OUTPUT clause will work directly because the owners table participates in the foreign key constraint. From MSDN link you've mentioned: output_table cannot: Have enabled triggers defined on it; Participate on either side of a FOREIGN KEY constraint; Have CHECK constraints or enabled rules.
@marc_s no, the owners table doesnt just contain the field pId. I need this to be auto updated, adn the other values, i gotta insert on my own.
@Anudeep Bulla: So you started off with the wrong SQL statement, you got correct answers that worked in some conditions, but you are not happy with them because they don't work in some circumstances you didn't specify. Maybe you should have made the question clearer or make up your mind about what you really want to achieve. It's not the community job to extract information about your question.
@dradu: yup, you're right - in this situation here, this approach using the OUTPUT clause will not work. I had missed that fact that the column in "owners" is taking part in a FK relationship. For other cases, this approach however works quite nicely and efficiently
I agree with you, the OUTPUT clause is very nice. Your answer still worth upvoting :)
|
3

Try the following steps

1) Apply transaction level on insertion

2) Get last inserted id using Scope_Identity() function.

When you apply transaction level it will lock your tables and other/same user cannot insert the value in this time.

try this it will work for you.

4 Comments

can you plz explain transaction level?? i believe me explicitly locking the tales ill work, but i wanted to know if there as a easy ay out...
When you apply transaction level it locks the tables that you are using in this transaction and release table locking when you finish the transaction. During Transaction other request will be queued by Sql server and after completion of this transaction other request will be completed. I suggest you have to use transaction level i.e Begin Trans ....... Commit Trans in your code this will avoid any other user to perform insertion in same time. Thanks
Does transactions definitely lock the tables involved? I mean, wont it be a real performance bottleneck?
Yes its definitely lock the tables, you can try it Open a sql server session and Only give Begin Tran and then insert into table and dont commit it like Begin Tran Insert into dbo.tblKeyValuesSettings Values ('12','Desc') open another session and then select the insert table like Select * from dbo.tblKeyValuesSettings you can see the table is locked in this time. and in your case performance is not matter of concern because when you are only inserting into two tables.
3

Since OUTPUT clause cannot be used directly because of the foreign key, you could add the generated IDs into a temporary table, then insert those values into the owners table:

BEGIN TRANSACTION 

CREATE TABLE #ids(ID INT)
INSERT INTO personal(firstName)
    OUTPUT inserted.pid INTO #ids
    SELECT 'A'
    UNION SELECT 'B'

INSERT INTO owners(pid)
    SELECT ID FROM #ids

COMMIT TRANSACTION

SCOPE_IDENTITY will work too, but it's limited to one value.

2 Comments

what is the life time and scope of a temporary table? I mean, can other similar statements, but with a different scope insert into iy??
The local temporary table is available to the current connection only. You can have global temporary tables (marked with ##) which are available to all connections. See MSDN.
2

You can use the SCOPE_IDENTITY() function to return the identity value inserted.

DECLARE @id INT
INSERT INTO [Personal] (Colums ....) VALUES (this, that, stuff)
SET @id = SCOPE_IDENTITY()

INSERT INTO [Owners] (Colums ....) VALUES (@id ....)

8 Comments

I understand SCOPE_IDENTITY gives the last inserted identity in a given scope, but not necessarily on the given table... The application is hosted on the net, and multiple users acting won't give me the exact result i guess. For example, after i update table personal, other/same users can update other tables before the insert into owners gets executed.The SCOPE_IDENTITY will then give me the latest identity value, but not from the table personal. Or am I wrong??
Sorry I am not sure if I understand what you are saying, can you clarify your question?
different users has different scope. so SCOPE_IDENTITY() will return identity from the same scope. and you will never have that conflict, you are mentioning
I wanna insert a value into table personal. The primary key column on this table is on IDENTITY , and so it will then generate a new id. I need to map THIS id and insert it into the table owners. The problem with scope_identity is it even takes into account other tables.
have you applied transaction level on your insertion ??
|
2

I think Your option is to use SCOPE_IDENTITY() but the other closest to your option is IDENT_CURRENT(‘tablename’) so I thought, I post detail of detail of other identity options as well which might help you to understand your choice and might helpful some other time

@@IDENTITY It returns the last IDENTITY value produced on a connection, regardless of the table that produced the value, and regardless of the scope of the statement that produced the value.


SCOPE_IDENTITY() It returns the last IDENTITY value produced on a connection and by a statement in the same scope, regardless of the table that produced the value.


IDENT_CURRENT(‘tablename’) It returns the last IDENTITY value produced in a table, regardless of the connection that created the value, and regardless of the scope of the statement that produced the value.

1 Comment

I think all three won't do... The problem is, multiple users will be working from different scopes, on different tables. I need to find the identity value of the given tuple I just inserted. Please note the words I and given tuple. I mean I can't have results from other tables, or scopes interfering...
0

Here is one simple example of using SCOPE_IDENTITY() to get recent Identity Value http://msdn.microsoft.com/en-us/library/ms190315.aspx

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.