MySQL / Classic ASP - Parameterized Queries - mysql

In an absolute emergency, I am trying to go through my website and add parameterized queries. I'm a newbie and have only just learnt about them.
My problem is, I only know a very little about connection types and all of the examples I'm seeing are using another methods of connection, which is confusing me. I don't particularly want to change the way I connect to my DB, as it's on lots of pages, I just want to update my queries to be safer.
This is how I have been connecting to my DB:
Set connContent = Server.CreateObject("ADODB.Connection")
connContent.ConnectionString = "...blah...blah...blah..."
connContent.Open
and this is the SQL bit with parameters:
username = Trim(Request("username"))
connContent.Prepared = True
Const ad_nVarChar = 202
Const ad_ParamInput = 1
SQL = " SELECT * FROM users WHERE (username=?) ; "
Set newParameter = connContent.CreateParameter("#username", ad_nVarChar, adParamInput, 20, username)
connContent.Parameters.Append newParameter
Set rs = connContent.Execute(SQL)
If NOT rs.EOF Then
' Do something...
End If
rs.Close
It's obviously not working but I need to know if I can actually achieve this using the connection I have or am I missing something altogether that's stopping it from working?
Before I go forth and spend the next 2 days debugging something I'm unfamiliar with, I would like to know I'm at least on the right track...

The code in your second snippet is correct, but should be applied to a new ADODB.Command object, not to the Connection object:
username = Trim(Request("username"))
'-----Added this-----
Dim cmdContent
Set cmdContent = Server.CreateObject("ADODB.Command")
' Use this line to associate the Command with your previously opened connection
Set cmdContent.ActiveConnection = connContent
'--------------------
cmdContent.Prepared = True
Const ad_nVarChar = 202
Const ad_ParamInput = 1
SQL = " SELECT * FROM users WHERE (username=?) ; "
Set newParameter = cmdContent.CreateParameter("#username", ad_nVarChar, ad_ParamInput, 20, username)
cmdContent.Parameters.Append newParameter
cmdContent.CommandText = SQL
Set rs = cmdContent.Execute
If NOT rs.EOF Then
' Do something...
End If
rs.Close
By the way, there was a typo with the spelling of adParamInput instead of ad_ParamInput (corrected in my example).

Related

VBscript call stored procedure from MySQL with output parameters [duplicate]

This question already has answers here:
Using Stored Procedure in Classical ASP .. execute and get results
(3 answers)
Closed last year.
[ EDIT 20220219 ]
Resolved using VBSCRIPT CODE below
SQL = " CALL NewCheckData(#pOld); "
cn.execute(SQL)
SQL = " SELECT #pOld; "
Set RS = cn.execute(SQL)
pOld = cInt(RS("#pOld"))
[ EDIT 20220219 ]
[EDIT]
I have a Stored Procedure on a MySQL DB.
Which simply takes the COUNT ROWS of a Parameter and returns the Value of that Parameter.
I would like to call this Stored Procedure to assign value to variable in my VBscript code.
This is MySql routine (stored procedure) tried and worked.
CREATE DEFINER=`user`#`%` PROCEDURE `NewCheckData`(OUT pOld INT (11))
BEGIN
SELECT
COUNT(*) tOld INTO pOld
FROM
`DoTable`
WHERE
DATE( myDATE ) = CURRENT_DATE;
END
VBSCRIPT CODE is as below
On Error Resume Next
Const adCmdStoredProc = 4
Const adInteger = 3
Const adVarWChar = 202
Const adParamInput = &H0001
Const adParamOutput = &H0002
Const adParamReturnValue = &H0004
Set cn = CreateObject("ADODB.Connection")
cn.Open "DRIVER={MySQL ODBC 5.1 Driver};SERVER=XXX;PORT=3306;DATABASE=XXX;USER=XXX;PASSWORD=XXX;OPTION=3;"
cn.CommandTimeout = 10000
Set cmd = CreateObject("ADODB.Command")
With cmd
Set .ActiveConnection = cn
.CommandText = "NewCheckData"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("RETURN_VALUE", adInteger, adParamReturnValue )
.Parameters.Append .CreateParameter("#pOld", adInteger, adParamOutput, 11)
.Execute
parmval = .Parameters(0).Value
End With
cn.Close()
Set cn = Nothing
If Err.Number <> 0 Then
WScript.Echo "Error in : " & Err.Description
Err.Clear
End If
On Error GoTo 0
Error or messagebox
Error or messagebox
Any suggestion, please.
[OLD QUESTION]
I am working with VBSCRIPT and using stored procedure MySQL.
I have to get the value of stored procedure out parameter.
This is MySql routine (stored procedure) tried and worked
CREATE DEFINER=`user`#`%` PROCEDURE `CheckData`(OUT pOld INT (11))
BEGIN
SELECT
COUNT(*) tOld INTO pOld
FROM
`DoTable`
WHERE
DATE( myDATE ) = CURRENT_DATE;
END
VBSCRIPT CODE is as below
Set cn = CreateObject("ADODB.Connection")
cn.Open "DRIVER={MySQL ODBC 5.1 Driver};SERVER=XXX;PORT=3306;DATABASE=XXX;USER=XXX;PASSWORD=XXX;OPTION=3;"
cn.CommandTimeout = 1000
Set objCommandSec = CreateObject("ADODB.Command")
objCommandSec.ActiveConnection = cn
objCommandSec.CommandType = 4
objCommandSec.CommandText = "CheckData"
objCommandSec.Parameters.Refresh
objCommandSec.Parameters.append objCommandSec.createParameter("#pOld", adInteger, adParamReturnValue) <<< error line
objCommandSec.execute , , adExecuteNoRecords
pOld = objCommandSec.Parameters("#pOld").value
MsgBox(pOld)
cn.Close()
Set cn = Nothing
Error or messagebox line 15
Error 'Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another'
Any suggestion, please.
Edit: I failed to consider and mention that the below code example is accessing a MS-SQL DB. The behavior could therfor be different.
I don't use .VBS much anymore, but as I believe you are using the "Windows Script Host" environment I don't think it will make much difference. In the past I have done essentially the same thing as you demonstrate above many times with WSH & .JS. I also always ran into problems when I explicitly added the parameter definitions. I have since learned that for me the .refresh() is completely sufficient. I therefore leave .createParameter out now and simply give the named parameters the needed values as such:
var jsADO = {};
jsADO.objConn = new ActiveXObject("ADODB.Connection");
jsADO.objConn.Open("Provider=SQLOLEDB.1;...");
jsADO.cmd_insertShare = new ActiveXObject("ADODB.Command");
var cmd = jsADO.cmd_insertShare;
cmd.ActiveConnection = jsADO.objConn;
cmd.CommandType = adCmdStoredProc; // 4
cmd.CommandText = "usp_insertShare";
cmd.Prepared = true;
cmd.NamedParameters = true;
cmd.Parameters.Refresh()
...
var sqlRec;
var cmd = jsADO.cmd_insertShare;
cmd.Parameters("#p_Server") = "myServer";
cmd.Parameters("#p_Name") = "myShare";
cmd.Parameters("#p_Description") = "myShare Desc";
cmd.Parameters("#p_LocalPath") = "sharePath";
sqlRec = cmd.Execute(null, null, 0);
The syntax is indeed different, but I hope the gist is clear.
In summary, I think you've got it, just try leaving the .createParameter function out and only setting the named parameter values.

Why isn't the ADO Extended Properties "HDR=No" flag being obeyed here?

I have a CSV file with no header output by a process I do not control:
FOO,<auto>,12345678,8005882300, ,2
FOO,<auto>,23456789,2128675309, ,2
FOO,<auto>,34567890,3125577203, ,2
FOO,<auto>,45678901,9198423089, ,2
I'm trying to access it using Classic ASP with ADO then print out the phone number using this code:
stmt = "SELECT * FROM baz.txt"
connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=I:;Extended Properties='Text;HDR=No;FMT=Delimited'"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open connectstring
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open stmt, conn, adLockOptimistic, , adCmdText
If Not rs.eof Then
Data=rs.GetRows()
End If
for r = 0 to UBound(Data,2)
response.write(Data(3,r) & "<br>")
next
Even though I have the HDR flag set to No the result set never includes the first row:
2128675309
3125577203
9198423089
What am I doing wrong that it appears the first row is still being skipped?
I wanted to post the answer to my own question in case someone else runs into a similar situation in the future.
For the purposes of the post I had oversimplified my code, and in so doing I had removed the thing that was making it break. The code was actually contained within a loop to iterate through several files in several subfolders:
path = "I:"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set dirFolders = objFSO.GetFolder(path).SubFolders
For Each subFolder in dirFolders
Set dirFiles = objFSO.GetFolder(subFolder).Files
For Each bar in dirFiles
stmt = "SELECT * FROM " & bar
connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& path &";Extended Properties='Text;HDR=No;FMT=Delimited'"
[...]
In practice, this is what was actually getting passed to ADO:
stmt = "SELECT * FROM I:\20140509\baz.txt"
connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=I:;Extended Properties='text;HDR=No;FMT=CSVDelimited'"
Having the full path included in stmt and an incomplete path in connectstring caused the HDR flag to be ignored. It would have been nice if ADO had broken a little less subtly when I fed that to it, but it is what it is.
Corrected code:
For Each path in dirFolders
Set dirFiles = objFSO.GetFolder(path).Files
For Each bar in dirFiles
stmt = "SELECT * FROM " & objFSO.GetFileName(bar)
connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& path &";Extended Properties='Text;HDR=No;FMT=Delimited'"
Ultimately, it's a reminder that chucking a couple of response.write statements at puzzling code is a Good Idea, and when it doesn't work like you expect, to strip it down to brass tacks to make sure you're looking in the right place.

ASP Classic Database Connection

I want to use classic ASP to open and close a connection to a SQL Server database and let it run a procedure from the database. It has no parameters.
This is the connection details in ASP, change caps to the relevant information objDBRS(0) will be your first part of data from a select statement
Set objDBConn = Server.CreateObject("ADODB.Connection")
objDBConn.Open "Provider=sqloledb;Data Source=SQLSERVERNAME;Initial Catalog=DATABASENAME; User ID=Chris;Password=PASSWORD;"
Set objDBCommand = Server.CreateObject("ADODB.Command")
objDBCommand.ActiveConnection = objDBConn
objDBCommand.CommandText = "SQLPROCEDURENAME"
objDBCommand.CommandType = adCmdStoredProc
Set objDBRS = Server.CreateObject("ADODB.RecordSet")
objDBRS.open objDBCommand,,adOpenForwardOnly
DO WHAT YOU WANT HERE
Set objDBCommand=nothing
objDBConn.Close
Set objDBConn=nothing
Here is a tried and tested approach I use over and over again.
<%
Dim cmd, conn_string, rs, data, row, rows
'Connection String if using latest version of SQL use SQL Server Native Client
'for more examples see http://www.connectionstrings.com/sql-server/
conn_string = "Provider=SQLNCLI11;Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;"
Set cmd = Server.CreateObject("ADODB.Command")
With cmd
'No need to build ADODB.Connection the command object does it for you.
.ActiveConnection = conn_string
.CommandType = adCmdStoredProc
.CommandText = "[schema].[procedurename]"
Set rs = .Execute()
'Populate Array with rs and close and release ADODB.Recordset from memory.
If Not rs.EOF Then data = rs.GetRows()
Call rs.Close()
Set rs = Nothing
End With
'Release memory closes and releases ADODB.Connection as well.
Set cmd = Nothing
'Use Array to enumerate data without overhead of ADODB.Recordset.
If IsArray(data) Then
rows = UBound(data, 2)
For row = 0 To rows
'Read data
Call Response.Write("First Field: " & data(0, row))
Next
Else
'No records
Call Response.Write("No records to display")
End If
%>

How to pass variables to ASP query

I am an ASP beginner trying to make a very simple page. The functionality is to accept two inputs from the user and display a report based on those on the next page. The data for the report is fetched a SQL query on the ASP page.
This is what I have done till now:
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=MSDAORA;
Data Source=şemam;
User Id=xyz;
Password=xyz;"
aranan = Request("aranan")
Set objRs = objConn.Execute("select * from my_department where user_id = <input from user>")
if objRs.BOF and objRs.eof then
response.end
end if
The problem I am facing is that I cannot find how to properly pass the user input in the query.
Please help!
Use ? as a placeholder, then pass the parameters into the Execute method.
dim paramArray(0)
paramArray(0) = 123
Set objRs = objConn.Execute("select * from my_department where user_id = ?", paramArray)
To send parameters to a database query you need to use a command-object.
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=MSDAORA;" & _
"Data Source=şemam;" & _
"User Id=xyz;" & _
"Password=xyz;"
aranan = Request("aranan")
Set objCmd = Server.CreateObject("ADODB.Command")
Set objCmd.ActiveConnection = objConn
objCmd.CommandText = "SELECT * FROM my_department WHERE user_id = ?"
objCmd.CommandType = 1
Set objRs = objCmd.Execute(, array(aranan))
if not objRs.EOF then
' Do whatever you need to with the result...
end if
objRs.Close
objConn.Close
Don't end the response before you closed the connection otherwise you will end up exhausting your connectionpool.

ASP/MySQL - Parameterized Query(s)

In my example code below, you can see that I have been trying to suss-out parameterized queries in ASP and MySQL.
I am doing something wrong here and would like to know what it is. In my example, you can see two queries. If I leave off the last query (under the '//////// line), this script works. As soon as I add the last query, I get the following error:
"Multiple-step OLE DB operation generated errors. Check each OLE DB
status value, if available. No work was done."
I'm really not sure what I am doing wrong. I googled the error and it said something about data types but it didn't register in my empty head!
Am I declaring the parameters (.createParameter) in the right place, as I'm processing multiple queries? Do they have to be declared before all the queries?
My Code
Set connContent = Server.CreateObject("ADODB.Connection")
connContent.ConnectionString="...blah..blah..blah..."
connContent.Open
Set cmdContent = Server.CreateObject("ADODB.Command")
Set cmdContent.ActiveConnection = connContent
cmdContent.Prepared = True
Const ad_varChar = 200
Const ad_ParamInput = 1
Const ad_Integer = 3
Const ad_DBDate = 133
Const ad_DBTimeStamp = 135
theNumber = 23
theText = "Hello there!"
theDate = "2011-10-15"
SQL = " INSERT INTO testTable (integerCol) VALUES (?); "
Set newParameter = cmdContent.CreateParameter("#theNumber", ad_Integer, ad_ParamInput, 50, theNumber)
cmdContent.Parameters.Append newParameter
cmdContent.CommandText = SQL
cmdContent.Execute
' ////////////
SQL = " INSERT INTO testTable (varCharCol) VALUES (?); "
Set newParameter = cmdContent.CreateParameter("#theText", ad_varChar, ad_ParamInput, 50, theText)
cmdContent.Parameters.Append newParameter
cmdContent.CommandText = SQL
cmdContent.Execute
UPDATE:
Well I got both queries to work but I had to set another command object and active connection, shown below. Although it works, is this the right thing to do with my type of connection? Do I need to set the command object to nothing after each query then?
' ////////////
Set cmdContent = Server.CreateObject("ADODB.Command")
Set cmdContent.ActiveConnection = connContent
SQL = " INSERT INTO testTable (varCharCol) VALUES (?); "
Set newParameter = cmdContent.CreateParameter("#theText", ad_varChar, ad_ParamInput, 50, theText)
cmdContent.Parameters.Append newParameter
cmdContent.CommandText = SQL
cmdContent.Execute
I believe your problem is because both insert statements are using the same command object. Because of that, the second command will have both parameters in it and that is what I believe causes the exception you are seeing.
To fix the problem, add:
Set cmdContent = Server.CreateObject("ADODB.Command")
Set cmdContent.ActiveConnection = connContent
after your //// comment and things should start working.