【问题标题】:Passing empty or blank values from Excel data to SQL Server using VBA使用 VBA 将空值或空白值从 Excel 数据传递到 SQL Server
【发布时间】:2022-12-26 01:12:17
【问题描述】:

如何使用 VBA 将 Excel 中的空值或空白值传递给 SQL Server?

当我的代码读取一个空白单元格时,即使它有数据,下一个后续单元格也将是空白的。

我试图在单元格为空时输入 null,但我在处理日期时遇到了问题,因为我在 SQL Server 中日期列的数据类型是日期,因此它无法将“null”读取为日期。

此外,我的 SQL 查询中出现运行时错误(“',' 附近的语法不正确”)。

Public Sub UploadData()

    Dim count As Long
    Dim start As Integer
    Dim i As Long
    Dim con As ADODB.Connection

    Set con = New ADODB.Connection
    con.Open "Provider=SQLOLEDB;Data Source=10.206.88.119\BIWFO;" & _
                      "Initial Catalog=TESTDB;" & _
                      "Uid=user; Pwd=pass;"
    
    Dim cmd As ADODB.Command
    Dim pm As ADODB.Parameter

    If MsgBox("This will IMPORT everything! Are you sure?", vbYesNo) = vbNo Then Exit Sub
    
    Dim rng As Range:  Set rng = Range("A2", Range("A2").End(xlToRight).End(xlDown))
    Dim row As Range
    
    count = ActiveSheet.Cells(Rows.count, "A").End(xlUp).row

    i = 2

    OpenStatusBar

    Do While i <= count
 
        For Each row In rng.Rows

            RequestID = row.Cells(1).Value
            IssuingCountryName = row.Cells(2).Value
            ProgramStructure = row.Cells(3).Value
            LineOfBusinessName = row.Cells(4).Value
            RequestGrossPremiumAmount = row.Cells(5).Value
            RequestCollectionCurrencyName = row.Cells(6).Value
            Clientname = row.Cells(7).Value
            ROServiceContact = row.Cells(8).Value
            RequestEffectiveDate = row.Cells(9).Value
            RequestReleaseDate = row.Cells(10).Value
            OriginalRequestReleaseDate = row.Cells(11).Value
            RequestType = row.Cells(12).Value
            RequestStatus = row.Cells(13).Value
            RequestRejectDate = row.Cells(14).Value
            RequestRejectReason = row.Cells(15).Value
            RequestCorrectionDate = row.Cells(16).Value
            RequestAcceptedDate = row.Cells(17).Value
            RequestLocalBookDate = row.Cells(18).Value
            PolicyIssuedDate = row.Cells(19).Value
            IOAccountHandlerContact = row.Cells(20).Value
      
    SQL = " INSERT INTO [TESTDB].[dbo].[tbl_MN_Daily_SLA] " _
    & " Values('" & RequestID & "' , '" & IssuingCountryName & "' , '" & ProgramStructure & "' , '" & LineOfBusinessName & "' , " _
    & " " & RequestGrossPremiumAmount & " ,'" & RequestCollectionCurrencyName & "' , '" & Clientname & "' , '" & ROServiceContact & "' , " _
    & " '" & RequestEffectiveDate & "' , '" & RequestReleaseDate & "' , '" & OriginalRequestReleaseDate & "' , '" & RequestType & "' , '" & RequestStatus & "' ," _
    & " '" & RequestRejectDate & "' , '" & RequestRejectReason & "' , '" & RequestCorrectionDate & "' , '" & RequestAcceptedDate & "' , '" & RequestLocalBookDate & "' , " _
    & " '" & PolicyIssuedDate & "' , '" & IOAccountHandlerContact & "')"
    
        con.Execute SQL
      
        DoEvents
        Call RunStatusBar(i, count)
    
        i = i + 1
        count = Range("A2", Range("A2").End(xlDown)).count
    Next row
    Loop
 
    Unload StatusBar

    con.Close
    MsgBox "Done Importing"
    
End Sub

【问题讨论】:

    标签: sql-server excel vba


    【解决方案1】:

    考虑 SQL 参数化,编程行业的最佳实践是从 VBA 等应用层代码运行 SQL 查询。作为杰夫阿特伍德advises你永远不应该在你的应用程序中使用连接的 SQL 字符串.否则,您会遇到您遇到的问题,例如日期类型、NULL 处理、杂乱的引用附件等。 ADO 通过命令对象支持参数。

    ...
    
    ' PREPARED STATEMENT (WITH 20 QMARK PLACEHOLDERS)
    SQL = "INSERT INTO [TESTDB].[dbo].[tbl_MN_Daily_SLA] " _
        & "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
    
    ' LOOP THROUGH ROWS
    For Each row In rng.Rows
        ' NULLIFY EMPTY CELLS
        RequestID = IIf(row.Cells(1).Value = "", Null, row.Cells(1).Value)
        IssuingCountryName = IIf(row.Cells(2).Value = "", Null, row.Cells(2).Value)
        ProgramStructure = IIf(row.Cells(3).Value = "", Null, row.Cells(3).Value)
        LineOfBusinessName = IIf(row.Cells(4).Value = "", Null, row.Cells(4).Value)
        RequestGrossPremiumAmount = IIf(row.Cells(5).Value = "", Null, row.Cells(5).Value)
        RequestCollectionCurrencyName = IIf(row.Cells(6).Value = "", Null, row.Cells(6).Value)
        Clientname = IIf(row.Cells(7).Value = "", Null, row.Cells(7).Value)
        ROServiceContact = IIf(row.Cells(8).Value = "", Null, row.Cells(8).Value)
        RequestEffectiveDate = IIf(row.Cells(9).Value = "", Null, row.Cells(9).Value)
        RequestReleaseDate = IIf(row.Cells(10).Value = "", Null, row.Cells(10).Value)
        OriginalRequestReleaseDate = IIf(row.Cells(11).Value = "", Null, row.Cells(11).Value)
        RequestType = IIf(row.Cells(12).Value = "", Null, row.Cells(12).Value)
        RequestStatus = IIf(row.Cells(13).Value = "", Null, row.Cells(13).Value)
        RequestRejectDate = IIf(row.Cells(14).Value = "", Null, row.Cells(14).Value)
        RequestRejectReason = IIf(row.Cells(15).Value = "", Null, row.Cells(15).Value)
        RequestCorrectionDate = IIf(row.Cells(16).Value = "", Null, row.Cells(16).Value)
        RequestAcceptedDate = IIf(row.Cells(17).Value = "", Null, row.Cells(17).Value)
        RequestLocalBookDate = IIf(row.Cells(18).Value = "", Null, row.Cells(18).Value)
        PolicyIssuedDate = IIf(row.Cells(19).Value = "", Null, row.Cells(19).Value)
        IOAccountHandlerContact = IIf(row.Cells(20).Value = "", Null, row.Cells(20).Value)
    
        ' INITIALIZE COMMAND OBJECT
        Set cmd = New ADODB.Command
    
        ' ADJUST COMMAND PROPERTIES
        With cmd
            .ActiveConnection = conn
            .CommandText = SQL
            .CommandType = adCmdText
    
            '  BIND PARAMETERS OF VARCHARS AND DATES
            .Parameters.Append .CreateParameter("pRequestID", adVarChar, adParamInput, , RequestID)
            .Parameters.Append .CreateParameter("pIssuingCountryName", adVarChar, adParamInput, , IssuingCountryName)
            .Parameters.Append .CreateParameter("pProgramStructure", adVarChar, adParamInput, , ProgramStructure)
            .Parameters.Append .CreateParameter("pLineOfBusinessName", adVarChar, adParamInput, , LineOfBusinessName)
            .Parameters.Append .CreateParameter("pRequestGrossPremiumAmount", adVarChar, adParamInput, , RequestGrossPremiumAmount)
            .Parameters.Append .CreateParameter("pRequestCollectionCurrencyName", adVarChar, adParamInput, , RequestCollectionCurrencyName)
            .Parameters.Append .CreateParameter("pClientname", adVarChar, adParamInput, , Clientname)
            .Parameters.Append .CreateParameter("pROServiceContact", adVarChar, adParamInput, , ROServiceContact)
            .Parameters.Append .CreateParameter("pRequestEffectiveDate", adDate, adParamInput, , RequestEffectiveDate)
            .Parameters.Append .CreateParameter("pRequestReleaseDate", adDate, adParamInput, , RequestReleaseDate)
            .Parameters.Append .CreateParameter("pOriginalRequestReleaseDate", adDate, adParamInput, , OriginalRequestReleaseDate)
            .Parameters.Append .CreateParameter("pRequestType", adVarChar, adParamInput, , RequestType)
            .Parameters.Append .CreateParameter("pRequestStatus", adVarChar, adParamInput, , RequestStatus)
            .Parameters.Append .CreateParameter("pRequestRejectDate", adDate, adParamInput, , RequestRejectDate)
            .Parameters.Append .CreateParameter("pRequestRejectReason", adVarChar, adParamInput, , RequestRejectReason)
            .Parameters.Append .CreateParameter("pRequestCorrectionDate", adDate, adParamInput, , RequestCorrectionDate)
            .Parameters.Append .CreateParameter("pRequestAcceptedDate", adDate, adParamInput, , RequestAcceptedDate)
            .Parameters.Append .CreateParameter("pRequestLocalBookDate", adDate, adParamInput, , RequestLocalBookDate)
            .Parameters.Append .CreateParameter("pPolicyIssuedDate", adDate, adParamInput, , PolicyIssuedDate)
            .Parameters.Append .CreateParameter("pIOAccountHandlerContact", adVarChar, adParamInput, , IOAccountHandlerContact)
    
            '  EXECUTE ACTION
            .Execute
        End With
       
        Set cmd = Nothing
    Next row
    

    【讨论】:

    • 像魔术一样工作!非常感谢@Parfait。只是一个问题,当我在日期列上有空白单元格时,它会给我一个错误“应用程序对当前操作使用了错误类型的值。”
    • 此外,如果该单元格为空,则下一个后续单元格也将为空 :(
    • 请参阅更新以取消将 Null 作为参数值传递的空单元格。
    • @Parfailt 非常感谢!多么救命啊!
    猜你喜欢
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多