'Return ID of newly inserted row on a PostgreSQL database using C# and Npgsql?
I'm building a WinForms project in C# using a PostgreSQL database and the Npgsql framework.
For inserting a record, I need to return the ID of the new record. This SO question says to add SELECT SCOPE_IDENTITY()
to the query string passed to cmd. So my query string looks like this:
string insertString = "INSERT INTO sometable (company_name, category, old_value, old_desc, new_value, new_desc, reference1, reference2) VALUES (@comp, @cat, @oldValue, @oldDesc, @newValue, @newDesc, @ref1, @ref2); SELECT SCOPE_IDENTITY();";
and then get the ID with something like
int modified = cmd.ExecuteNonQuery();
But that's likely SQL Server-specific. If I use that method, I get an exception at the above line saying, "fuction scope_identity() does not exist".
I wasn't able to find anything that seemed to address this on the Npgsql documentation.
Per the linked SO question and Denis' suggestions I've tried adding both
RETURNING id;
and
CURRVAL(pg_get_serial_sequence('my_tbl_name','id_col_name'))
to the query string, replacing SELECT SCOPE_IDENTITY();
with those statements in the code above. In both cases they work as intended in DBeaver on an insert, but in my C# code in my WinForm project, modified was set to "1".
NOTE: I re-titled the question and added more information about what I've done.
Solution 1:[1]
Add "returning idcolumn" to the end of the sql query, then run the command with the ExecuteScalar() method instead of ExecuteNonQuery(). It should return with an int.
string insert = "insert into table1 (col1) values (something) returning idcol";
int id = cmd.ExecuteScalar();
Solution 2:[2]
All the comments above were almost nearly spot on and got me to a solution but didn't exactly wrap it in a bow -- so I thought i'd post my implementation that works (with silly fake example tables of course).
private int? InsertNameIntoNamesTable(string name)
{
int? id = null;
using (var dbcon = new NpgsqlConnection(_connectionString))
{
dbcon.Open();
StringBuilder sb = new StringBuilder();
var sql = $@"
insert into names_table
(name)
values
({name})
returning id;
";
sb.Append(sql);
using (var cmd = new NpgsqlCommand(sql, dbcon))
{
id = (int)cmd.ExecuteScalar();
}
dbcon.Close();
}
return id;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | user3567816 |
Solution 2 | Jason Roos |