I'm trying to insert a row into a PostgreSQL table with a serial primary key and I need to retrieve this column after it was inserted. I got something like this:
The table "pais" has 3 columns: id, pais, capital; id is a serial column and is its primary key.
NpgsqlCommand query = new NpgsqlCommand("insert into pais(nombre, capital) values(@nombre, @capital)", conn);
query.Parameters.Add(new NpgsqlParameter("nombre", NpgsqlDbType.Varchar));
query.Parameters.Add(new NpgsqlParameter("capital", NpgsqlDbType.Varchar));
query.Prepare();
query.Parameters[0].Value = this.textBox1.Text;
query.Parameters[1].Value = this.textBox2.Text;
Object res = query.ExecuteScalar();
Console.WriteLine(res);
It inserts the row on the table but "res" value is null. If I insert with the nexval('table_sequence') also returns null.
Any idea of how can I return the id of the table? Am I missing something?
Thanks in advance
The insert itself does not cause a value to be returned. When you perform ExecuteScalar it is looking for a single value to be "Selected" so to speak.
I believe you need to follow up your insert with a select statement to solve your issue.
If you were using t-sql you would do this like so
string sql = "INSERT INTO [Table] (FieldName) VALUES (@ParamName); " + "SELECT CAST(scope_identity() AS int)";
ExecuteScalar would then return the unique id;
I am not sure of the exact syntax for postGresql but hopefully this allows you to solve your issue.
replace
id
with your primary keyenter code here
and useInside
res
you'll have the PK.In order to select the last identity inserted you need to use:
currval(sequencename)
so your select statement should look like:
Is that thread safe?
What if another insert happens between your insert and select? Why not use:
INSERT INTO table (fieldnames) VALUES (values) RETURNING idcolumn
?