Npgsql:准备好的语句“_p1”不存在

Npgsql: prepared statement "_p1" does not exist

我正在尝试使用此方法将 EOD 库存数据加载到 table:

    public async Task<long> BulkInsertEodData(IEnumerable<EodData> records, string symbol)
    {
        var recordsProcessed = 0L;
        using (var conn = await OpenConnection())
        using (var trans = conn.BeginTransaction())
        using (var comm = _factory.CreateCommand())
        {
            try
            {
                comm.Connection = conn;
                comm.Transaction = trans;
                comm.CommandText = INSERT_EOD;
                var ps = AddParametersToInsertEodQuery(comm);
                foreach (var p in ps) comm.Parameters.Add(p);
                comm.Prepare();

                foreach (var record in records)
                {
                    comm.Parameters["@date_id"].Value = record.DateId;
                    comm.Parameters["@symbol"].Value = symbol.ToUpper();
                    comm.Parameters["@eod_close"].Value = record.EodClose;
                    comm.Parameters["@eod_high"].Value = record.EodHigh;
                    comm.Parameters["@eod_low"].Value = record.EodLow;
                    comm.Parameters["@eod_volume"].Value = record.EodVolume;
                    comm.Parameters["@eod_open"].Value = record.EodOpen;
                    comm.Parameters["@eod_split"].Value = record.EodSplit;
                    comm.Parameters["@eod_dividend"].Value = record.EodDividend;
                    comm.Parameters["@last_modified"].Value = DateTime.UtcNow;
                    await comm.ExecuteNonQueryAsync();
                    recordsProcessed++;
                }

                trans.Commit();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "BulkInsertEodData(IEnumerable<EodData>)");
                trans.Rollback();
            }
        }

        return recordsProcessed;
    }

查询文字如下:

        INSERT INTO public.eod_datas(
            date_id, 
            stock_id, 
            eod_open, 
            eod_close, 
            eod_low, 
            eod_high, 
            eod_volume, 
            eod_dividend, 
            eod_split, 
            last_modified_timestamp
        )
        values
            @date_id, 
            (select s.id from stocks s where s.symbol = @symbol limit 1), 
            @eod_open, 
            @eod_clos, 
            @eod_low, 
            @eod_high, 
            @eod_volume, 
            @eod_dividend, 
            @eod_split, 
            current_timestamp
        on conflict (date_id, stock_id)
        do update set 
            eod_open = @eod_open, 
            eod_close = @eod_close, 
            eod_low = @eod_low, 
            eod_high = @eod_high, 
            eod_volume = @eod_volume, 
            eod_dividend = @eod_dividend, 
            eod_split = @eod_split, 
            last_modified_timestamp = current_timestamp;

这不是我第一次使用准备好的语句,但这次我做了一些不同的事情(.NET Core,使用 DbProviderFactory),我得到了奇怪的结果。

通过这种方法的前几次,我得到了一个错误 Npgsql.PostgresException (0x80004005): 42601: syntax error at or near "" 这本身就很神秘,但最神秘的是错误实际上是 away 在几次方法调用之后,我开始得到 Npgsql.PostgresException (0x80004005): 26000: prepared statement "_p1" does not exist 一致的后记。

有人可以解释这种行为吗?我究竟做错了什么?我在哪里可以获得更多关于“$1”的详细信息?

插入的值周围缺少括号。遗憾的是,Postgres 不会告诉您它在 $1 之前需要括号。

正确的语法:

values (
    @date_id, 
    (select s.id from stocks s where s.symbol = @symbol limit 1), 
    @eod_open, 
    @eod_clos, 
    @eod_low, 
    @eod_high, 
    @eod_volume, 
    @eod_dividend, 
    @eod_split, 
    current_timestamp)
on conflict (date_id, stock_id)