【发布时间】:2020-01-16 06:23:41
【问题描述】:
我需要使用 Excel VBA 将 SQL Server 表中的一些数据复制到类似的 Access 表中。为此,我创建了一个函数,该函数根据 SQL Server 的 Select 语句创建将 SQL 插入 Access DB (PreparedStatement)。
字符串、日期和整数都很好。十进制值(adNumber 类型)如何导致错误“标准表达式中的数据类型不匹配”。如果我将十进制值四舍五入为整数,事情就会顺利进行。我还确认可以使用 access 手动将十进制值输入到目标表中。
原始 SQL Server 源表字段中的数据类型是小数(18,4),而在目标 Access 表中,相应的类型是数字(精度为 18 和小数位数为 4 的小数字段类型)。下面的代码将该字段视为 adNumeric 类型,NumericScale 为 4,Precision 为 18。
例如,当我从源表中读取值 5.16 并尝试将其插入目标表时,我得到一个错误。如果我将读取值四舍五入为 5,则插入工作不会出错。
那么我在这里做错了什么,我应该怎么做才能得到正确的十进制数字?
我正在根据 select 查询创建并执行插入语句,如下所示:
Private Sub AddToTargetDatabase(ByRef source As ADODB.Recordset, ByRef targetCn As ADODB.connection, tableName As String)
Dim flds As ADODB.Fields
Set flds = source.Fields
'target table is cleared at the beginning
targetCn.Execute ("DELETE FROM " & tableName)
Dim insertSQL As String
insertSQL = "INSERT INTO " & tableName & "("
Dim valuesPart As String
valuesPart = ") VALUES ("
Dim i As Integer
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = targetCn
cmd.Prepared = True
Dim parameters() As ADODB.Parameter
ReDim parameters(flds.Count)
'Construct insert statement and parameters
For i = 0 To flds.Count - 1
If (i > 0) Then
insertSQL = insertSQL & ","
valuesPart = valuesPart & ","
End If
insertSQL = insertSQL & "[" & flds(i).Name & "]"
valuesPart = valuesPart & "?"
Set parameters(i) = cmd.CreateParameter(flds(i).Name, flds(i).Type, adParamInput, flds(i).DefinedSize)
parameters(i).NumericScale = flds(i).NumericScale
parameters(i).Precision = flds(i).Precision
parameters(i).size = flds(i).DefinedSize
cmd.parameters.Append parameters(i)
Next i
insertSQL = insertSQL & valuesPart & ")"
Debug.Print insertSQL
cmd.CommandText = insertSQL
'String generated only for debug purposes
Dim params As String
Do Until source.EOF
params = ""
For i = 0 To flds.Count - 1
Dim avalue As Variant
If (parameters(i).Type = adNumeric) And Not IsNull(source.Fields(parameters(i).Name).Value) And parameters(i).Precision > 0 Then
avalue = source.Fields(parameters(i).Name).Value
'If rounded insert works quite nicely
'avalue = Round(source.Fields(parameters(i).Name).Value)
Else
avalue = source.Fields(parameters(i).Name).Value
End If
'construct debug for the line
params = params & parameters(i).Name & " (" & parameters(i).Type & "/" & parameters(i).Precision & "/" & source.Fields(parameters(i).Name).Precision & ") = " & avalue & "|"
parameters(i).Value = avalue
Next i
'print debug line containing parameter info
Debug.Print params
'Not working with decimal values!!
cmd.Execute
source.MoveNext
Loop
End Sub
【问题讨论】:
-
让我猜猜……你的十进制符号是逗号?在数据库中是
.?