retrieve resultset from MSSQL stored procedure in classic asp - vbscript

I'm not well versed in ASP, but that's what I've got to work with for the moment. I have a stored procedure that generates a resultset which i'd like to handle in classic ASP. I can see the resultset if I run the SP in SQL Management Studio with the same parameter so I know its working.
The stored procedure takes 1 parameter #part, i've testing with the following code and can see the SP is executed using SQL Profiler, but I get a '500 - Internal server error' returned from ASP instead of a resultset displayed.
How do correctly retrieve the resultset?
Dim fpart, objCommand, objRecordset
fpart = "SMF10320BRNU12"
Set objCommand = Server.CreateObject("ADODB.Command")
With objCommand
.ActiveConnection = db
.CommandText = "sp_movements"
.CommandType = 4
.CommandTimeout = 240
.Parameters.Append .CreateParameter("#part", 200, 1, 20)
.Parameters("#part") = fpart
Set objRecordset = .Execute
End With
for each x in objRecordset.Fields
Response.Write(x.name)
Response.Write(" = ")
Response.Write(x.value & "<br />")
next
Response.Write("<br />")
objRecordset.MoveNext
objRecordset.Close
Set objRecordset = nothing
objCommand.Close
Set objCommand = nothing

So I figured this out on my own. After digging though some logs I saw an error which I hadn't spotted previously:
Object_doesn't_support_this_property_or_method:_'Close'
Turns out I was incorrectly trying to close the command object: objCommand.Close
My working solution is:
Dim fpart, objCommand, objRecordset
fpart = "SMF10320BRNU12"
Set objCommand = Server.CreateObject("ADODB.Command")
With objCommand
.ActiveConnection = db
.CommandText = "sp_movements"
.CommandType = 4
.CommandTimeout = 240
.Parameters.Append .CreateParameter("#part", 200, 1, 20)
.Parameters("#part") = fpart
Set objRecordset = .Execute
End With
Do until objRecordset.EOF
for each x in objRecordset.Fields
Response.Write(x.name)
Response.Write(" = ")
Response.Write(x.value & "<br />")
next
Response.Write("<br />")
objRecordset.MoveNext
loop
objRecordset.Close
Set objRecordset = nothing
Set objCommand = nothing
Note:
This code also has a Do until loop around added to output all the rows from the recordset, but that wasn't strictly necessary to get something output on the page.
EDIT
Edited to reflect comments from Lankymart below, I did need to close the recordset.

Related

ADO recordset not populated by ADO command execute method

I am doing some clean up to protect from SQL injection attacks happening in a older internal website that uses ASP. Here's the gist of it all in code...
Database connection is setup in a separate asp file named connect.asp
<%
on error resume next
Set DB = Server.CreateObject("ADODB.Connection")
DB.CommandTimeout = 180
DB.ConnectionTimeout = 180
connStr = "Provider=SQLOLEDB;Data Source=xxx-xxxx-xxxxxx;Initial Catalog=xxxx;Persist Security Info=True;User ID=xxxxx;Password=xxxxxxxxxxxx;"
DB.Open connStr
' Check DB connection and go to Error Handler is error exists
if DB.state=0 then
Response.Write "<p>Cannot connect to database.</p>"
TrapError Err.description
Response.end
end if
%>
This works and the db connections is opened.
I have a file named DBFunctions.asp that I use to sort of map functions to stored procedures and their parameters. I am trying to use the function below to return a ADO recordset to another asp front end page.
Function GetFacilityByFID(fid)
set rs = server.CreateObject("ADODB.Recordset")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = DB
cmd.CommandText = "GetFacilityByFID"
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("#FID", adVarChar, adParamInput, 20)
cmd("#FID") = fid
Set rs = cmd.Execute
Set GetFacilityByFID = rs
End Function
Here is the code from the calling front end asp page, facDetail.asp
<%
Dim FID, FCBI, Error
FID = Request("FID")
FCBI = Request("FCBI")
' Check DB connection and go to Error Handler is error exists
if DB.state=0 then
Response.Write "<p>Cannot connect to database.</p>"
TrapError Err.description
Response.end
else
if FID then
Set RS = GetFacilityByFID(FID)
elseif FCBI then
Set RS = GetFacilityByFCBI(FCBI)
end if
if RS.EOF then
Response.Write "<BR><p class=alert>No record found</p>"
response.End
end if
end if
%>
The calling page is displaying that there are no records returned
but the stored procedure works when executed in SSMS.
Updated code
Here's the SQL Code for the GetFacilityByFID stored procedure.
CREATE PROCEDURE [dbo].[GetFacilityByFID]
#FID varchar(20)
AS
BEGIN
SET NOCOUNT ON;
SELECT [FAC_CBI_NBR]
,[FAC_ID]
,[FAC_TYPE]
,[FAC_SUBTYPE]
,[FAC_REGION]
,[FAC_COST_CENTER]
,[FAC_SUPPLY_CODE]
,[FAC_UPLINE]
,[FAC_SERVICE]
,[FAC_LOCATION_NAME]
,[FAC_LOCAL_ADDR1]
,[FAC_LOCAL_ADDR2]
,[FAC_LOCAL_CITY]
,[FAC_LOCAL_STATE]
,[FAC_LOCAL_ZIP]
,[FAC_MAIL_ADDR1]
,[FAC_MAIL_ADDR2]
,[FAC_MAIL_CITY]
,[FAC_MAIL_STATE]
,[FAC_MAIL_ZIP]
,[FAC_COUNTRY]
,[FAC_PHONE]
,[FAC_FAX]
,[FAC_MANAGER]
,[FAC_CONTACT]
,[FAC_CONTACT_PHONE]
,[FAC_CONTACT_EXT]
,[FAC_CONTACT_EMAIL]
,[FAC_COMMENTS]
,[FAC_CHANGED_BY]
,[FAC_LAST_UPDATE]
,[FAC_MAILOUT]
,[FAC_CONTRACTION]
,[FAC_PROPERTY_CODE]
,[FAC_ATTN_TO]
FROM [cbid].[dbo].[FACILITY]
WHERE [FAC_ID]=#FID
END
GO
Can anyone tell me what is going wrong? I have been looking at this too long and have grown frustrated with it.
Any help will be greatly appreciated!
Edit:
Current Status of issue: getting the following from the ADO provider
Error Number: -2147217904 Error Desc: Procedure or function 'GetFacilityByFID' expects parameter '#FID', which was not supplied. Error Source: Microsoft OLE DB Provider for SQL Server
You need to specify the size.
From CreateParameter Method (ADO)
If you specify a variable-length data type in the Type argument, you
must either pass a Size argument or set the
Size
property of the Parameter object before appending it to the
Parameters collection; otherwise, an error occurs.
cmd.Parameters.Append cmd.CreateParameter("#FID", adVarChar, adParamInput, Len(fid))
Before going any further, the first thing is to confirm if your stored procedure GetFacilityByFID actually returns a Recordset? Most likely it does not. If it only return a single string value, you should modify Function GetFacilityByFID(fid) to something like below:
Function GetFacilityByFID(fid)
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = DB
cmd.CommandText = "GetFacilityByFID"
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("#returnVal", adVarChar, adParamOutput, 255, "")
cmd.Parameters.Append cmd.CreateParameter("#FID", adVarChar, adParamInput)
cmd("#FID") = fid
cmd.Execute
GetFacilityByFID = cmd("#returnVal")
End Function
I rewrote the function using some of the examples I found and some of LankyMart's suggestions. Thanks everyone for your help.
Here's the working code...
Function GetFacilityByFID(fid)
Set rs = server.CreateObject("ADODB.Recordset")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = DB
cmd.CommandText = "GetFacilityByFID"
cmd.CommandType = adCmdStoredProc
cmd.CommandTimeout = 900
set prm = cmd.CreateParameter("#FID",adVarChar, adParamInput, 20, fid)
cmd.Parameters.Append prm
rs.CursorLocation = adUseClient
rs.Open cmd, , adOpenForwardOnly, adLockReadOnly
Set GetFacilityByFID = rs
On Error GoTo 0
End Function
The way you're setting the parameters looks no right, try this instead:
Dim param
Set param = cmd.CreateParameter("#FID", adVarChar, adParamInput)
cmd.Parameters.Append param
param.Value = fid
You can read more here: https://msdn.microsoft.com/pt-br/library/ms675860(v=vs.85).aspx
Hope it helps

VBA Recordset / Oracle and Excel Connect

I've installed tries recordset in my vba statement.
Unfortunately he accesses only the first line in my database. Who can help me?
I'm not very good in VBA it's my first porject. I hope someone can help me with my code. Thank you
Sub Testbox()
Dim conn, Rs
Dim strSQL As String
Dim auswahl As Integer
auswahl = MsgBox("Die Daten werden geladen", vbOKCancel, "Bitte auswählen")
If auswahl = 1 Then
connstring = "UID=user;PWD=passwort;DRIVER={Microsoft ODBC For Oracle};SERVER=server.WORLD;"
Set conn = New ADODB.Connection
With conn
.ConnectionString = connstring
.CursorLocation = adUseClient
.Mode = adModeRead
.Open
End With
Set Rs = CreateObject("ADODB.Recordset")
strSQL = "select * from table where logdatum =1507"
Rs.Open strSQL, conn, 3, 3
Range("A2:A5000") = Rs("scanclient")
Range("B2:B500") = Rs("Sum")
Range("C2:C500") = Rs("batchclass")
Rs.Close
Set Rs = Nothing
conn.Close
Set conn = Nothing
Else
Exit Sub
End If
End Sub
Unfortunately, it is not possible to print data from Recordset into worksheet like that:
Range("A2:A5000") = Rs("scanclient")
Range("B2:B500") = Rs("Sum")
Range("C2:C500") = Rs("batchclass")
You need to replace this code with the below:
Dim i As Long: i = 1
Do Until Rs.EOF
i = i + 1
Cells(i, 1) = Rs("scanclient")
Cells(i, 2) = Rs("Sum")
Cells(i, 3) = Rs("batchclass")
Call Rs.MoveNext
Loop

PL/SQL stored procedure out cursor to VBA ADODB.RecordSet?

To preface this post, I want to say that I am fairly new to Excel 2007 vba macros. I am trying to call an Oracle PL/SQL stored procedure that has a cursor as an output parameter. The procedure spec looks like this:
PROCEDURE get_product
(
out_cur_data OUT SYS_REFCURSOR,
rptid IN NUMBER,
scenario IN VARCHAR2
);
And I have written my macro as:
Sub GetProduct()
Const StartRow As Integer = 4
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
With conn
.ConnectionString = "<my connection string>"
.Open
End With
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandType = adCmdText
.CommandText = "{call their_package.get_product({out_cur_data 100},?,?)}"
.NamedParameters = True
.Parameters.Append cmd.CreateParameter("rptid", adNumeric, adParamInput, 0, 98)
.Parameters.Append cmd.CreateParameter("scenario", adVarChar, adParamInput, 4, "decline001")
End With
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs
.CursorType = adOpenStatic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
End With
Set rs = cmd.Execute
Cells(StartRow + 1, 1).CopyFromRecordset rs
rs.Close
conn.Close
End Sub
This does not work obviously, I get a run-time error '-2147217900 (80040e14): One or more errors occurred during processing of command.' So, OK.
I am looking for some guidance/advice on how to bring back that cursor into an ADODB.RecordSet. I don't think I have set up the output cursor correctly for "out_cur_data", but my searches online for any help have come up dry so far. Can any give me a basic working example to help me understand what I am doing wrong?
BTW... I do not have control of the stored procedure at all, it is from an external package.
Any help is really appreciated.
Thanks,
Doran
I think it should be this one:
With cmd
.Properties("PLSQLRSet") = TRUE
.ActiveConnection = conn
.CommandType = adCmdText
.CommandText = "{call their_package.get_product(?,?)}"
.NamedParameters = True
.Parameters.Append cmd.CreateParameter("rptid", adNumeric, adParamInput, 0, 98)
.Parameters.Append cmd.CreateParameter("scenario", adVarChar, adParamInput, 4, "decline001")
End With
...
Set rs = cmd.Execute
cmd.Properties("PLSQLRSet") = FALSE
Note:
Although their_package.get_product() takes three parameters, only two need to be bound because Ref cursor parameters are automatically bound by the provider.
For more information check Oracle documentation: Oracle Provider for OLE DB Developer's Guide - "Using OraOLEDB with Visual Basic"

vbscript, validate a user is in active directory by schema attribute

I'm trying to write a vb script that prompts a user for a schema attribute which I'll call bID and checks that the person with that bID is in active directory. I really have no idea how to get started, there are plenty of examples on how to query active directory users but I havent found a good one regarding checking against specific attributes. Any help/suggestions are greatly appreciated!
UPDATE:
ok heres my code so far, doesnt error out and returns 0, but I dont get a wscript.echo of the distinguished name for some reason. I included a few debugging wscript.echo's and it seems to never get into the while loop. Any ideas?
Option Explicit
GetUsers "CN=users,DC=example,DC=example,DC=example,DC=com","123456"
Function GetUsers(domainNc, ID)
Dim cnxn
Set cnxn = WScript.CreateObject("ADODB.Connection")
cnxn.Provider = "ADsDSOObject"
cnxn.Open "Active Directory Provider"
Dim cmd
Set cmd = WScript.CreateObject("ADODB.Command")
cmd.ActiveConnection = cnxn
cmd.CommandText = "<LDAP://" & domainNc & ">;(&(objectCategory=user)(objectClass=user) (employeeNumber=" & ID & "));distinguishedName;subtree"
WScript.Echo cmd.CommandText
cmd.Properties("Page Size") = 100
cmd.Properties("Timeout") = 30
cmd.Properties("Cache Results") = False
WScript.Echo "setting cmd.properties"
Dim rs
Set rs = cmd.Execute
WScript.Echo "rs object set"
While Not rs.eof
On Error Resume Next
WScript.Echo "while loop start"
Wscript.Echo rs.fields("distinguishedName".Value)
rs.MoveNext
If (Err.Number <> 0) Then
WScript.Echo vbCrLf& "Error # "& CStr(Err.Number)& " "& Err.Description
Else
On Error GoTo 0
End If
Wend
WScript.Echo "while loop end"
rs.close
WScript.Echo "rs object closed"
cnxn.Close
Set rs = Nothing
Set cmd = Nothing
Set cnxn = Nothing
End Function
Here's some vbscript that will find all users with bID=FooVal and write their DN out
Function GetUsers(domainNc, bIdVal)
Dim cnxn
Set cnxn = WScript.CreateObject("ADODB.Connection")
cnxn.Provider = "ADsDSOObject"
cnxn.Open "Active Directory Provider"
Dim cmd
Set cmd = WScript.CreateObject("ADODB.Command")
cmd.ActiveConnection = cnxn
cmd.CommandText = "<LDAP://" & domainNc & ">;(&(objectCass=user)(objectCategory=person)(bid=" & bidVal & "));distinguishedName;subtree"
cmd.Properties("Page Size") = 100
cmd.Properties("Timeout") = 30
cmd.Properties("Cache Results") = False
Dim rs
Set rs = cmd.Execute
While Not rs.eof
Wscript.Echo rs.fields("distinguishedName").Value
rs.MoveNext
Wend
rs.close
cnxn.Close
Set rs = Nothing
Set cmd = Nothing
Set cnxn = Nothing
End Function

updating the table using recordset

I have a recordset rcdDNE. I want to update my reclamation by making some conditions with my existing recordset. But my table is not updating. Can you guys tell me where I am doing wrong?
Dim lngRecCount As Long
frmDNELoad.lblStatus.Caption = "Updating records in Reclamation Table..."
frmDNELoad.Refresh
CqDate = Format(Date, "dd/MM/yyyy")
Set rcdreclamation = New ADODB.Recordset
With rcdreclamation
.ActiveConnection = objConn
.Source = "SELECT * FROM T_DATA_reclamation"
.CursorType = adOpenDynamic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open
End With
rcdDNE.MoveFirst
Do Until rcdDNE.EOF
With cmdDNEFRC
.ActiveConnection = objConn
.CommandText = "update t_data_reclamation set ClaimStatus = 'C',DateClosed = 'CqDate', Audit_LastUpdated = 'CqDate', Audit_UserAdded = 'SYSTEM' where RTProvided = '" & rcdDNE("AccountNbr") & "'"
.CommandType = adCmdText
End With
rcdDNE.MoveNext
Loop
Unless its something you forgot to put in your sample code, You are missing a call to the Execute function inside your Command object's with block.
With cmdDNEFRC
.ActiveConnection = objConn
.CommandText = "update t_data_reclamation set ClaimStatus = 'C',DateClosed = 'CqDate', Audit_LastUpdated = 'CqDate', Audit_UserAdded = 'SYSTEM' where RTProvided = '" & rcdDNE("AccountNbr") & "'"
.CommandType = adCmdText
.Execute 'dont forget execution
End With
Also when writing data to the table, using Connection objects BeginTrans and CommitTrans function is recommended, just in case something has to go wrong when writing the data you don't end up with data inconsistencies.

Resources