如何将GETDATE()的默认字符串表示更改为包含毫秒?

时间:2017-03-25 14:32:48

标签: sql-server json vb.net datetime

我创建了一个名为dbfiddle的工具,有人has asked如何从GETDATE()和SYSDATETIME()获得更高的精度,目前只显示秒数:

SELECT SYSDATETIME(), GETDATE();
GO
(No column name)    | (No column name)   
:------------------ | :------------------
25/03/2017 14:22:16 | 25/03/2017 14:22:16

dbfiddle here

我使用JSON API访问数据库后端,SQL Server 2014/2016使用System.Web.Script.Serialization.JavaScriptSerializer将结果转换为JSON,产生此输出:

[["25/03/2017 13:59:54"],["25/03/2017 13:59:54"]]

只需从ExecuteReader构建一个数组并将其传递给JavaScriptSerializer即可生成结果。

我认为我需要更改当前文化的DateTimeFormat.LongTimePattern以显示毫秒(或更多),这是正确的,如果是这样,我如何在VB.NET中为ASP页面执行此操作?

我无法改变执行的SQL,因此CONVERT不是一个选项。

以下是我的代码相关部分的简化版本:

Dim sr = New StreamReader(Request.InputStream)
Dim ser = New System.Web.Script.Serialization.JavaScriptSerializer()
ser.MaxJsonLength = Int32.MaxValue
Dim queries = ser.Deserialize(Of List(Of String))(sr.ReadToEnd())
sr.Close()
Dim query = queries(0)

Dim connection As SqlConnection
Dim command As SqlCommand

…

command = connection.CreateCommand
command.CommandText = query

Dim reader = command.ExecuteReader()
Dim result = New List(Of List(Of String))

For i As Integer = 0 To reader.FieldCount-1
    result.Add(New List(Of String))
Next

While reader.Read()
    For i As Integer = 0 To reader.FieldCount-1
        result(i).Add(reader(i))
    Next
End While

reader.Close()
connection.Close()
…
Response.Write(ser.Serialize(result))

2 个答案:

答案 0 :(得分:1)

编辑:由于OP添加了代码段,因此问题是将所有结果列转换为字符串。

您希望将所有列都装箱到一个对象,以便它们保留其基础数据类型。然后,序列化器将能够在类型上正确工作。然后,DateTime对象将如下所示。

为此,请更改:

Dim result = New List(Of List(Of String))

到此:

Dim result = New List(Of List(Of Object))

并改变这一点:

result.Add(New List(Of String))

到此:

result.Add(New List(Of Object))

在此过程中,您必须在JSON序列化之前或期间对数组中的元素进行隐式或显式调用ToString()

执行阅读器时,它会将列包含为DateTime,而不是字符串。在DateTime上调用ToString()时,它将返回当前区域性格式的字符串。 (en-us看起来像这样#34; 3/25/2017 11:10:05 AM")

using (var con = new SqlConnection("ConnectionStringHere"))
using (var cmd = new SqlCommand("SELECT SYSDATETIME(), GETDATE();", con))
{
    con.Open();
    var reader = cmd.ExecuteReader();

    var columns = new List<object>();
    while (reader.Read())
    {
        columns.Add(reader[0]);
        columns.Add(reader[1]);
    }

    // The columns list contains SYSDATETIME and GETDATE output
    columns.Dump();

    // The data type of both columns is System.DateTime
    columns[0].GetType().Dump();
    columns[1].GetType().Dump();

    // By default, the JavaScriptSerializer will convert DateTime
    // to the number of ticks, not a pretty string representation
    // e.g. "\/Date(1490454072159)\/"
    // https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx
    var serializer = new JavaScriptSerializer();
    serializer.Serialize(columns[0]).Dump();

    reader.Close();
}

如果您没有看到有关如何构建阵列并将其传递给序列化程序的代码,我无法确定您出错的位置。但是,如果您维护数据类型并且不将每个结果列视为字符串,则序列化程序应该为您提供完整的精度。

答案 1 :(得分:-5)

可能有办法弄清楚如何执行此操作,但该值正在通过软件堆栈的几个不同级别传递。这可以使解决方案变得棘手。

也许您可以说服用户,如果他们想要特定格式,请使用convert()

SELECT SYSDATETIME(), CONVERT(varchar(255), GETDATE(), 121)

在这种情况下,121会按照提问者的要求行事。

几乎所有其他工具都适用于数据库。请注意,这是一个小问题。例如,连接到Oracle的Toad仅显示date数据类型的日期组件 - 即使Oracle中的date具有时间组件。