Output params and Stored Procedure - asp-classic

I've googled but none of the solutions seems to work for me!
I have a SPROC in SQL Server which has an input param and also an output parameter being set within the SPROC.
using classic ASP, I want to retrieve the value of that output parameter but nothing seems to get set (but I can see the output parameter working correctly when executing in the SQL Server Management Studio)
OpenConnection
Set cmdTemp = Server.CreateObject("ADODB.Command")
cmdTemp.CommandType = 4 'adCmdStoredProc
Set cmdTemp.ActiveConnection = dbConn
cmdTemp.CommandText = "GetCerts"
cmdTemp.Parameters.Refresh
cmdTemp.Parameters(1) = "ABC123"
cmdTemp.Parameters(2).Direction = 2 'Output
Set reader = cmdTemp.Execute
Response.Write(cmdTemp.Parameters(2)) ' Nothing is displayed at all.
CloseConnection
I tried using the named parameters approach but always got an error saying that the parameters are out of range, wrong arguments or wrong type (Something similar to this).
Really... getting a headache. I just want the OUTPUT param value set from the SPROC (2nd parameter in the SPROC)

Check for errors:
Set reader = cmdTemp.Execute
If Err.number <> 0 or dbConn.Errors.Count <> 0 Then
'Do something to handle the error
End If
Do you have permissions to execute the stored procedure? i.e. the credentials of the ASP user...
Execute Stored Procedure from Classic ASP

It seems after a long long investigation that what I am trying to do is not possible (but it is in .NET). Seems I need to execute the command twice, first time getting the output parameters values then the next time to display the results. Awful. Praise .NET!

Most collections in the COM world use zero-based indexing. Try using Parameters(0) as the input parameter and Parameters(1) as the output parameter.

Related

Handling Chinese in ASP classic

I write the following piece of codes :
rst.Open(strSQL & Request.QueryString("C-PLACE")), conn, 0, 1
But got the following error. However, if the querystring is in English or just number, no error will pop out. Any guru can help please ?
Microsoft OLE DB Provider for ODBC Drivers error '80040e10'
[Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 2.
/deliverable/GetMemberTest.asp, line 19
It's going to either be passing an encoding variable to the server, or in the case of your error, its saying "too few parameters". In this case, the parameter is "C-PLACE" and its suppose to be passed to your asp script from the previous page's link, something like:
/deliverable/GetMemberTest.asp?C-PLACE=THECPLACE
https://www.w3schools.com/asp/coll_querystring.asp
(citation about query strings)
or something like that .. obviously its not actually "THECPLACE", but just saying a QueryString("VARIABLENAME") looks to the URL of the previous page to pass the parameter to the script, so that error message should of done something to add a ? mark = C-PLACE= to something, and we aren't seeing that. So something on the previous page that was suppose to add this when they click a submit button didn't do it's job, or the script is just getting run on its own without the proper previous page's work being done to prepare it to execute properly on the following page.
It will also be of note that these types of things are easily hacked through sql script injection, so if you aren't validating your url first, someone could use some code to escape out of your sql and add their own code, such as one to drop your tables ..., so make sure you validate the variable FIRST instead of dumping it straight into your code. I can give some guidance into that later, but first lets figure out your problem.
(side note - can i request strSQL from you? Can you put this line in before that line:
<%
response.write("strSQL is " & StrSQL & "<BR>")
%>
All this code does is display what is stored in the StrSQL variable, see if we can figure out what is going on here. Also take note that your error message indicated that it expected 2 parameters, so we are missing 2 for this script to run properly.
EDIT - try this encoding:
<%
Response.CodePage=65001
Response.Charset="UTF-8"
Response.ContentType = "text/html"
%>
Try this strSQL, you didn't need the Response.Write and on C-PLACE you want to use '' instead of "" because the "" will exit you out of the SQL statement. Try this, and let me know how it works, but I still think we are going to need another parameter supplied to it, unless its getting one from the string and then it isn't actually counting the one supplied from the url perhaps.
<%
strSQL="SELECT * FROM DetailMemberInfo
WHERE C-PLACE=" & strSQL & Request.QueryString('C-PLACE'))"
%>

Prepared Statements and sanitizing data

When using a prepared statement with Classic ASP such as this:
SQL = "SELECT user_name, user_sign_up_date FROM tbl_users WHERE this = ? AND id = ? "
Set stmt01 = Server.CreateObject("ADODB.Command")
stmt01.ActiveConnection = oConn
stmt01.Prepared = true
stmt01.commandtext = SQL
stmt01.Parameters.Append stmt01.CreateParameter("#x1", adVarChar, adParamInput, 255, card_pwd)
stmt01.Parameters.Append stmt01.CreateParameter("#x2", adInteger, adParamInput, , this_id)
set myRS = stmt01.Execute
Apart from doing the usual sense checking to e.g. make sure that a number is a number and so on, does the process of using this kind of Parameterised Statement mean that I no longer have to worry about, e.g. for a varchar or text field, sanitising the data input from users - e.g. would I no longer need to use a function to push everything input by a user through Server.HTMLencode?
I'm not sure if the parameterised statement route means I can be less strict re. sanitizing user data now?
You are conflating two different types of sanitisation. SQL parameterization prevents the “Bobby Tables” vulnerability — a maliciously written bit of data that tricks SQL into ending the current query and executing a separate query of the attacker’s choosing.
https://bobby-tables.com
Even with SQL parameters, an attacker could try to run a script on your page by (for example) entering “alert(‘Gotcha!’)” in a field. Display the field data on an HTML page and that script is written out and executed. To prevent that you use Server.HTMLencode
If your concern is SQL injection attacks then parameterization should remove the possibility of the SQL string being tampered with because the values are supplied at execution time.
Others are correct that you don't need to worry about the contents of the parameters. You do have to worry about the length of strings. I would pass Left(card_pwd, 255) to CreateParameter() to avoid exceptions crashing your script. I tend to not worry about calling IsNumeric() on integer parameters but that might be worthwhile (try passing nonsense and see what happens).

How to trace a call to a stored procedure and get feedback out of its execution?

I have a stored procedure that I'm calling from asp.net and I'm adding 47 parameters mostly from values selected on drop downs and radio buttons and text boxes from a form. I also have (for some reason beyond my pay grade) some parameters that are set to Null..these are also a source of some hair pulling and I don't know if these are the problems or not.
Dim Parameter As SqlParameter = New SqlParameter("#type", "u")
Dim Parameter1 As SqlParameter = New SqlParameter("#user", User)
Dim Parameter2 As SqlParameter = New SqlParameter("#term", terminal)
Dim Parameter3 As SqlParameter = New SqlParameter("#url", accesslevel)
Dim Parameter4 As SqlParameter = New SqlParameter("#name", firstname & " " & lastname)
Dim Parameter5 As SqlParameter = New SqlParameter("#mgr", mgr)
Dim Parameter6 As SqlParameter = New SqlParameter("#mgrEmail", mgr)
Dim Parameter7 As SqlParameter = New SqlParameter("#phone", mgr)
Dim Parameter8 As SqlParameter = New SqlParameter("#title", titletitle)`
... and on and on until Parameter48...
Dim myCommand As New SqlCommand("dbo.proc_vsSpacAccess", conn)
myCommand.CommandType = CommandType.StoredProcedure
myCommand.Parameters.Add(Parameter)
myCommand.Parameters.Add(Parameter1)
myCommand.Parameters.Add(Parameter2)
myCommand.Parameters.Add(Parameter3)
myCommand.Parameters.Add(Parameter4)
... and on until Parameter48... and then finally I run the stored proc..
myCommand.ExecuteNonQuery()
end of subroutine...
I run this and get nothing, no feedback, nothing. How do I know what's wrong if things aren't working? do I debug from SQL Server (I can't change the stored procedure it's not mine to change btw) or try to debug the stored procedure from Visual Studio?
I REPEAT, I CANNOT CHANGE THE STORED PROCEDURE IT IS READ ONLY FOR ME..
ExecuteNonQuery won't return anything unless you explicitly catch the return value.
If you want to know how query is executing, you can view using SQL Server Profiler.
Set a break point right after ExecuteNonQuery
Let SQL Server Profiler run at the background
See the executed query
You can even copy the query from Profiler, and run it in SSMS to make sure it even works.
Let me give you some advice on debugging. First run profiler when you run your application (on dev!) and grab the SQL that is generated.
Next open up SSMS and put that SQL in it and see if it generated valid sql. Sometimes you qwill find it did not. Then the problem is in how you are building the sql. If the SQL is valid, either it ran but didn't give you a return message or the problem is the proc itself or the data in the parameters.
Then open up the stored proc to see what it does; if it is inserting to a table or updating a table, check that table in the db to see if the data was inserted or updated based on teh variables you sent. You should always have unit tests built to check the results of an action stored proc, if you do not, then write them now, so the next time you test, you know what you should see in the database as a result of running the proc.
If you did not get the action you expected, try running the proc from SSMS with the profiled data. If the data still doesn't insert or update, you may need to ask the people responsible for the proc to track down what the problem is. Likely in this case, soemthing is wrong with the particular parameters you are sending although it could bea genuiine bug of a case taht was not expected. For instance you may be sending a null for a reuired field. Not all procs are built to properly handle errors, so it may not be sending one up the chain to you.
Lets start from the point that when it comes to executing stored procedures, you need to design it to return some feedback. Just the fact that you have stored procedure, doesn't mean that you will have any feedback. For example (pseudo-code)
Create procedure MyProc()
Begin
Try
-- Do something
-- And it happens to error here
Catch
' do nothing
End Try
End
Now, this one, will never give you any info of what happened, success or failure because error is handled within
Lets look at this one now, again, pseudo-code
Create procedure MyProc(#retVal int out)
Begin
set #retVal = -1 -- assume it failed
Try
-- Do something
set #retVal = 0 -- a flag that it is success
Catch
' do nothing
End Try
End
Now, with this you can go to your vb code and test
myCommand.ExecuteNonQuery()
Dim val as Object = myCommand.Parameters(0).Value
If CInt(val) = 0 Then
' success route
Else
' error route
End If
Basically, this is the example of one of the few methods how to obtain info about state of execution of your stored procedure. But again, you need to code for this.
Now, if you want to know in details, what is your SP doing while it is executing, again, you need to code for this. You can create a log table, in which you will store data that you scrape within your SP. I've seen designs where each SP had one parameter #debug. And, when called in debug mode, it would post logs about its execution data.

Insert using ADO with classic ASP

' Setting variables
Dim con, sql_insert, data_source
data_source = "project_db"
sql_insert = "insert into cart ( UserID,Count,ProductName,ProductDescription,ProductPrice) values ('"&user_id&"','"&count&"','"&product_name&"','"&product_description&"','"&product_price&"')"
' Creating the Connection Object and opening the database
Set con = Server.CreateObject("ADODB.Connection")
con.Open data_source
' Executing the sql insertion code
con.Execute sql_insert
' Done. Now Close the connection
con.Close
Set con = Nothing
AS you can see , it is a simple code . and it worked in my local host for 5 or 6 times. but now it didn't work. What's the problem ? I think , it's about my database or memory. i setup 2 different iis in 2 different computer and they behave same... please help..
Thanks
Does it give you any error message? Make sure all the values you are inserting actually have values and are not blank or null. You can check this by response.write all the values and then response.end to see if they contain any values.
I bet it's a data-dependent error. You should be using ADO parameters. Those will ensure that extraneous SQL-unfriendly characters in your input do not adversely affect your database operation. You should also use them to guard against SQL injection issues.
Some docs are available at http://msdn.microsoft.com/en-us/library/ms675869(VS.85).aspx, and you can google for "ADO parameters" and find many relevant examples.
I believe that 'data_source' should be focused on (and agreed with Tom Gullen as regards to error messages. Always use Option Explicit at the top of your pages).
con.Open either expects some DSN parameters or a database connection string to be passed within 'data_source'.
Examples, respectively :
data_source = DSN_Database, DSN_User, DSN_Password
(these 'DSN_' parameters are found/set in your DSN configuration)
OR :
data_source = "Driver={SQL Server};Server=server.domain.com;Database=project_db;uid=MyUser;pwd=MyPass;""

ASP Classic page quit working

I've had a set of legacy pages running on my IIS7 server for at least a year. Sometime last week something changed and now this line:
Response.Write CStr(myRS(0).name) & "=" & Cstr(myRS(0).value)
which used to return nothing more exciting than the string: 'Updated=true' (the sproc processing input params, stores them to a table, checks for errors and when that's all done returns a success code by executing this statement:
select 'true' as [Updated]
Now my pageside error handler is being involved and offers:
myError=Error from /logQuizScore.asp
Error source: Microsoft VBScript runtime error
Error number: 13
Error description: Type mismatch
Important to note that all lots of pages use the same framework - same db, same coding format, connecitonstrings and (so far as I can tell) all others are working.
Troubleshot to this point:
The call to the stored procedure is working correctly (stuff is stored to the given table). The output from the stored procedure is working correctly (i can execute a direct call with the given parameters and stuff works. I can see profiler calling and passing. I can replace all code with 'select 'true' as updated' and the error is the same.
everything up to the response.write statement above is correct.
So something changed how ADO renders that particular recordset.
So i try: Response.Write myRS.Item.count
and get:
Error number: 424
Error description: Object required
The recordset object seems not to be instantiating but the command object _did execute. Repeat - lots of other pages just the same basic logic to hit other sprocs without a problem.
full code snippet
set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = MM_cnCompliance4_STRING
cmd1.CommandText = "dbo._usp_UserAnswers_INSERT"
...
cmd1.CommandType = 4
cmd1.CommandTimeout = 0
cmd1.Prepared = true
set myRS = cmd1.Execute
Response.Write CStr(myRS(0).name) & "=" & Cstr(myRS(0).value)
It seems to me that the sproc has changed and returns a scalar instead of a result set.
Changing CommandType = 1 (adCmdText) is need to match with your query changed to SELECT 'whateveryouwannatry' AS [updated].
Since you stated that nothing in the asp code changed we can rule out that the return type of your command/sproc was altered by specifying an output parameter.

Resources