Actual inserted row ID - sql-server

I have created table in my db in this statement
CREATE TABLE tPerson
(
id INT NOT NULL PRIMARY KEY identity(1,1)
, name NVARCHAR(100) not null
, email NVARCHAR(30) not null
)
GO
Now I insert new value with INSERT. My question is how can I get id of current added row? Any idea ??

Assuming SQL server, you should check out this article to gain a good understanding of retrieving identities.
Here's a snippet:
SELECT ##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.
##IDENTITY will return the last identity value entered into a table in
your current session. While ##IDENTITY is limited to the current
session, it is not limited to the current scope. If you have a trigger
on a table that causes an identity to be created in another table, you
will get the identity that was created last, even if it was the
trigger that created it.
SELECT 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. SCOPE_IDENTITY(), like ##IDENTITY, will
return the last identity value created in the current session, but it
will also limit it to your current scope as well. In other words, it
will return the last identity value that you explicitly created,
rather than any identity that was created by a trigger or a user
defined function.
SELECT 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. IDENT_CURRENT is not limited by scope and session; it is
limited to a specified table. IDENT_CURRENT returns the identity value
generated for a specific table in any session and any scope.

It looks like SQL Server, and it that case, just use:
INSERT INTO dbo.tPerson(....) VALUES(.....)
DECLARE #NewID INT
SELECT #NewID = SCOPE_IDENTITY()
SCOPE_IDENTITY returns the last inserted IDENTITY value in this current scope.
Side note: "email" is only 30 characters long!?!? I typically make that the longest column in my table - 200 chars or even more :-)

Use ##IDENTITY or SCOPE_IDENTITY for MS SQL Server :)

Try
SELECT ##IDENTITY AS LastID
after your INSERT

You can also do this through JDBC directly to avoid the need to select, as typically an insert statement will return the number of rows inserted which you may want to validate. Spring supports this through its JdbcTemplate, see here

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

Retrieving new rowversion after INSERT using ##DBTS - is it safe?

It is common practice to pick up the newly created IDENTITY of a table using the ##IDENTITY variable after an INSERT.
Is it just equality correct to retrieve the last rowversion value following an UPDATE in a similar manner using the ##DBTS value?
For example:
IF(OBJECT_ID('XXX') IS NOT NULL)
DROP TABLE XXX
GO
CREATE TABLE XXX
(
ID int IDENTITY(1,1) PRIMARY KEY,
Name varchar(64) NOT NULL,
RV rowversion
)
GO
INSERT INTO XXX(Name) VALUES
('Apples'),('Bananas'),('Cranberries'),('Dragon Fruit'),('Eggplant'),('Fig'),('Grape')
GO
SELECT * FROM XXX
GO
UPDATE XXX
SET Name = 'Chocolate' WHERE ID = 3
PRINT ##DBTS
GO
Now is ##DBTS safe from concurrent updates?
If another connection performs insert and updates between the UPDATE and the PRINT, would we end up with the rowversion of the 'other' connection rather than the one from our own update?
According to MSDN ##DBTS
returns the last-used timestamp value of the current database
This means it is not thread safe.
You also should not use ##IDENTITY. ##IDENTITY and SCOPE_IDENTITY return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; ##IDENTITY is not limited to a specific scope. ##IDENTITY can for example return the wrong value if a trigger gets executed on a table with an identity column.

What is the difference between scope_identity() and current_identity()?

What is the difference between scope_identity() and current_identity()?
Scope_identity and current _identity both are similar and it will return the last identity value generated in the table.
Scope_Identity will return the identity value in table that is currently in scope
is it correct definition for this question?
IDENT_CURRENT is similar to the SQL Server 2000 identity functions SCOPE_IDENTITY and ##IDENTITY. All three functions return last-generated identity values.
However, the scope and session on which last is defined in each of these functions differ:
IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
##IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.
Source
##IDENTITY
It returns the last identity value generated for any table in the current session, across all scopes.
Let me explain this... suppose we create an insert trigger on table which inserts a row in another table with generate an identity column, then ##IDENTITY returns that identity record which is created by trigger.
SCOPE_IDENTITY
It returns the last identity value generated for any table in the current session and the current scope.
Let me explain this... suppose we create an insert trigger on table which inserts a row in another table with generate an identity column, then SCOPE_IDENTITY result is not affected but if a trigger or a user defined function is affected on the same table that produced the value returns that identity record then SCOPE_IDENTITY returns that identity record which is created by trigger or a user defined function.
IDENT_CURRENT
It returns the last identity value generated for a specific table in any session and any scope.
In other words, we can say it is not affected by scope and session, it only depends on a particular table and returns that table related identity value which is generated in any session or scope.
find here

Inserting a identity column value into another table

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

SQL: How to get the id of values I just INSERTed?

I inserted some values into a table. There is a column whose value is auto-generated. In the next statement of my code, I want to retrieve this value.
Can you tell me how to do it the right way?
##IDENTITY is not scope safe and will get you back the id from another table if you have an insert trigger on the original table, always use SCOPE_IDENTITY()
This is how I do my store procedures for MSSQL with an autogenerated ID.
CREATE PROCEDURE [dbo].[InsertProducts]
#id INT = NULL OUT,
#name VARCHAR(150) = NULL,
#desc VARCHAR(250) = NULL
AS
INSERT INTO dbo.Products
(Name,
Description)
VALUES
(#name,
#desc)
SET #id = SCOPE_IDENTITY();
This works very nicely in SQL 2005:
DECLARE #inserted_ids TABLE ([id] INT);
INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6])
OUTPUT INSERTED.[id] INTO #inserted_ids
VALUES (#col1,#col2,#col3,#col4,#col5,#col6)
It has the benefit of returning all the IDs if your INSERT statement inserts multiple rows.
If your using PHP and MySQL you can use the mysql_insert_id() function which will tell you the ID of item you Just instered.
But without your Language and DBMS I'm just shooting in the dark here.
Again no language agnostic response, but in Java it goes like this:
Connection conn = Database.getCurrent().getConnection();
PreparedStatement ps = conn.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);
try {
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
rs.next();
long primaryKey = rs.getLong(1);
} finally {
ps.close();
}
If you are working with Oracle:
Inset into Table (Fields....) values (Values...) RETURNING (List of Fields...) INTO (variables...)
example:
INSERT INTO PERSON (NAME) VALUES ('JACK') RETURNING ID_PERSON INTO vIdPerson
or if you are calling from... Java with a CallableStatement (sry, it's my field)
INSERT INTO PERSON (NAME) VALUES ('JACK') RETURNING ID_PERSON INTO ?
and declaring an autput parameter for the statement
There's no standard way to do it (just as there is no standard way to create auto-incrementing IDs). Here are two ways to do it in PostgreSQL. Assume this is your table:
CREATE TABLE mytable (
id SERIAL PRIMARY KEY,
lastname VARCHAR NOT NULL,
firstname VARCHAR
);
You can do it in two statements as long as they're consecutive statements in the same connection (this will be safe in PHP with connection pooling because PHP doesn't give the connection back to the pool until your script is done):
INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George');
SELECT lastval();
lastval() gives you the last auto-generated sequence value used in the current connection.
The other way is to use PostgreSQL's RETURNING clause on the INSERT statement:
INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;
This form returns a result set just like a SELECT statement, and is also handy for returning any kind of calculated default value.
An important note is that using vendor SQL queries to retrieve the last inserted ID are safe to use without fearing about concurrent connections.
I always thought that you had to create a transaction in order to INSERT a line and then SELECT the last inserted ID in order to avoid retrieving an ID inserted by another client.
But these vendor specific queries always retrieve the last inserted ID for the current connection to the database. It means that the last inserted ID cannot be affected by other client insertions as long as they use their own database connection.
For SQL 2005:
Assuming the following table definition:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[somevalue] [nchar](10) NULL,
)
You can use the following:
INSERT INTO Test(somevalue)
OUTPUT INSERTED.ID
VALUES('asdfasdf')
Which will return the value of the ID column.
From the site i found out the following things:
SQL SERVER – ##IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT – Retrieve Last Inserted Identity of Record
March 25, 2007 by pinaldave
SELECT ##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.
##IDENTITY will return the last identity value entered into a table in your current session. While ##IDENTITY is limited to the current session, it is not limited to the current scope. If you have a trigger on a table that causes an identity to be created in another table, you will get the identity that was created last, even if it was the trigger that created it.
SELECT 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.
SCOPE_IDENTITY(), like ##IDENTITY, will return the last identity value created in the current session, but it will also limit it to your current scope as well. In other words, it will return the last identity value that you explicitly created, rather than any identity that was created by a trigger or a user defined function.
SELECT 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.
IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope.
Remember that ##IDENTITY returns the most recently created identity for your current connection, not necessarily the identity for the recently added row in a table. You should always use SCOPE_IDENTITY() to return the identity of the recently added row.
What database are you using? As far as I'm aware, there is no database agnostic method for doing this.
This is how I've done it using parameterized commands.
MSSQL
INSERT INTO MyTable (Field1, Field2) VALUES (#Value1, #Value2);
SELECT SCOPE_IDENTITY();
MySQL
INSERT INTO MyTable (Field1, Field2) VALUES (?Value1, ?Value2);
SELECT LAST_INSERT_ID();
sql = "INSERT INTO MyTable (Name) VALUES (#Name);" +
"SELECT CAST(scope_identity() AS int)";
SqlCommand cmd = new SqlCommand(sql, conn);
int newId = (int)cmd.ExecuteScalar();
Ms SQL Server: this is good solution even if you inserting more rows:
Declare #tblInsertedId table (Id int not null)
INSERT INTO Test ([Title], [Text])
OUTPUT inserted.Id INTO #tblInsertedId (Id)
SELECT [Title], [Text] FROM AnotherTable
select Id from #tblInsertedId
Rob's answer would be the most vendor-agnostic, but if you're using MySQL the safer and correct choise would be the built-in LAST_INSERT_ID() function.
SELECT ##Scope_Identity as Id
There is also ##identity, but if you have a trigger, it will return the results of something that happened during the trigger, where scope_identity respects your scope.
insert the row with a known guid.
fetch the autoId-field with this guid.
This should work with any kind of database.
An Environment Based Oracle Solution:
CREATE OR REPLACE PACKAGE LAST
AS
ID NUMBER;
FUNCTION IDENT RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY LAST
AS
FUNCTION IDENT RETURN NUMBER IS
BEGIN
RETURN ID;
END;
END;
/
CREATE TABLE Test (
TestID INTEGER ,
Field1 int,
Field2 int
)
CREATE SEQUENCE Test_seq
/
CREATE OR REPLACE TRIGGER Test_itrig
BEFORE INSERT ON Test
FOR EACH ROW
DECLARE
seq_val number;
BEGIN
IF :new.TestID IS NULL THEN
SELECT Test_seq.nextval INTO seq_val FROM DUAL;
:new.TestID := seq_val;
Last.ID := seq_val;
END IF;
END;
/
To get next identity value:
SELECT LAST.IDENT FROM DUAL
In TransactSQL, you can use OUTPUT clause to achieve that.
INSERT INTO my_table(col1,col2,col3) OUTPUT INSERTED.id VALUES('col1Value','col2Value','col3Value')
FRI: http://msdn.microsoft.com/en-us/library/ms177564.aspx
Simplest answer:
command.ExecuteScalar()
by default returns the first column
Return Value
Type: System.Object
The first column of the first row in the result set, or a null reference (Nothing in Visual Basic) if the result set is empty. Returns a maximum of 2033 characters.
Copied from MSDN

Resources