我从Active Directory中读取了pwdLastSet
属性,并希望将其存储在SQL Server表的DATETIME2(0)
列中。我不想存储几分之一秒。
这是一个8字节的整数,自1601年1月1日凌晨12:00开始以100纳秒的步长表示。我使用this function将其转换为Date变量。
使用ODBC-call failed
继续失败,并且花了我很多时间才能确定该函数返回的额外精度导致了错误。
从Date
变量中删除几分之一秒的最佳方法是什么?
我使用SQL Server 2008 R2和Access2010。
在SQL Server中:
CREATE TABLE TestDT (
ID INT NOT NULL,
colDT2 DATETIME2(0) NULL,
CONSTRAINT PK_TestDT PRIMARY KEY (ID)
)
GO
INSERT TestDT (ID) VALUES (1)
GO
使用Native Client ODBC驱动程序或当前的Microsoft ODBC Driver 17 for SQL Server将表链接到Access。默认的“ SQL Server”驱动程序实际上并不知道如何使用DATETIME2。
在Access VBA中:
Public Sub TestDT()
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim dte As Date
Dim i As Long
Set DB = CurrentDb
' Random date+time
dte = CDate("2018-12-24 15:16:17")
' 1st iteration: write original date+time -> works
' 2nd iteration: try to write date+time with fractional seconds -> error for DATETIME2(0) column
For i = 1 To 2
If i = 2 Then
' Introduce milliseconds nastiness
dte = dte + 0.00001
End If
Debug.Print "Iteration " & i, Format(dte, "yyyy-mm-dd hh:nn:ss")
Set RS = DB.OpenRecordset("SELECT * FROM TestDT WHERE ID = 1", dbOpenDynaset)
With RS
.Edit
!colDT2 = dte
On Error Resume Next
.Update
If Err.Number <> 0 Then
Debug.Print "Error " & Err.Number, Err.Description
' The DAO Errors collection shows the actual error
Debug.Print Errors(0).Description
Else
Debug.Print "Update OK"
End If
On Error GoTo 0
.Close
End With
Next i
End Sub
输出:
Iteration 1 2018-12-24 15:16:17
Update OK
Iteration 2 2018-12-24 15:16:18
Error 3146 ODBC-Aufruf fehlgeschlagen.
[Microsoft][ODBC Driver 17 for SQL Server]Datetime field overflow.
Fractional second precision exceeds the scale specified in the parameter binding.
答案 0 :(得分:3)
您可以这样舍入到第二个:
PwdLastSetSecond = CDate(Int(PwdLastSet * 86400) / 86400)
答案 1 :(得分:1)
Access中删除时间部分的正确功能是:
DateValue(“日期/时间”表达式)
因此,您得到:
dte = DateValue(CDate(“ 2018-12-24 15:16:17”))
或DateValue(无论日期时间表达式如何)
Access中删除时间部分的正确功能是:
TimeValue(“日期/时间”表达式)
因此,您得到:
dte = TimeValue(CDate(“ 2018-12-24 15:16:17”))
或TimeValue(无论日期/时间表达式如何)
如果您需要将时间部分保存或剥离为单独的值,请执行以下操作:
dtMyTime = TimeValue((CDate(“ 2018-12-24 15:16:17”))
但是,您的问题并未删除日期或时间。
格式中没有“ .ms”这样的东西。
这将给您一个月+秒的时间。
如果你仔细看:
2018-12-24 15:16:17.1217
在上面,te 1217是第12个月零17秒。
格式中没有“ ms”这样的东西。所以这就是为什么您看到溢出的原因。
因此您不能使用“ .ms”。
您只能在Access中获得秒数。
只需使用标准格式命令。如果要去除“额外”时间:
Set rst = CurrentDb.OpenRecordset("dbo_TimeTest2", dbOpenDynaset, dbSeeChanges)
rst.Edit
rst!StartTimeD = Format(rst!StartTimeD, "MM-DD-YYYY hh:nn:ss")
rst.Update
危险危险将罗宾逊。 Access不使用或不支持格式中的“ ms”。
仅在您获得的现有日期/时间上使用上述“格式”,就会在几秒钟后拉出并扔掉多余的值。
答案 2 :(得分:0)
我想出了
dte = CDate(Int(dte) + TimeSerial(Hour(dte), Minute(dte), Second(dte)))
但是那很笨拙。 :(