How to get the total number of records count from a sql ado dB connection in classic asp [duplicate] - asp-classic

I am newbie in VBScript and I've come across with the following problem. I want get data from sql server db and to allow RecordCount properties. Next code get data but RecordCount is disabled. How can I enable this properties
Const DB_CONNECT_STRING = "Provider=SQLOLEDB.1;Data Source=BUG\SQLSERVER2005;Initial Catalog=test;user id ='sa';password='111111'"
Set myConn = CreateObject("ADODB.Connection")
Set myCommand = CreateObject("ADODB.Command" )
myConn.Open DB_CONNECT_STRING
Set myCommand.ActiveConnection = myConn
myCommand.CommandText = ("select * from klienci k where k.indeks = " & oferty(16))
Set klienci = myCommand.Execute

AFAIK you can't change the cursor type when using the Execute method of the Command object, and you can't change the cursor type after you retrieved the recordset. Something like this might work, though:
Const DB_CONNECT_STRING = "Provider=SQLOLEDB.1;Data Source=BUG\SQLSERVER2005;Initial Catalog=test;user id ='sa';password='111111'"
Set myConn = CreateObject("ADODB.Connection")
myConn.Open DB_CONNECT_STRING
query = "select * from klienci k where k.indeks = " & oferty(16)
Set klienci = CreateObject("ADODB.Recordset")
klienci.CursorLocation = 3 'adUseClient
klienci.CursorType = 3 'adOpenStatic
klienci.LockType = 1 'adLockReadOnly
klienci.Open query, myConn

I don't think this is a VBScript issue- I think it is an ADO issue.
I think you are using a default forward-only cursor which won't work with recordcount.
I think you should stick a cursortype=adOpenStatic in there but I'm having a little trouble determining if you are specifying a recordset object - klienci?
If so try
klienci.cursortype=adOpenStatic

Related

Stored Procedure not working from ASP.NET

I have the following stored procedure:
alter proc SPCP_ProgramUpdate
#ID int,
#UserID int,
#Name nvarchar(150),
#University int,
#Level tinyint,
#isActive bit
as
update tblUniversityProgram set University_Fkey = #University, Level_Fkey = #Level, Program_Name = #Name, EditDate = GETDATE(), EditUser = #UserID, isActive = #isActive
where tblUniversityProgram.ID = #ID
When I run the stored procedure from SSMS, it works as intended.
However, when I run that stored procedure from ASP.NET using this code:
Dim varDbconn As New SqlConnection
Dim varDbcomm As SqlCommand
Dim varDbRead As SqlDataReader
varDbconn.ConnectionString = ConfigurationManager.ConnectionStrings("CPDB_ConnectionString").ToString
varDbconn.Open()
If Request.QueryString("program") <> "" Then
varDbcomm = New SqlCommand("SPCP_ProgramUpdate", varDbconn)
varDbcomm.CommandType = CommandType.StoredProcedure
varDbcomm.Parameters.AddWithValue("#ID", Request.QueryString("program")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#UserID", Session("UserID")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#University", Session("DecryptID")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#Level", ddlLevel.SelectedValue).DbType = DbType.Byte
varDbcomm.Parameters.AddWithValue("#isActive", chkisActive.Checked).DbType = DbType.Boolean
varDbcomm.Parameters.AddWithValue("#Name", txttitle.Text).DbType = DbType.String
varDbcomm.ExecuteNonQuery()
varDbcomm.Dispose()
Else
....
End IF
varDbconn.Close()
nothing happens.
Any ideas?
The most likely answer to your question is that the value you are getting out of the querystring for program is not the Id in your database that you expect.
At the minute, your code is reading in input values and passing them to a stored procedure without any validation of your expected values - missing session for example could cause you all sorts of unexpected issues.
Debug your code and see exactly what parameters you are passing to your DB. Check your connection string to see that you are hitting the database where you have amended your stored procedure.
What you have should work. I would use parmaters.Add in place of addwith, but that should not really matter.
Try adding this code right after you are done setting up the parmaters:
Debug.Print("SQL = " & varDbcomm.CommandText)
For Each p As SqlParameter In varDbcomm.Parameters
Debug.Print(p.ParameterName & "->" & p.Value)
Next
That way in the debug window (or immediate depending on VS settings), you see a list of param values, and the parameter names. I suspect one of the session() values is messed up here.

Insert long string into Access DB using parametrised query in classic ASP

I'm trying to update a classic ASP application and as part of the update I've tried to replace dynamic SQL using string concatenation with a parametrised query.
The problem is that the parameters won't accept a value which is longer than 210 characters.
I get the following error...
ADODB.Parameter error '800a0d5d'
Application uses a value of the wrong type for the current operation.
/admin/Save_product_subcategories.asp, line 30
My first attempt looks like this...
SQLString = "UPDATE Product_SubCategories
SET SubCategory=?, Description=?
WHERE SubCategoryID=?"
Set courseCommand = Server.CreateObject("ADODB.Command")
courseCommand.ActiveConnection = objConn
courseCommand.CommandText = SQLString
courseCommand.Parameters(0).value = cleanCategory
courseCommand.Parameters(1).Value = cleanDescription
courseCommand.Parameters(2).value = cleanSubCategoryId
I've tried manually setting the parameter type and increasing the size of the parameter...
courseCommand.Parameters(1).Type = 203
courseCommand.Parameters(1).Size = 300
courseCommand.Parameters(1).Type = adLongVarWChar
I've also tried creating a parameter with the command.CreateParameter method but that gives the same error.
param = courseCommand.CreateParameter(,,,,cleanDescription)
'or
param = courseCommand.CreateParameter(,adLongVarWChar,,,cleanDescription)
'or
param = courseCommand.CreateParameter(,adLongVarWChar,,300,cleanDescription)
courseCommand.Parameters(1) = param
I'm beginning to think that my only option is to go back to dynamic sql.
Edit:
I tried to Append the parameter instead of adding it to the collection using the array index but none of the parameters worked after that.
Provider error '80020005'
Type mismatch.
/admin/Save_product_subcategories.asp, line 31
For anyone else looking for this the answer is to use a Recordset.
SQLString = "select * from Product_SubCategories where 1=0"
Set rs= Server.CreateObject("ADODB.Recordset")
rs.open SQLString , objConn, 1,3 'open as keyset ,lock optimistic that will create empty recordset for you
' Add new record
rs.AddNew
'assign values
rs("SubCategoryID")=cleanSubCategoryId
rs("Description")=cleanDescription
rs("SubCategory")=cleanCategory
' send new record with values to database
rs.Update
'close recordset
rs.close
'destroy recordset object
se rs=nothing

How can I use an ADODB.CommandObject with ADODB.RecordSet?

I am trying to make a Classic ASP/VBScript website more secure by making SQL statements parameterized.
I have the following function:
Function OpenUpdateableRS(strSQL)
Dim rs
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open strSQL, cnDZ, adOpenKeyset, adLockPessimistic, adCmdText
Set OpenUpdateableRS = rs
Set rs = Nothing
End Function
I intend to convert it to something like:
Function SecureOpenUpdateableRS(strSQL, strParam1, strParam2)
Dim rs
Dim cmdOB
Set cmdOB = Server.CreateObject("ADODB.CommandObject")
With cmdOB
.ActiveConnection = cnDZ
.CommandText = strSQL
.Parameters(0).value = strParam1
.Parameters(0).value = strParam2
End With
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open cmdOB.Execute, , adOpenKeyset, adLockPessimistic
Set SecureOpenUpdateableRS = rs
Set rs = Nothing
End Function
When I call the function with:
Set rs = SecureOpenUpdateableRS("SELECT CustID, LastActive, LoggedIn, SessionID FROM tblLogins WHERE EMail = ? AND PWord = ?", strEMail, strPassword)
I get a "500 - Internal Server Error" which is probably because I disabled debugging on the server.
Any ideas on how I could make the original function more secure without breaking it?
You'll have to create the parameters and append them to the command's parameter collection. Just assigning the values to (the same!) parameter can't possibly work. Google for a sample; perhaps this VB! sample will get you started.
Added:
I can think of two strategies to derive the parameter types:
If you pass the correct/maximally specified parameter values to the function you can map VarType(value) constants to parameter type constants
If you do a SELECT based on the fieldnames in the command text, you can map the recordset's field .Types to parameter type constants
It won't be trivial to get this right for all possible cases. I would pass pairs of value and desired type to the function.

How to run a stored procedure with param and store result as a record set in classic asp

I wasn't able to find a question/answer that covers this fully hence why I am asking. What I need to do is run a stored procedure that takes 1 parameter. It will return a set of results which I need to store in a record set. I plan to loop through this recordset later. I'm pretty inexperienced when it comes to older asp, but here is what I have to far:
dim myConn
Set myConn = Server.CreateObject("ADODB.Connection")
myConn.Open = ("DSN=example-dsn;SERVER=example-server;DATABASE=example-db;UID=user;PWD=pass;")
dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")
With oStoredProc
.ActiveConnection = myConn
.CommandType = adCmdStoredProc
.CommandText = "myStoredProcedure"
.Parameters.Append(.CreateParameter("#PARAM1", ADODB.adInteger, ADODB.adParamInput, 10, 2012))
Dim rs : Set rs = .Execute()
End With
// Will loop through it here.
My guess is that I'm not setting up the recordset right, but like I said, I'm not really sure. If anyone can point me in the right direction I'd appreciate it!
You will want to make sure your result set is the correct object
set rs = Server.CreateObject("ADODB.Recordset")
Then you will use the open method I think it works something like this:
rs.Open oStoredProc
Then use the other members of the Record Set object to loop through the results.
Alright there were a few things I was doing wrong but here is what ended up working for me. First off it turns out I didn't need a parameter passed in, but that was not the problem anyway. One of the main issues what that 'adCmdStoredProc' wasn't recognized, which is odd because I've seen it used everywhere else, but replacing it with it's corresponding value, 4, did work.
dim myConn, cmd
Set myConn = Server.CreateObject("ADODB.Connection")
myConn.Open = ("DSN=[BLAH];SERVER=[SERVER];DATABASE=[BLAH];UID=[User];PWD=[Pass];")
dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")
oStoredProc.CommandType = 4
oStoredProc.CommandText = "StoredProcedureName"
oStoredProc.ActiveConnection = myConn
// Add parameters here if needed.
Dim rs
Set rs = oStoredProc.Execute()
// I Loop through here
rs.Close
myConn.Close
Set rs = Nothing
Set oStoredProc = Nothing
Set myConn = Nothing
I hope this helps if anyone else needs it.
Dim rsStk As New ADODB.Recordset
Set rsStk = cnnPck.Execute("SP_JOB_ALL '" & Trim(te_Item) & "'")
Set Recordset= CONNECTION .Execute()
This one is simple way to do this thing

ADO.RecordCount equals - 1 problem

When ever I try to access the RecordCount property, I always get a return value of -1. Below is my sample code.
Set oConn = Server.CreateObject ("ADODB.Connection")
oConn.Open Application("strConnectstring")
Set rs = Server.CreateObject ("ADODB.Recordset")
rs.ActiveConnection = oConn
SQL = "Publications_PicoSearchListing"
set rs = oConn.execute(SQL)
I'm not sure if I'm doing forwardCursor or dynamic cursors, or if the provider even supports the RecordCount property. How do I check if the provider supports RecordCount property or if I'm using either forwardCursor or dynamic cursors.
Any help would be appreciated.
Thank You
Recordcount is not supported with the default forward-only cursor.
you must add extra parameters to the open command
rs.open sql,conn,1,1
That should let you have access to rs.recordcount.
But paging is best done by using the Recordset.GetRows() + Recordset.Move() method.
http://databases.aspfaq.com/database/how-do-i-page-through-a-recordset.html
(scroll down to the bold "Recordset.GetRows() + Recordset.Move()" this is fastest way without using stored procedures)
Please note: unless you move to the end of the recordset there is no guarantee that the RecordCount will have been populated. The standard pattern to to iterate over each row in the recordset using While Not rs.EOF. In all the VBA code I've ever written, I have never relied on checking rs.RecordCount
Rather than checking the cursor type, you can set it. For example:
Set conn=Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("northwind.mdb"))
set rs = Server.CreateObject("ADODB.recordset")
sql="SELECT * FROM Customers"
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockBatchOptimistic
rs.Open sql, conn
If all you want is the count, why not emit a "SELECT Count(*) From Publications_PicoSearchListing"
Of Interest?: Understanding ADO's Default Cursor Type
Another alternative to get the RecordCount is to execute:
rs.MoveLast
rs.MoveFirst
and then check the RecordCount, and even then I seem to remember some cursor types aren't guaranteed (but memory hazy on this).
Also note: Don't use the MoveLast/MoveFirst unless you really need to: this will be slow with a large recordset or a recordset drawn across a network. Instead use the Count(*) technique.
For paging you can use the recordset.PageSize and recordset.AbsolutePage like this
Set rs = Server.CreateObject("ADODB.Recordset")
' make recordset use adUSEclient ( client side cursor)'
rs.CursorLocation = 3
' make recordset use the adOpenStatic cursor ( scrollable )'
rs.CursorType = 3
rs.PageSize = RecordsPerPage
rs.Open sql, conn
' go to selected page'
if not rs.EOF and not rs.BOF then
rs.AbsolutePage = page_you_want_to_go
end if
you then have access to recordset.PageCount to know the number of pages returned..

Resources