【问题标题】:Insert DateTimes of format (yyyy-mm-dd HH:mm:ss +TT:TT) into SQL Server将格式为 (yyyy-mm-dd HH:mm:ss +TT:TT) 的日期时间插入 SQL Server
【发布时间】:2015-10-19 13:24:04
【问题描述】:

我正在尝试构建参数以将日期时间插入数据库,如下所示:

InsertCommand.Parameters.AddWithValue("@TIME1", DateTime.Parse(fubardata[12]));

其中 fubardata[12] 包含“2015-07-22 13:41:53 +00:00”并且是字符串列表

我在执行查询时得到:

从字符串转换日期和/或时间时转换失败。 目标列的类型为 Datetimeoffset(7)

注意:以下内容不适用 数据库 没有进行格式化,我的情况是 .net。 [与https://msdn.microsoft.com/en-us/library/ms187819.aspx 一样,这种字符串格式似乎不是受支持的类型,它还提到堆栈溢出的各种帖子不支持它。]

我很难找到合适的演员表,或者需要如何呈现 Datetime 类以便 SQL 参数接受它。我曾多次看到以这种格式呈现给我的日期时间数据库数据。我确定有办法。

更新:转换为 DateTimeOffset.Parse(fubardata[12]) 在参数集语法 InsertCommand.Parameters.AddWithValue("@TIME1", DateTimeOffset.Parse(fubardata[12])); 中使用时仍会引发相同的异常@

更新(解决方案): 我在一个仅包含 ID 列和 theTime DateTimeOffset(7) 列的测试数据库上编写了一个小程序,以测试将这些值写入数据库。 一般来说,如果时间以非标准字符串格式出现在您的数据库中,我发现将时间写入数据库的最佳方法是:

InsertCommand.Parameters.Add("@[your param]",SqlDbType.DateTimeOffset).Value = "[date as a string]";

FOLLOWS 是我用来测试它的代码。我了解到,当使用 addwithvalue 时,SQL 无法处理从格式为“yyyy-mm-dd HH:mm:ss +-TT:TT”的字符串创建的 daytimeoffset / datetime。一个重要的注意事项是,如果您的表使用的是 DateTimeOffsets,您应该在插入之前将您的日期时间转换为该 DateTimeOffset 类型。作为旁注,我觉得很尴尬

InsertCommand.Parameters.AddWithValue("@[your param]", DateTime.Now)

-不会引起人们一直使用的问题。

    private static void Main()
    {

        SqlConnection DataBaseWriterConnection;
        SqlCommand DataBaseWriterCommand;
        string SqlQueryString;
        List<List<string>> theData = new List<List<string>>();
        List<string> theDataRow1 = new List<string>();
        theDataRow1.Add("2015-07-22 13:41:00 +00:00");
        List<string> theDataRow2 = new List<string>();
        theDataRow2.Add("2015-07-22 13:42:00 +00:00");
        List<string> theDataRow3 = new List<string>();
        theDataRow3.Add("2015-07-22 13:43:00 +00:00");
        theData.Add(theDataRow1);
        theData.Add(theDataRow2);
        theData.Add(theDataRow3);

        DataBaseWriterConnection = new SqlConnection("Server = localhost; database = CA_TakacsTesting; connection timeout=30; Trusted_Connection = Yes");
        try
        {
            DataBaseWriterConnection.Open();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error connecting. Reason:\n" + ex.Message );
        }
        foreach (List<string> aDataRow in theData)
        {
            try
            {
                SqlQueryString = "INSERT INTO DateTimeTesting (theTime) VALUES(@theDateTimeOffset)";


                SqlCommand InsertCommand = new SqlCommand(SqlQueryString, DataBaseWriterConnection);

                InsertCommand.Parameters.Add("@theDateTimeOffset", SqlDbType.DateTimeOffset).Value = aDataRow[0];
                InsertCommand.ExecuteNonQuery();
                Console.WriteLine("No Problems Caused");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot Write for reason:\n" + ex.Message);
                Console.ReadLine();
            }

        }
        DataBaseWriterConnection.Close();
    }
}

生成的数据库输出为:

ID  theTime
1   2015-07-22 13:41:00.0000000 +00:00
2   2015-07-22 13:41:00.0000000 +00:00
3   2015-07-22 13:42:00.0000000 +00:00

这是我们想要的。

【问题讨论】:

  • 为什么要解析为DateTime 而不是DateTimeOffset?请注意,在您的示例中,字符串处理完全在 .NET 代码中 - SQL Server 根本不解析原始字符串。
  • 我将时间表示为需要传递到表中的字符串。我可能需要为那个字符串做 DateTimeOffset.Parse()。
  • 但是你已经在你的 .NET 代码中解析它了——这很好。但是您将其解析为错误的类型-您的字段类型是DateTimeOffset,因此您应该将其解析为.NET System.DateTimeOffset 类型...我建议使用DateTimeOffset.ParseExact,并指定格式(和不变的文化)
  • 对,我可能在这里错过了我的文化,因此正如我所见,没有明确支持解析为“yyyy-mm-dd HH:mm:ss TT:TT”的需要在 MSDN Transact SQL 页面上。我需要准确解析 ISO 文化。下次试试这个
  • 我还怀疑,鉴于您看到的错误,您可能实际上并没有从您向我们展示的代码中得到问题 - 也许它是另一个字段?我建议您通过创建一个虚拟数据库just 来解决此问题,从而缩小范围。创建一个只有一个字段的表,类型为 DateTimeOffset,然后使用 complete 示例更新您的帖子以尝试更新它。我还建议使用...Parameters.Add("@name", SqlDbType.DateTimeOffset).Value = ... 而不是AddWithValue,但那是另一回事。

标签: c# sql-server date datetime timezone


【解决方案1】:

我在这里看到了一些不好的事情:

  1. Sql Server 中的日期值(包括 DateTime、DateTime2、DateTimeOffset 等)使用该格式。它们以人类不可读的二进制格式存储。您只能在调试器和查询工具提供的便利中看到它们,或者在实际将日期值放入原始 SQL 时(并且参数不会创建原始 SQL,因此您很少需要它)。
  2. Don't use AddWithValue()
  3. 在任何时候都不需要将 DateTimeOffset 值转换为字符串。
  4. 从 DataRow 对象解析字段意味着您有一个查询,该查询应该在单个语句中使用 JOIN 或 INSERT + SELECT 编写。正确构建 SQL,根本不需要在 C# 级别拥有这些数据。

您可以固定点 1-3,如下所示。我们需要了解更多上下文以帮助您解决第 4 点。

InsertCommand.Parameters.Add("@TIME1", SqlDbType.DateTimeOffset).Value = DataRow[12];

【讨论】:

  • 4.该数据来自一个 list> 由处理大型数据集生成的类生成;表示一个平面文件。我正在使用 foreach 迭代器将内部字符串的行推送到数据库中。然后 DataRow[x] 从字符串列表中获取索引。我没有意识到 DataRow 是某个类的关键字。我刚刚将它的名称从我的程序更改为这里的通用名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-21
  • 2020-03-07
  • 2020-09-27
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多