I've run into a problem today that has stumped me.
Here is some sample code:
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
When I reach the .MoveNext() function the app throws an error that reads like this: The UPDATE permission was denied on the object 'PhoneNumbers', database 'MyDb', schema 'dbo'.
Nothing in this code block is calling an update (the function calls in the loop are just formatting data), does anyone have any idea of what could be causing this?
I should also add that I can run this using SSPI locally, however the code needs to be able to run on a server using a SQL username and PW; I have tested updates with the app on other pages, and it works fine.
This is just a hunch, but I do see one place in that code that might result in an UPDATE commend: oRecBuild.AddNew()
. I don't see how it could, but I wonder if calling oRec.MoveNext()
is somehow forcing a commit from oRecBuild
. Otherwise, I'd take a longer look at the SelectAll_PhoneNumbers_ById
procedure, and any possible triggers that might be attached to tables or views it uses.
And if that fails, I'd do this:
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
While I'm at it... anytime you're reading data from one recordset into another there's a very strong chance that the whole thing could be done entirely in the database, with no client code at all.
To close this question, I wanted to go ahead and say that I finally was able to get this resolved. The issue was that dynamic sql being executed with sp_executesql explicitly checks the select, insert, or update privileges of the SQL user; execute privs are NOT enough.
So, either the dynamic SQL has to be done away with or the select/update/insert/delete privs must be granted.
Thank you all for the help and time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.