在 C# 中使用 Npgsql 在 PostgreSql (TimescaleDB) 中执行多行更新插入时出错

问题描述 投票:0回答:1

我尝试使用 example 推断其单行更新插入,以在 PostgrSQL/Timescale 表上执行多行更新插入,但收到以下错误:

ON CONFLICT DO UPDATE command cannot affect row a second time

SQL语句为:

INSERT INTO tablename 
(time, Column2Name, Column3Name)
 VALUES ($1, $2, $3), 
        ($1, $2, $3) 
 ON CONFLICT (time) DO UPDATE SET 
   Column2Name = excluded.Column2Name, 
   Column3Name = excluded.Column3Name;

我这样设置 Npgsql 参数:

var parameterList1 = new List<NpgsqlParameter>();
var timeParameter = new NpgsqlParameter(null, NpgsqlDbType.TimestampTZ);
timeParameter.Value = reading1.dateTimeOffsetValue.UtcDateTime;
parameterList1.Add(timeParameter); 

var column2Parameter = new NpgsqlParameter(null, NpgsqlDbType.Double);
column2Parameter = reading1.column2Value;
parameterList1.Add(column2Parameter); 
 
var column3Parameter = new NpgsqlParameter(null, NpgsqlDbType.Double);
column3Parameter = reading1.column3Value;
parameterList1.Add(column3Parameter); 


var parameterList2 = new List<NpgsqlParameter>();
var timeParameter2 = new NpgsqlParameter(null, NpgsqlDbType.TimestampTZ);
timeParameter2.Value = reading2.dateTimeOffsetValue.UtcDateTime;
parameterList2.Add(timeParameter2); 

var column2Parameter2 = new NpgsqlParameter(null, NpgsqlDbType.Double);
column2Parameter2 = reading2.column2Value;
parameterList2.Add(column2Parameter2); 
 
var column3Parameter2 = new NpgsqlParameter(null, NpgsqlDbType.Double);
column3Parameter2 = reading2.column3Value;
parameterList2.Add(column3Parameter2);

然后执行sql为:

using var connection = _dataSource.OpenConnection();
{
     using var cmd = new NpgsqlCommand(sql, connection);
     cmd.Parameters.AddRange(parameterList1.ToArray());
     cmd.Parameters.AddRange(parameterList2.ToArray());
     cmd.ExecuteNonQuery();
     connection.Close();
};

然后我收到错误:

ON CONFLICT DO UPDATE command cannot affect row a second time

我已经确认,在执行此示例时,reading1.DateTimeOffsetValue 和 Reading2.DateTimeOffsetValue 是唯一的,但传入的数据可能在要写入的数组记录中存在重复项,并且数据库中已有一条记录。

线索?

c# postgresql npgsql timescaledb
1个回答
0
投票

Timescale 支持最终回答了这个问题。占位符在整个语句中必须是唯一的,而不仅仅是每行,正确的 sql 是:

VALUES ($1, $2, $3), ($4, $5, $6)

此外,虽然更新插入将更新该时间戳处的现有行,但重要的是确保您尝试写入的新值没有任何重复的时间戳。

© www.soinside.com 2019 - 2024. All rights reserved.