Inserting a identity column value into another table - sql-server

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...

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

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.

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.

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 ....)

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.

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

Related

Issue ##IDENTITY AND IDENT_CURRENT(tableName) SQL SERVER

After INSERT record to the table with an identity column
I try to get identified by the way SELECT ##IDENTITY but it returns NULL,
but I try to use ;
SELECT IDENT_CURRENT ('tableName')
this statement return I'm expected value
You shouldn't use ##Identity, nor should you use ident_current().
The first answers a question that you probably don't want to ask, and the second is unreliable, according to SQL Server expert Aaron Bertrand (or, at least, that was the case back in January 2014, when this article was published).
You should be using the output clause if you're inserting more than one record, or scope_identity() if you're only inserting one.
Note that the output clause doesn't play nice with triggers, and scope_identity() will have problems if your target table have an instead of insert trigger.
For more information, you can read Use the right tool to get identity values back after an insert over on my blog.
IDENT_CURRENT() returns the last inserted identity value for a given table.
SCOPE_IDENTITY() returns the last identity value inserted into an identity column in any table in the current session and current scope.
Probably you execute SCOPE_IDENTITY() in the other session

SQL Server add auto serial id to additional field during insert

I have an insert statement in a stored procedure who's primary key is a serial id. I want to be able to populate an additional field in the same table during the same insert statement with the serial id used for the primary key. Is this possible?
Unfortunately this is a solution already in place... I just have to implement it.
Regards
I can't imagine a reason why you would want a copy of the key in another column. But in order to do it, I think you'll need to follow your update with a statement to get the value of the identity key, and then an update to put that value in the other column. Since you're already in a stored procedure, it's probably ok to have a few extra statements, instead of doing it in the very same one.
DECLARE #ID INT;
INSERT INTO TABLE_THINGY (Name, Address) VALUES ('Joe Blow', '123 Main St');
SET #ID = SCOPE_IDENTITY();
UPDATE TABLE_THINGY SET IdCopy = #Id WHERE ID = #ID
If it's important that this be done every single time, you might want to create a Trigger to do it; beware, however, that many people hate triggers because of the obfuscation and difficulty in debugging, among other reasons.
http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/
I agree, it is odd that you would replicate the key within the same table but with that said you could use a trigger, thus making it have no impact to current insert statements.
The below trigger is "After Insert" so technically it happens milliseconds after the insert if you truly wanted it to happen at the same time you would use a FOR INSERT instead and just replicate the logic used to create the serial id field into the new field.
CREATE TRIGGER triggerName ON dbo.tableName
AFTER INSERT
AS
BEGIN
update dbo.tableName set newField = inserted.SerialId where serialId = inserted.SerialId
END
GO
You could have a computed column that just returns the id column.
CREATE TABLE dbo.Products
(
ProductID int IDENTITY (1,1) NOT NULL
, OtherProductID AS ProductID
);
Having said that, data should only live in one place and to duplicate it in the same table is just a wrong design.
No, you cannot use the same insert statement for identity Id and copy that auto generated Id to the same row.
Multi-Statement using OUTPUT inserted or Trigger is your best bet.

Getting the primary key of an newly inserted row in SQL Server 2008

I have a bunch of data which will insert into a table. This issue is that I need it to return the primary key to that table. I wasn't sure if there was things like:
insert into TABLE (...) values (...) RETURNING p_key
or
select p_key from (insert into TABLE (...) values (...))
I am making a workaround for a browser and saved information which will more or less add a row and then update it... but without the primary key, there is no way to update it as there is no reference to it.
I was looking online and found some examples via google, but it confused me slightly with these examples.
http://en.wikipedia.org/wiki/Insert_(SQL)#Retrieving_the_key
http://www.daniweb.com/web-development/databases/ms-sql/threads/299356/returning-identity-of-last-inserted-row-uniqueidentifier
Wikipedia was saying that for SQL Server 2008 to use OUTPUT instead of RETURNING, possible to use something like OUTPUT p_key
If you're inserting a whole set of rows, selecting the SCOPE_IDENTITY() won't do. And SCOPE_IDENTITY also only works for (numeric) identity columns - sometimes your PK is something else...
But SQL Server does have the OUTPUT clause - and it's very well documented on MSDN!
INSERT INTO dbo.Table(columns)
OUTPUT INSERTED.p_key, INSERTED.someothercolumnhere .......
VALUES(...)
Those values will be "echoed" back to the calling app, e.g. you'll see them in a grid in SQL Server Management Studio, or you can read them as a result set from your C# or VB.NET calling this INSERT statement.
Scope_Identity() is what you want, assuming that by "primary key" you mean "Identity"
declare #id int
insert yourtable values (some, values)
select #id = Scope_Identity()
In C#, right after your SQL Statement write SELECT SCOPE_IDENTITY(); so your code would be:
insert into TABLE (...) values (...); SELECT SCOPE_IDENTITY();
then, instead of executeNonQuery use executeScalar.
That should do the trick!
After performing insert, query:
select scope_identity()
to retrieve last inserted primary key.
Using ##IDENTITY , you can get the last generated primary key
Insert into TableName (Name,Class) values('ABC','pqr')
select ##IDENTITY

Will a trigger be able to copy a primary key that's an identity id?

I want to do after I an INSERT in table X to copy that record into another History table immediately.
Now the table has the primary key as an Identity column, so the record won't have an primary key id until it is actually inserted.
My question is if I do a trigger on this record will I get the identity id for that record or will it still be blank?
Yes the identity is available in the trigger but make sure you get that id correctly.
##identity, SCOPE_IDENTITY etc are NOT what you want to do in a trigger!
SELECT #id = id FROM inserted
Is also a bad idea.
Always write your triggers to expect multiple changes being made simultaneously. The above approaches will all cause subtle but important errors when you insert more than one record into the table at a time.
The correct approach is to insert into your audit table FROM the inserted table
i.e.
INSERT INTO myAuditTable(Id, Datetime, user)
SELECT id, GETDATE(), USER_NAME())
FROM inserted
if you do the 'after insert' trigger, the record is already there with a value for the identity column.
Just make sure you declare the trigger as "AFTER" insert, not "FOR" or "INSTEAD OF" (guess you wouldn't use the last one... ;)
http://msdn.microsoft.com/en-us/library/ms189799.aspx

How to increment (or reserve) IDENTITY value in SQL Server without inserting into table

Is there a way to reserve or skip or increment value of identity column?
I Have two tables joined in one-to-one relation ship. First one has IDENTITY PK column, and second one int PK (not IDENTITY). I used to insert in first, get ID and insert in second. And it works ok.
Now I need to insert values in second table without inserting into first.
Now, how to increment IDENTITY seed, so I can insert it into second table, but leave "hole" in ID's of first table?
EDIT: More info
This works:
-- I need new seed number, but not table row
-- so i will insert foo row, get id, and delete it
INSERT INTO TABLE1 (SomeRequiredField) VALUES ('foo');
SET #NewID = SCOPE_IDENTITY();
DELETE FROM TABLE1 WHERE ID=#NewID;
-- Then I can insert in TABLE2
INSERT INTO (ID, Field, Field) VALUES (#NewID, 'Value', 'Value');
Once again - this works.
Question is can I get ID without inserting into table?
DBCC needs owner rights; is there a clean user callable SQL to do that?
This situation will make your overall data structure very hard to understand. If there is not a relationship between the values, then break the relationship.
There are ways to get around this to do what you are looking for, but typically it is in a distributed environment and not done because of what appears to be a data model change.
Then its no more a one-to-one relationship.
Just break the PK constraint.
Use a DBCC CHECKIDENT statement.
This article from SQL Server Books Online discusses the use of the DBCC CHECKIDENT method to update the identity seed of a table.
From that article:
This example forces the current identity value in the jobs table to a value of 30.
USE pubs
GO
DBCC CHECKIDENT (jobs, RESEED, 30)
GO
I would look into the OUTPUT INTO feature if you are using SQL Server 2005 or greater. This would allow you to insert into your primary table, and take the IDs assigned at that time to create rows in the secondary table.
I am assuming that there is a foreign key constraint enforced - because that would be the only reason you would need to do this in the first place.
How do you plan on matching them up later? I would not put records into the second table without a record in the first, that is why it is set up in a foreign key relationship - to stio that sort of action. Just why do you not want to insert records into the first table anyway? If we knew more about the type of application and why this is necessary we might be able to guide you to a solution.
this might help
SET IDENTITY_INSERT [ database_name . [ schema_name ] . ] table { ON | OFF }
http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx
It allows explicit values to be inserted into the identity column of a table.

Resources