我换了一台新的笔记本电脑(Windows10i5),并试图设置我的笔记本电脑。NET应用程序。我遇到了一个奇怪的问题,花了我很多时间。在我的应用程序中,我将当前日期时间以UTC格式存储在Postgres DB表中。c#命令DateTime。UtcNow
将日期格式输出为
14-12-2021 13:50:57
当上述日期通过要存储在Postgres Db中的insert查询传递时,它抛出错误如下
错误:日期/时间字段值超出范围:"14-12-2021 13:50:57"
更奇怪的是,在我的旧笔记本电脑上(同样的操作系统-视窗10 i3),同样的代码工作正常,并给出日期的输出
12/14/2021 07:24:24上午
这种格式被Postgres DB接受。
表的设计如下所示
CREATE TABLE IF NOT EXISTS public."Log"
(
"Id" bigint NOT NULL DEFAULT nextval('"Log_Id_seq"'::regclass),
"QueueId" uuid NOT NULL,
"MessageId" character varying(100) COLLATE pg_catalog."default",
"LogTime" timestamp without time zone,
CONSTRAINT "Log_pkey" PRIMARY KEY ("Id")
)
由日期时间生成的值。UtcNow
正在传递到LogTime
列中。
下面是构成Postgres查询的c#代码。
string query = $@"INSERT INTO public.""Log""(
""QueueId"",
""LogTime"",
""Message"",
)
VALUES(
'{req.QueueId}',
'{req.LogTime}',
'{(item.Message.Length > 100 ? item.Message.Substring(0, 100) : item.Message)}'
RETURNING ""Id"";";
相同的代码在具有相同操作系统的不同机器上的行为不同。任何线索都将不胜感激。谢谢你的帮助。
我重复上面的评论,因为您在编写{req.LogTime}时正在转换字符串中的日期时间,因此代码为数据库创建了一个解析问题,因为它需要将该字符串转换回timespan以将其插入列中。这不仅在转换字符串时容易产生不同的结果(一台电脑认为日期的正确格式是“MM-dd”,另一台电脑认为是“dd-MM”),而且还造成了一个众所周知的漏洞,称为Sql注入
只需使用参数将值传递给数据库即可
使用适当的类型定义参数,值的解析不再有歧义,数据库也不会受到脚本孩子尝试世界上最简单的黑客攻击的影响。
string query = $@"INSERT INTO public.""Log""(
""QueueId"", LogTime"", ""Message"")
VALUES(@qid, @ltime, @msg)
RETURNING ""Id"";";
using (var cmd = new NpgsqlCommand(query, conn))
{
cmd.Parameters.Add("@qid", NpgsqlDbType.Uuid).Value = req.QueueId;
cmd.Parameters.Add("@ltime", NpgsqlDbType.Timestamp).Value = req.LogTime;
cmd.Parameters.Add("@msg", NpgsqlDbType.Varchar).Value =
(item.Message.Length > 100 ? item.Message.Substring(0, 100) : item.Message);
var id = cmd.ExecuteScalar();
}
设置日期样式以匹配您的输入。这个对我很有用:
SET DateStyle to DMY;
SELECT '14-12-2021 13:50:57'::TIMESTAMP