C# 获取上次输入的记录postgres的id值
阅读关于类似问题的答案,并尝试了一些,但没有乐趣。我想使用PostGresql向表中添加一条记录,并将值记录在该记录的“id”列中 尝试了currval,并返回…在Id=int.Parsesqlcmd.ExecuteScalar.ToString上崩溃;你知道我做错了什么吗C# 获取上次输入的记录postgres的id值,c#,postgresql,C#,Postgresql,阅读关于类似问题的答案,并尝试了一些,但没有乐趣。我想使用PostGresql向表中添加一条记录,并将值记录在该记录的“id”列中 尝试了currval,并返回…在Id=int.Parsesqlcmd.ExecuteScalar.ToString上崩溃;你知道我做错了什么吗 try { StringBuilder command = new StringBuilder(); command.Append("resul
try
{
StringBuilder command = new StringBuilder();
command.Append("resultId BIGINT");
command.Append("INSERT INTO image_table (\"id\", \"table_name\", \"file_name\", \"image_data\", \"creation_date\") ");
command.Append("VALUES ('" + ID + "', '" + tableName + "', '" + fileName + "', @Image, (SELECT LOCALTIMESTAMP))");
command.Append("RETURNING id INTO resultId;");
//command.Append("SELECT currval('id');");
//command.Append("RETURNING id;");
//command.Append("SELECT @@IDENTITY");
using (NpgsqlCommand sqlcmd = CreateTextCommand(command.ToString(), connectionDataString))
{
sqlcmd.Parameters.AddWithValue("@Image", imageAsBytes);
Id = int.Parse(sqlcmd.ExecuteScalar().ToString());
}
}
catch (Exception ex)
{
throw (ex);
}
finally
{
CloseConnection();
}
return Id;
}
请参阅从以下位置获取最后一个插入id:
这不是我正在做的吗
更新我是用
K command.Append("INSERT INTO image_table (\"id\", \"table_name\", \"file_name\", \"image_data\", \"creation_date\") ");
command.Append("VALUES ('" + ID + "', '" + tableName + "', '" + fileName + "', @Image, (SELECT LOCALTIMESTAMP))");
command.Append("RETURNING id;");
using (NpgsqlCommand sqlcmd = CreateTextCommand(command.ToString(), connectionDataString))
{
sqlcmd.Parameters.AddWithValue("@Image", imageAsBytes);
Id = int.Parse(sqlcmd.ExecuteScalar().ToString());
}
在博士后,我通常会这样说:
WITH inserts as (
INSERT INTO image_table (feature_id, table_name, file_name, image_data, creation_date)
VALUES (. . .)
RETURNING *
)
SELECT id
FROM inserts;
然后,您可以从任何SELECT查询中获取值。您似乎已经找到了解决方案,但要澄清的是,一个问题似乎是:
command.Append("resultId BIGINT");
command.Append("INSERT INTO image_table ... ");
这是一个迫在眉睫的问题,因为使用Append时,它实际上会将两个字符串连接起来:
resultId BIGINTINSERT INTO image_table ...
^^
注意BIGINT和INSERT之间缺少空格。如果在将来的工作中使用AppendLine而不是Append,它可以帮助防止意外的字符串混搭
值得一提的是,您对图像使用了bind变量,这是完全合适的,但最好对所有传递的值使用bind变量,而不是文字
绑定变量:
NpgsqlConnection conn = new NpgsqlConnection(connectionDataString);
conn.Open();
StringBuilder command = new StringBuilder();
command.Append("INSERT INTO image_table ");
command.Append("\"id\",\"table_name\",\"file_name\",\"image_data\",\"creation_date\") ");
command.Append("VALUES (:ID, :TABLENAME, :FILENAME, :IMAGE, current_timestamp) ");
command.Append("RETURNING id");
NpgsqlCommand cmd = new NpgsqlCommand(command.ToString(), conn);
cmd.Parameters.AddWithValue("ID", ID);
cmd.Parameters.AddWithValue("TABLENAME", tableName);
cmd.Parameters.AddWithValue("FILENAME", fileName);
cmd.Parameters.AddWithValue("IMAGE", imageAsBytes);
int Id = Convert.ToInt32(cmd.ExecuteScalar());
conn.Close();
使用C和RDBMS之间的数据类型来管理所有不好的地方
如果您的字符串包含有趣的字符(即一个会导致SQL无法编译的单引号),则可以消除复杂性
无需在SQL中“引用”非数值
保护您的代码不受SQL注入的影响
对数据库更友好,因为它只编译一次SQL,并且可能使用不同的值反复执行SQL
以下是转换为使用所有绑定变量的代码:
NpgsqlConnection conn = new NpgsqlConnection(connectionDataString);
conn.Open();
StringBuilder command = new StringBuilder();
command.Append("INSERT INTO image_table ");
command.Append("\"id\",\"table_name\",\"file_name\",\"image_data\",\"creation_date\") ");
command.Append("VALUES (:ID, :TABLENAME, :FILENAME, :IMAGE, current_timestamp) ");
command.Append("RETURNING id");
NpgsqlCommand cmd = new NpgsqlCommand(command.ToString(), conn);
cmd.Parameters.AddWithValue("ID", ID);
cmd.Parameters.AddWithValue("TABLENAME", tableName);
cmd.Parameters.AddWithValue("FILENAME", fileName);
cmd.Parameters.AddWithValue("IMAGE", imageAsBytes);
int Id = Convert.ToInt32(cmd.ExecuteScalar());
conn.Close();
使用参数来创建SQL语句,而不是字符串连接,您的代码容易出现SQL错误。同样看到这个问题,它应该是重复的:检查这些主题:你得到了哪一个错误?谢谢你的回答,但不起作用..请看原始的Q…我如何捕获返回值?@John。我认为您会像使用任何SELECT一样使用ExecuteQuery。