Adodb Recordset 函数.MoveNext 导致异常"UPDATE permission was denied"

Adodb Recordset function .MoveNext Causes Exception "UPDATE permission was denied"

我 运行 今天遇到了一个困扰我的问题。

下面是一些示例代码:

                Dim objRec As ADODB.Recordset 
                Dim oRec As ADODB.Recordset 
                Dim oRecBuild As New ADODB.Recordset 
                cmd = New ADODB.Command()
                cmd.ActiveConnection = objConn
                cmd.CommandText = "SelectAll_PhoneNumbers_ById"
                cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
                cmd.NamedParameters = True

                cmd.Parameters.Append(cmd.CreateParameter("@ObjId", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamInput, 20, objRec.Fields("PK_ProgramID").Value))

                oRec = New ADODB.Recordset()
                oRec.Open(cmd, , ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)

                If oRec.EOF = False Then
                    Do Until oRec.EOF
                        If IsDBNull(oRec.Fields("PhoneType").Value) = False Then
                            sName = PhoneNumberEdit(oRec.Fields("Phone").Value)
                            If IsDBNull(oRec.Fields("Extension").Value) = False And Len(oRec.Fields("Extension").Value) > 0 Then
                                sName = PhoneNumberEdit(oRec.Fields("Phone").Value) & " " & oRec.Fields("Extension").Value
                            End If
                            oRecBuild.AddNew(New Object() {"TextPrint", "TextType"}, New Object() {sName, oRec.Fields("PhoneType")})
                        End If
                        oRec.MoveNext()
                    Loop
                End If

当我到达 .MoveNext() 函数时,应用会抛出如下错误:对象 'PhoneNumbers'、数据库 'MyDb'、架构 [=24= 的更新权限被拒绝].

此代码块中没有任何内容调用更新(循环中的函数调用只是格式化数据),有人知道是什么原因造成的吗?

我还应该补充一点,我可以 运行 在本地使用 SSPI,但是代码需要能够 运行 在服务器上使用 SQL 用户名和 PW;我已经在其他页面上测试了该应用程序的更新,并且运行良好。

这只是一种预感,但我确实看到该代码中的一个地方 可能 导致更新推荐:oRecBuild.AddNew()。我不明白它怎么可能,但我想知道调用 oRec.MoveNext() 是否以某种方式强制从 oRecBuild 提交。否则,我会更长时间地查看 SelectAll_PhoneNumbers_ById 过程,以及可能附加到它使用的表或视图的任何可能的触发器。

如果失败,我会这样做:

Public Class PhoneNumber
    Public Number As String
    Public PhoneType As String
End Public
'...

Dim result As New List(Of PhoneNumber)
Using cn As New SqlConnection("connection string"), _
      cmd As New SqlCommand("SelectAll_PhoneNumbers_ById", cn)

    cmd.CommandType = CommandType.StoredProcedure
    'Is this really an integer?
    cmd.Parameters.Add("@ObjId", SqlDbType.NVarChar, 20).Value = objRec.Fields("PK_ProgramID").Value
    cn.Open()

    Using rdr As SqlDataReader = cmd.ExecuteReader()
       While rdr.Read()
          Dim phone As String = ""
          If Not IsDbNull(rdr("PhoneType"))
              phone = PhoneNumberEdit(rdr("Phone"))
          End If
          If Not IsDbNull(rdr("Extension"))
              phone = phone & " " & PhoneNumberEdit(rdr("Extension"))
          End If
          result.Add(New PhoneNumber With {.Number = phone, .PhoneType = rdr("PhoneType")})
       End While
    End Using      
End Using

当我在做的时候......任何时候你将数据从一个记录集读取到另一个记录集时,很有可能整个事情都可以完全在数据库中完成,根本没有客户端代码。

为了结束这个问题,我想继续说我终于能够解决这个问题。问题是用 sp_executesql 执行的动态 sql 明确检查 SQL 用户的 select、插入或更新权限;执行特权还不够。

因此,要么必须取消动态 SQL,要么必须授予 select/update/insert/delete 特权。

感谢大家的帮助和时间。