代码之家  ›  专栏  ›  技术社区  ›  Jeremy Holovacs

Npgsql:准备好的语句“\u p1”不存在

  •  0
  • Jeremy Holovacs  · 技术社区  · 7 年前

    我正在尝试使用以下方法将EOD库存数据加载到表中:

        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 "$1" 消失 在几个方法调用之后,我开始 Npgsql.PostgresException (0x80004005): 26000: prepared statement "_p1" does not exist

    有人能解释一下这种行为吗?我做错什么了?我从哪里可以得到更多关于“1美元”的细节呢?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Łukasz Kamiński    7 年前

    插入的值周围缺少括号。遗憾的是,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)