在事务中使用 Npgsql 的 Where 子句中出现 DateTime 异常,无需事务即可工作

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

并非总是如此,但有时我会遇到例外:
“42846:无法将整数类型转换为带时区的时间戳 位置:150 英寸

但是现在(在我的数据集中)的所有输入都是相同的。
“2023-06-30 22:00:00+00” “2023-07-31 21:59:59+00”

只有 ean 发生了变化,但有些更新有效,有些则无效。

发现只有当列 id 有多行时才会出现异常。
因此,当 foreach 在我的代码中有不止一次迭代时。
| “身份证” | “伊恩”| “到”| “来自” | “CelkomBezDPH” | “CelkomIbaDPH”| “CelkomPlusDPH” | |---|---|---|---|---|---|---| | 205230110 | “123456789012345678” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” | 1 | 2 | 3 | | 205230111 | “123456789012345679” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” |南|南|南| | 205230111 | “123456789012345680” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” |南|南|南| | 205230112 | “123456789012345681” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” | 1 | 2 | 3 | | 205230113 | “123456789012345682” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” |南|南|南| | 205230113 | “123456789012345683” | “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” |南|南|南| | 205230114 | “123456789012345684”| “2023-07-31 21:59:59+00” | “2023-06-30 22:00:00+00” | 1 | 2 | 3 |

表:

CREATE TABLE IF NOT EXISTS public.vyfakturovane_om
(
    id bigint NOT NULL,
    ean character varying(18) COLLATE pg_catalog."default" NOT NULL,
    "from" timestamp with time zone NOT NULL,
    "to" timestamp with time zone NOT NULL,
    "CelkomBezDPH" double precision NOT NULL,
    "CelkomIbaDPH" double precision NOT NULL,
    "CelkomPlusDPH" double precision NOT NULL,
    CONSTRAINT vyfakturovane_om_pkey PRIMARY KEY (ean, koniec, zaciatok),
    CONSTRAINT id FOREIGN KEY (id)
        REFERENCES public.fakturas (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

最后一次尝试的代码:

using var Connection = new NpgsqlConnection(ConnectionString);
await Connection.OpenAsync(cancellationToken);
var transaction = Connection.BeginTransaction();
try
{
    const string updateOM = "UPDATE vyfakturovane_om SET \"CelkomBezDPH\" = @1, \"CelkomIbaDPH\" = @2, \"CelkomPlusDPH\" = @3 WHERE \"ean\" = '@4' AND \"from\"::timestamptz = @5::timestamptz AND \"to\"::timestamptz = @6::timestamptz;";

    using var cmdOM = new NpgsqlCommand(updateOM, Connection, transaction);
    foreach (var om in faktura.OM)
    {
        //string timestampFrom, timestampTo;
        try
        {
            if (om.HladinaNapatia == HladinaNapeti.NN)
            {
                var f = faktura.NN[om.Key.From].Single(f => f.EAN == om.Key.EAN);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.BezDPH);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.IbaDPH);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.PlusDPH);
            }
            else
            {
                var f = faktura.VN[om.Key.From].Single(f => f.EAN == om.Key.EAN);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.BezDPH);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.IbaDPH);
                cmdOM.Parameters.AddWithValue(NpgsqlDbType.Double, f.PlusDPH);
            }
            cmdOM.Parameters.AddWithValue(NpgsqlDbType.Varchar, om.Key.EAN);
            //timestampFrom = om.Key.From.UtcDateTime.ToString("yyyy-MM-dd HH:mm:ss+00");
            //timestampTo = faktura.ToLocal.UtcDateTime.ToString("yyyy-MM-dd HH:mm:ss+00");
            cmdOM.Parameters.AddWithValue(NpgsqlDbType.TimestampTz, om.Key.From.UtcDateTime);
            cmdOM.Parameters.AddWithValue(NpgsqlDbType.TimestampTz, faktura.ToLocal.UtcDateTime);
            var omResult = await cmdOM.ExecuteNonQueryAsync(cancellationToken);
            if (omResult != 1)
            {
                throw new Exception("Failed to updated OM in DB.");
            }
            cmdOM.Parameters.Clear();
        }
        catch (Exception ex)
        {
            logger?.LogError("Failed to update {ean}, {from}-{to}. {ex}", om.Key.EAN, om.Key.From, faktura.ToLocal, ex.Message);
            throw;
        }
    }
    transaction.Commit();
}
catch
{
    transaction.Rollback(); // Rollback the transaction in case of an exception
    throw;
}
finally
{
    transaction.Dispose();
}

我还尝试了单引号@5和@6,然后异常更改为:
“22007:带有时区的时间戳类型的输入语法无效:“@5” 位置:148 英寸

删除交易后,它开始工作,但不知道为什么。
有什么想法,我应该怎么做才能继续使用交易?

c# .net postgresql .net-6.0 npgsql
1个回答
0
投票

你的桌子看起来像这样

| "id" | "ean" | "to" | "from" | "CelkomBezDPH" | "CelkomIbaDPH" | "CelkomPlusDPH" | 
|---|---|---|---|---|---|---| 
| 205230110 | "123456789012345678" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | 1 | 2 | 3 | 
| 205230111 | "123456789012345679" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | NaN | NaN | NaN | 
| 205230111 | "123456789012345680" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | NaN | NaN | NaN | 
| 205230112 | "123456789012345681" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | 1 | 2 | 3 | 
| 205230113 | "123456789012345682" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | NaN | NaN | NaN | 
| 205230113 | "123456789012345683" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | NaN | NaN | NaN | 
| 205230114 | "123456789012345684" | "2023-07-31 21:59:59+00" | "2023-06-30 22:00:00+00" | 1 | 2 | 3 |

您确定是日期失败而不是由于其他原因吗?

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