在VBA中运行SQL动态语句时未设置对象变量或With块变量

时间:2015-07-20 11:10:47

标签: sql-server vba

在userform上有几个文本框。当选择组合框中的项目时,只有部分项目保持可见。我想在那时单步浏览可见的文本框,并用SQL Server数据库中的数据填充它们。 组合框列表中的项与表名相同,因此它成为SQL语句中的参数。

调试代码时执行语句时弹出错误(它在Management Studio中运行正常)。也许我错过了一些字符,例如'"whitespace(但代码不是红色的)或代码有问题并使用记录集本身:< / p>

    Private Sub cboTyp_AfterUpdate()

Dim rs As ADODB.Recordset
Dim Nazwa As String
Dim Skr As String
Dim Kolumna As String
Dim c As Control

On Error Resume Next
For Each c In Me.Controls
    Select Case c.TabIndex
        Case 3 To 10:
            If c.Visible = True Then
            Nazwa = c.Name
            Skr = Right(Nazwa, 5)

            On Error GoTo Nazwa_Initialize_Err:
            Set rs = New ADODB.Recordset

                rs.Open "SELECT DISTINCT c.name AS NazwaKolumny FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                            " WHERE c.name LIKE '%" & Skr & "';", _
                                con, adOpenStatic
                Kolumna = rs.Fields("NazwaKolumny")
                rs.Close
                Set rs = Nothing

                'Wyszukanie ostatniej wartości dla wybranej składowej
                    Set rs = New ADODB.Recordset
                    rs.Open "Declare @sqlCommand varchar(max)" & _
                                " Declare @columnName varchar(250)" & _
                                " Set @columnName = (SELECT DISTINCT c.name FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                                " WHERE c.name LIKE '%" & Skr & "')" & _
                                " Set @sqlCommand = 'SELECT [' + @columnName + ']' + " & _
                                " 'FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'" & _
                                " Exec (@sqlCommand);", _
                                    con, adOpenStatic

                'Jeżeli brak wartości (zwróci NULL) oznacza to przejdź do normalnego wstawiania
                    If rs.RecordCount = 0 Then
                        c.SetFocus
                    'Jeśli znajdzie wartość to ją wstaw
                    Else
                        rs.MoveFirst
                            Do
                                Nazwa = rs.Fields(Kolumna)
                                rs.MoveNext
                            Loop Until rs.EOF
                    End If
            End If
    End Select
Next
On Error GoTo 0

'Opuszczanie pola - zamknięcie i wyczyszczenie Recordset
Nazwa_Initialize_Exit:
    On Error Resume Next
    rs.Close
    Set rs = Nothing

Exit Sub

2 个答案:

答案 0 :(得分:2)

修改 请在使用之前为其分配一个新的记录集对象,例如

删除了SET NOCOUNT ON。它主要用于存储过程。

    set rs= New ADODB.Recordset

   rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
   rs.Open "Declare @sqlCommand varchar(max)" & _
                        " Declare @columnName varchar(250)" & _
                        " Set @columnName = (SELECT DISTINCT c.name FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id" & _
                        " WHERE c.name LIKE '%" & Skrócona & "')" & _
                        " Set @sqlCommand = 'SELECT ' + '[' + @columnName + ']' + " & _
                        "' FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'" & _
                        " Exec (@sqlCommand);", _
                            con, adOpenStatic

还为正确的记录计数添加了rs.CursorLocation

答案 1 :(得分:0)

您在前缀和结尾处有额外的单引号:

"' FROM [" & cboTyp.Value & "] WHERE ID = (SELECT MAX(ID) FROM [" & cboTyp.Value & "])'"

我不会建议这样的代码容易出现SQL注入攻击并使用参数代替。在示例的帮助中检查sp_ExecuteSQL。