在将记录添加到数据库之前检查记录是否存在

时间:2017-09-08 08:49:04

标签: sql sql-server excel vba excel-vba

在VBA中是否有办法在添加记录之前检查数据库中是否存在记录?

我尝试在变量中捕获选择查询:

sSQL = "select count(*) from OptionRestriction where Feature_ID_1 = 1021 AND OptionValue_1 = 3 AND value = 0 AND Feature_ID_2 = 403 AND OptionValue_2 = 5 and visible = 1"

我在if语句中使用了变量来检查计数是否为1.如果语句为true,则应添加记录:

            If sSQL <> "1" Then
                conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
            End If

然而,这在VBA中无法奏效。我有什么想法可以让它发挥作用吗?

更新

根据Vityata的评论,我做了以下更改:

我添加了一个功能:

Public Function RestrictionCount() As Long
     RestrictionCount = DCount("Feature_ID_1", "OptionRestriction", "Feature_ID_1 = 1023 AND OptionValue_1 AND value = 0  AND Feature_ID_2 = 403 AND optionValue_2 = 5 AND visible = 1")
End Function

并在我的if所在的代码中使用了functon:

Private Sub CommandButton1_Click()

   Dim conn              As New ADODB.Connection
   conn.Open             "<string to connect to DB. Not displayed here due to confidentiality reasons>"


            If RestrictionCount() <> 1 Then
                conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
            End If

End Sub

现在我收到一个编译错误,指出没有定义子或函数,而DCount位于另一个函数中。有办法解决这个问题吗?对不起我的问题(我是VBA新手)。

更新

现在可以通过Vityata的最后评论来执行检查。代码现在如下,包括我用来将数据添加到数据库的循环:

    rs.ActiveConnection = conn
    rs.Open "select * from OptionRestriction where Feature_ID_1 = 1021 AND OptionValue_1 = 3 AND value = 0 AND Feature_ID_2 = 403 AND OptionValue_2 = 5 and visible = 1"

    i = 2
    Do Until IsEmpty(Cells(i, 1))
        s_OptionValue_1_s = ActiveSheet.Cells(i, 1)
        value_s = ActiveSheet.Cells(i, 2)
        s_OptionValue_2_s = ActiveSheet.Cells(i, 3)

        If value_s <> "" Then

            If rs.RecordCount <> 1 Then
                conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
            End If

            conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, '" & Replace(value_s, "'", "''") & "', OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 0 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
        Else
            conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, 1, OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 0 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
            conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue  As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue  AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
        End If

    i = i + 1
    Loop

现在数据库中的结果是:

enter image description here

然而,选中的行不应该存在。所以它只需要添加1021 - 3 - 0 - 403 - 5 - 1一次。为了达到这个目的,我需要在循环中进行哪些更改?

将数据插入数据库的excel文件如下所示:

enter image description here

1 个答案:

答案 0 :(得分:1)

如果您使用 MS Excel ,这是您可以使用的示例:

Public Sub CheckDataInSQLServer()

    Dim cnLogs              As Object
    Dim rsData              As Object

    On Error GoTo CheckDataInSQLServer_Error

    Set cnLogs = CreateObject("ADODB.Connection")
    Set rsData = CreateObject("ADODB.Recordset")

    cnLogs.Open ConnectionString 'this is a string function

    rsData.ActiveConnection = cnLogs
    rsData.Open "SELECT * FROM A WHERE B = C;"

    If rsData.EOF Then
        debug.print "no values"
    Else    
        debug.print "has values"
    End If    

End Sub

在VBA中,如果您使用 MS Access ,则需要的功能称为DCount

您可以使用DCount函数来确定指定记录集(域)中的记录数。在Visual Basic中使用DCount函数,宏,查询表达式或计算控件。例如,您可以使用模块中的DCount函数返回Orders表中与特定日期下的订单相对应的记录数。 MSDN

详细了解如何使用DCount - DCount with 2 criteria

这是一个如何在函数中构建DCount并使用它的示例:

Public Function OrdersCount(ByVal strCountry As String, ByVal dteShipDate As Date) As Long
    OrdersCount = DCount("[ShippedDate]", "Orders", _
                  "[ShipCountry] = '" & strCountry & _
                  "' AND [ShippedDate] > #" & dteShipDate & "#")
End Function

If OrdersCount("Bulgaria", Now()) = 0 then
    'Execute the SQL query.
End if