从VBA插入-Access

问题描述

我正在尝试将Access数据库中的Insert into语句推送到sql服务器。这一直在工作,但是我需要更改写“ j”列的方式,因为我现在需要区分true和NULL。我不断收到错误“无效使用null”。我应该如何转换J列的部分以避免此错误

                              If trow = 0 Then
                               sql = "INSERT ALL "
                               sql = sql + Chr(10) + "INTO " + username + "." + dbtable + " VALUES (" + _
                                    "q'[" + Format(rstIn("a"),"dd-mmm-yy") + "]'," + _
                                    "q'[" + Nz(rstIn("b"),"UNKNowN") + "]'," + _
                                       "" + CStr(Nz(rstIn("c"),"0")) + "," + _
                                    "q'[" + CStr(Nz(rstIn("d"),"UNKNowN")) + "]'," + _
                                    "" + CStr(Nz(rstIn("f")," + _
                                    "" + CStr(Nz(rstIn("e")," + _
                                    "" + CStr(Nz(rstIn("g")," + _
                                    "" + CStr(Nz(rstIn("h")," + _
                                    "q'[" + Nz(rstIn("i")," + _
                                    "q'[" + Format(rstIn("z")," + _
                                    "" + (rstIn("j").Value) + "," + _
                                    "" + CStr(Nz(rstIn("k")," + _
                                    "" + CStr(Nz(rstIn("l")," + _
                                    "" + CStr(Nz(rstIn("m"),"0")) + _
                                    ")"
                                

解决方法

如果j是数字字段,则不能向其传递字符串。因此,如果不接受 Null ,请尝试使用真正的零:

"" + Nz(rstIn("j").Value,0) + "," + _
,

假设您使用MS Access VBA中的ADO连接到SQL Server,请考虑使用一种避免了混乱的数据串联和引号标点的参数化解决方案。您甚至可以使用adVarCharadDateadInteger等来定义参数data types

下图显示了一个循环版本,该版本循环访问Access记录集以对SQL Server连接执行插入值查询。为演示的前5个定义了参数,以便将其扩展到所有14个。调整列名以及用...缩写的任何地方。

Dim sql As String
Dim connection As ADODB.Connection,cmd As ADODB.Command
Dim rstIn As DAO.Recordset

' OPEN ACCESS LOCAL RECORDSET
Set rstIn = CurrentDb.OpenRecordset("SELECT a,b,c,d,e,... FROM myAccessTable")

' PREPARED STATEMENT (NO DATA) WITH ? PLACEHOLDERS
sql = "INSERT INTO [" & username & "].[" & dbtable &] "(COL1,COL2,COL3,COL4,COL5," _ 
       & "                                              COl6,COl7,COL8,COL9,COL10," _
       & "                                              COL11,COL12,COl13,COl14)" _
       & " VALUES(?,?,?)"

' OPEN EXTERNAL SQL SERVER CONNECTION
Set connection = New ADODB.Connection
connection.Open "..."

Do While Not rstIn.EOF
    Set cmd = New ADODB.Command       ' INITIALIZE COMMAND

    With cmd
        .ActiveConnection = connection
        .CommandType = adCmdText
        .CommandText = query

        ' BIND PARAMETERS
        .Parameters.Append .CreateParameter(,adDate,adParamInput,rstIn("a"))
        .Parameters.Append .CreateParameter(,adVarChar,255,Nz(rstIn("b"),"UNKNOWN"))
        .Parameters.Append .CreateParameter(,adDouble,Nz(rstIn("c"),"0"))
        .Parameters.Append .CreateParameter(,Nz(rstIn("d"),Nz(rstIn("f"),"0"))
        ...

        ' RUN QUERY
        .Execute
    End With

    Set cmd = Nothing                 ' RELEASE COMMAND
    rstIn.MoveNext
Loop

rstIn.Close: connection.Close
Set rstIn = Nothing: Set connection = Nothing

或者,如果可以link SQL Server table in MS Access,则可以使用更简单的插入选择查询,从而避免循环和一行VBA。

SQL (另存为存储查询)

INSERT INTO mySQLServerLinkedTable (COL1,COl6,COL11,COl14)
SELECT Format(a,"dd-mmm-yy"),Nz(b,"UNKNOWN"),CStr(Nz(c,"0")),CStr(Nz(d,"UNKNOWN")),CStr(Nz(f,CStr(Nz(e,CStr(Nz(g,CStr(Nz(h,Nz(i,Format(z,j,CStr(Nz(k,CStr(Nz(l,CStr(Nz(m,"0")))
FROM myAccessLocalTable

VBA

DoCmd.OpenQuery "mySavedInsertQuery"