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
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.
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.
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
%>
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.
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.