ASP Classic page quit working - asp-classic

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.

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'))"
%>

Classic ASP ADO simple code error

I have a one liner classic ASP server side code that is failing.
...
result = rs(0)
That is throwing a HTTP 500.100 - Internal Error and I cannot figure it out. I feel like the dumbest web programmer in the universe at the moment.
I have introduced error checking as in:
...
On Error Resume Next
result = rs(0)
If Err.Number <> 0 Then
...
End If
and the HTTP error still result!
If I run the actual query in MS SQL Server Management Studio I get the expected result (1 row, 1 column result) so it is not the SQL. If I change the code to:
result = rs(1)
the On Error Resume Next code picks up the error as "#3265: Item cannot be found in the collection corresponding to the requested name or ordinal."
If I hard code to:
result = 10.0
I get no error.
Also prior to this one line of code I first check for an existing data row as in:
If Not rs.EOF Then
result = rs(0)
End If
So I can rule out there not being any data.
Gosh, no wonder I could not find the answer as I had already concluded to eliminate the possible area of concern the DAM SQL!
The precision on the column in question was numeric(19,6) which VBScript could not handle so I casted it to float and all is well.

Output params and Stored Procedure

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.

VBScript VarType function gives weird value

I've encountered a strange problem with getting data from a Database and casting it to the correct type using VBScript for ASP.
I have a recordset retrieved using the following function:
Public Function vfuncGetRS(strQuery)
'Returns a disconnected paging capable recordset
'Note - Non Windows servers don't support disconnected recordsets so you'll always get a connected recordset on
' a non Windows server!
On Error Resume Next
Err.Clear
Dim objData
Set objData = Server.CreateObject("ADODB.Recordset")
objData.CursorLocation = adUseClient
objData.CursorType = adOpenStatic
objData.LockType = adLockReadOnly
objData.Open vlogSQLFilter(strQuery), objDB
If Not blnUNIXMode Then
Set objData.ActiveConnection = Nothing
End If
Set vfuncGetRS = objData
End Function
If I select a value from the recordset and gets its VarType it returns the value 16 eg.
Set objRS = vfuncGetRS("SELECT * FROM SOME_TABLE")
Response.Write(VarType(objRS("someColumn")))
The weirdness is in two parts
This ONLY happens on a particular server, this code is part of a CMS which I deploy on multiple sites and it's only the instance running on IIS 6.0 that causes me an issue. Also this seems to be dependent on the recordset options.
The value 16 is not a valid value for VarType to return according to the official MSDN reference
I can get round this fairly easily by adding a check to the function that is being affected by the weird values which is as follows
If VarType(strValue) = 16 Then strValue = CInt(strValue)
I have to do the above because I need the function in question to correctly detect that the type is numeric and if the VarType is 16 then IsNumeric() gives false even if the value in the variable is numeric (and it will always be numeric)
So my question is does anyone know why this happens?
As Stijn have stated, the value of 16 means that it's a One Byte Variant, specified in the C++ headers as VT_I1.
And you're only getting this value because of the MySQL connection driver (as you've stated that the environment where you encounter this 16 value is IIS6 with MySQL).
Apparently this is a bug in the MySQL driver that instead of reporting adBoolean for a BIT field it's Reporting VT_I1.
According to this, 16 might stand for VT_I1, thus a single byte signed integer.

asp errors not displayed

I have moved an sql database from one server to a new one (detached/attached)
Now i experience some strange behavior as it does not work but NO error is displayed.
This is the code
<%
const database_dsn="PROVIDER=SQLNCLI10; SERVER=FR-2626\SQLLOP;DATABASE=Lop;Uid=admin-sql;Pwd=xxxx;"
response.write "Step 0//"
set conn=server.CreateObject("ADODB.Connection")
set RS=server.CreateObject("ADODB.Recordset")
conn.Open database_dsn
response.write "Step 1//"
req = "Select count(*) From tblArticleList"
response.write "Step 2//"
set RS = conn.Execute(req)
response.write "Step 3//"
%>
The program stops at Step 2; then nothing, no error is displayed...
I just don t know what to do..How can i get some error?
Thanks
Jonathan
Oh i partially found the answer for the error display.
In the Debug pane of the IIS directory configuration, Enable ASP debugging should NOT be checked...althought i thougth it should...
have you got your browser set to "show friendly http errors" this in conjuction with what you have already identified is the common causes I've had for not seeing an error message.
Shahkaplesh is also right that you can use Server.GetLastError() to get the last error that occurred but you shouldn't need to do this in this example.
When executing a query you don't use the "Set" command. I don't know why its not showing you anything, but your code should look more like this:
<%
const database_dsn="PROVIDER=SQLNCLI10; SERVER=FR-2626\SQLLOP;DATABASE=Lop;Uid=admin-sql;Pwd=xxxx;"
response.write("Step 0//")
set conn=server.CreateObject("ADODB.Connection")
set RS=server.CreateObject("ADODB.Recordset")
conn.Open database_dsn
response.write("Step 1//")
req = "Select count(*) From tblArticleList"
response.write("Step 2//")
RS = conn.Execute(req)
response.write("Step 3//")
%>
Yes, the parentheses on the "Response.Write" are optional. But I'm OCD like that and it makes troubleshooting a little easier.
You need to place error checking code to find out what the actual error might be.
I would suggest that you change you code like so:
<%
const database_dsn="PROVIDER=SQLNCLI10; SERVER=FR-2626\SQLLOP;DATABASE=Lop;Uid=admin- sql;Pwd=xxxx;"
'Its very important to add this line!!! '
On Error Resume Next
'Its very important to add this line!!! '
response.write "Step 0//"
set conn=server.CreateObject("ADODB.Connection")
set RS=server.CreateObject("ADODB.Recordset")
conn.Open database_dsn
if err.number<>0 then
response.write err.description
end if
response.write "Step 1//"
req = "Select count(*) From tblArticleList"
response.write "Step 2//"
set RS = conn.Execute(req)
if err.number<>0 then
response.write err.description
end if
response.write "Step 3//"
%>
And not to kick a dead horse but I'm doing something similar against an Oracle database and I've had two phantom problems I have yet to identify root cause but here's two things that made them go away.
1. Name all columns in a Query and Alias any that are calculated (sum, count, avg, etc.) So your query would become
req = "Select count(*) NumRows From tblArticleList"
2. Wrapping my query string in a call to cstr caused the result.EOF flag to be populated correctly rather than be returned with an empty or null value causing a simple DO WHILE NOT result.EOF Some Action LOOP to create an infinite loop until the web request timed out. So e.g.
response.write "Step 2//"
set RS = conn.Execute(cstr(req))
Nothing major just a couple tips if you get stuck and can't find out why. Follow the debugging advice above though, that's good info.
I think Server has a GetLastError method, which you can check to find out what error occurred while running any statement.
e.g. On error resume next
.... statement that could cause an error....
errorObject = Server.GetLastError()
For ASPError object, refer http://www.w3schools.com/asp/asp_ref_error.asp
Actually don't mean to be disagreeable, but yes you do need a Set there, as you are setting an object type and presumably wanting to use the return value at some point (if this wasn't just a test script which it looks like to me).
Also btw parentheses are not really correct there in Response.Write() as it does not return a value. They only happen to work on single parameter subs because you can put parentheses anywhere you like around expressions.
eg:
a = (b)
Response.Write ((("test"))&(1))

Resources