如何在VB.NET中实现相同的功能,这在SQL Server中非常容易实现。
SELECT CAST(GETDATE() AS VARBINARY(8)) --GIVES THE CURRENT TIME IN HEX
现在我的问题是如何在VB.NET中创建相同的字符串,以便我可以在SQL Server中进行比较 -
SELECT CASE WHEN GETDATE()=CAST(0X00009F5E00D8DF7C AS DATETIME) THEN 'TRUE' ELSE 'FALSE' END -- 0X00009F5E00D8DF7C WILL BE THE VALUE I GET IN VB.NET WHEN I CONVERT IT DATE.NOW() TO HEX
答案 0 :(得分:3)
这个答案只是简单地将.NET DateTimes转换为等同于SQL Server的datetime
数据类型的二进制格式,所以我认为它有足够的不同以保证单独的答案(我检查了here和here以确定没问题。)
正如@Martin Smith指出的那样,datetime
的二进制格式不仅仅是自特定时间点以来的一些滴答。
datetime
存储为8个字节,前4个字节是自01-01-1900以来的天数,第二个4个字节是自当天午夜以来的“滴答”数,其中a tick是10/3毫秒。
为了将.NET DateTime转换为等效的二进制表示,我们需要确定自'01 -01-1900'以来的天数,将其转换为十六进制,然后是从午夜开始的滴答数,这是因为.NET滴答是100ns,所以有点复杂。
例如:
DateTime dt = DateTime.Now;
DateTime zero = new DateTime(1900, 1, 1);
TimeSpan ts = dt - zero;
TimeSpan ms = ts.Subtract(new TimeSpan(ts.Days, 0, 0, 0));
string hex = "0x" + ts.Days.ToString("X8") + ((int)(ms.TotalMilliseconds/3.33333333)).ToString("X8");
当我运行此代码时,dt
为9/14/2011 23:19:03.366
,并将hex
设置为0x00009F5E01804321
,在SQL Server中转换为2011-09-14 23:19:03.363
。
我相信由于四舍五入会得到确切的日期总是有问题,但是如果你可以使用一个查询,其中日期时间不必完全匹配,直到毫秒,这可能足够接近。
修改强>
在我发布的第一个答案的评论中,我询问了SQL Server 2008,因为datetime2
数据类型确实存储的时间精度为100ns(至少是默认精度),与.NET很好地匹配。如果您对SQL Server中二进制级别的存储方式感兴趣,请参阅my answer以查看较旧的问题。
答案 1 :(得分:1)
我的第一个倾向是客户端不应该构建由数据访问层执行的sql语句,但假设你必须尽快开始工作,你可以考虑使用参数化查询。
如果要从客户端向其他应用程序层进行方法调用,则可以在客户端上构造SqlCommand
并将其传递到将在其中执行的下一层。
VB.NET不是我通常使用的语言,所以请原谅任何语法错误。
在客户端:
Dim dateValue As Date = DateTime.Now
Dim queryText As String = "SELECT CASE WHEN GETDATE() = @Date THEN 'True' ELSE 'False' END"
Dim command As SqlCommand = New SqlCommand(queryText)
command.Parameters.AddWithValue("@Date", dateValue)
如果必须发送字符串,可以将DateTime
转换为客户端上的字符串,然后使用通用格式转换回数据访问层上的DateTime
。
在客户端:
Dim queryText As String = "SELECT CASE WHEN GETDATE() = @Date THEN 'True' ELSE 'False' END"
Dim dateValue As Date = DateTime.Now
Dim dateString = DateTime.Now.ToString("M/d/yyyy H:mm:ss.fff", DateTimeFormatInfo.InvariantInfo)
然后将queryText
和dateString
发送到应用程序中的下一层,它将转换回Date
并再次使用参数化查询:
Dim dateValue As Date
Date.TryParseExact(dateString, "M/d/yyyy H:mm:ss.fff", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, dateValue)
Dim command As SqlCommand = New SqlCommand(queryText)
command.Parameters.AddWithValue("@Date", dateValue)
如果您的客户位于不同的时区,您应该(如@Martin Smith所述)考虑使用UTC时间。
在.NET中
Dim dateValue = DateTime.UtcNow
以及您的查询中,使用GETUTCDATE()
:
Dim queryText As String = "SELECT CASE WHEN GETUTCDATE() = @Date THEN 'True' ELSE 'False' END"
答案 2 :(得分:1)
我不得不将dbscript中的一些日期从SQL Server的十六进制格式字符串转换为标准日期时间字符串(用于TSQL到MySQL脚本转换)。我使用了一些我在这里查找的代码并提出了:
static string HexDateTimeToDateTimeString(string dateTimeHexString)
{
string datePartHexString = dateTimeHexString.Substring(0, 8);
int datePartInt = Convert.ToInt32(datePartHexString, 16);
DateTime dateTimeFinal = (new DateTime(1900, 1, 1)).AddDays(datePartInt);
string timePartHexString = dateTimeHexString.Substring(8, 8);
int timePartInt = Convert.ToInt32(timePartHexString, 16);
double timePart = timePartInt * 10 / 3;
dateTimeFinal = dateTimeFinal.AddMilliseconds(timePart);
return dateTimeFinal.ToString();
}
static string HexDateToDateString(string dateHexString)
{
int days = byte.Parse(dateHexString.Substring(0, 2), NumberStyles.HexNumber)
| byte.Parse(dateHexString.Substring(2, 2), NumberStyles.HexNumber) << 8
| byte.Parse(dateHexString.Substring(4, 2), NumberStyles.HexNumber) << 16;
DateTime dateFinal = new DateTime(1, 1, 1).AddDays(days);
return dateFinal.Date.ToString();
}
可能没有优化,但显示了这个想法。