Updateing NText causing long delay/timeouts - asp-classic

I'm trying to update an NText field in SQL 2000 using Classic ASP. Here is the code I'm using to do it. Any one have any pointers on how to maybe speed it up? Or am I stuck with it.
set Cnn = server.CreateObject("ADODB.connection")
Cnn.ConnectionString = Application("Cnn_ConnectionString")
Cnn.open
set rs = server.CreateObject("ADODB.Recordset")
rs.CursorType = adoOpenDynamic
rs.LockType = adLockOptimistic
conChunkSize = 100
rs.Open "MyTable",Cnn, , , adCmdTable
rs.Find "MyDataId=" & request("DataId"),,adSearchForward,1
lngOffset = 0
lngLogoSize = len(request("txtMyEntry"))*2
Do while lngOffset < lngLogoSize
varChunk = LeftB(RightB(request("txtMyEntry"), lngLogoSize - _
lngOffset), conChunkSize)
rs("MyDataField").AppendChunk varChunk
lngOffset = lngOffset + conChunkSize
Loop
rs.Update
rs.Close
Oh and this code is almost verbatim from the MSDN site.

First I would eliminate the chunking which is so 90's.
Then there is:-
rs.Open "MyTable",Cnn, , , adCmdTable
rs.Find "MyDataId=" & request("DataId"),,adSearchForward,1
Yikes! You'd like to think that ADO intelligently asked SQL server to find that record based on the indexed MyDataId field but bet it doesn't. Its most likely pulling the entire contents of the table across until the record is arrived at.
This really should be done with an UPDATE T-SQL statement and an ADODB.Command object.
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = cnn
cmd.CommandType = 1 '' // adCmdText
cmd.CommandText = "UPDATE MyTable SET MyDataField = ? WHERE MyDataId = ?"
cmd.Parameters.Append cmd.CreateParameter("dataField", 203, 1, Len(txtMyEntry), txtMyEntry) '' // 203 = asLongVarWChar, 1 = adParamInput
cmd.Parameters.Append cmd.CreateParameter("id", 3, 1, , CInt(DataID)) '' // 3 = adInteger
cmd.Execute

Related

How to prevent SQL injection in classic ASP [duplicate]

My db access code is like following:
set recordset = Server.CReateObject("ADODB.Recordset")
set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = Conn //connection object already created
cmd1.CommandText = "SELECT * FROM lbr_catmaster where catname = ?"
cmd1.CommandType = adCmdText
set prm = cmd1.CreateParameter("#prm", 200, 1,200 , "development")
cmd1.Parameters.Append prm
set recordset = cmd1.Execute
But there is no db hit going. Please help with this. I am using sql server 2005.
Thanks.
In my code, this is how I get a recordset from a command:
Set rs = server.createobject("ADODB.Recordset")
Set cmd = server.createobject("ADODB.Command")
cmd.ActiveConnection = Conn //connection object already created
cmd.CommandText = "SELECT * FROM lbr_catmaster where catname = ?"
cmd.CommandType = adCmdText
cmd.CommandTimeout = 900
set prm = cmd.CreateParameter("#prm", 200, 1, 200, "development")
cmd.Parameters.Append prm
' Execute the query for readonly
rs.CursorLocation = adUseClient
rs.Open cmd, , adOpenForwardOnly, adLockReadOnly
Hope it helps
I like using Parameters.Refresh, i.e.
set recordset = Server.CReateObject("ADODB.Recordset")
set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = Conn ' connection object already created
cmd1.CommandText = "SELECT * FROM lbr_catmaster where catname = ?"
cmd1.CommandType = adCmdText
cmd1.Prepared = True ' only needed if u plan to reuse this command often
cmd1.Parameters.Refresh
cmd1.Parameters(0).Value = "development"
set recordset = cmd1.Execute
Looks like you aren't referencing your named parameter correctly in your query.
Try replacing:
cmd1.CommandText = "SELECT * FROM lbr_catmaster where catname = ?"
with:
cmd1.CommandText = "SELECT * FROM lbr_catmaster where catname = #prm"
and see if that helps.
If you have a complex criteria using parameters here is an example I had to create based on my requirements
declare #loc smallint = ? , #dt1 date = ? SET #loc = ISNULL(#loc, 999)
SELECT m.* , c.*
FROM Costs c INNER JOIN MbrData m ON c.SN = m.SN and c.startDT = m.startDT
WHERE (m.LocationID = #loc OR #loc = 999) AND (MonthYear = #dt1 OR #dt1 IS NULL)
ORDER BY m.LocationID
then in your asp
cmd.CommandText = strSQL ' the string above
cmd.CommandType = 1 ' adCmdText
cmd.Parameters.Append cmd.CreateParameter("#loc",2,1) 'adSmallInt=2, adParamInput=1
cmd.Parameters("#loc") = rptlocation ' scrubbed location ID
cmd.Parameters.Append cmd.CreateParameter("#dt1",7,1) 'adDate=7, adParamInput=1
cmd.Parameters("#dt1") = scrubbed formatted date
set rst = cmd.Execute
Try leaving off the parameter name:
set prm = cmd1.CreateParameter(, 200, 1,200 , "development")

Response.Redirect error

I have form page that collects data. The user clicks SUBMIT, which goes to a "post page. At the end of this page is the redirect code I am using.
response.redirect( "test.asp?ChecklistID=" + ChecklistID )
For some reason, the result is this.
/test.asp?ChecklistID=4784,%204784
Why is this returning in TWO ID's? I only have ONE record in the 'results' table. And it is '4784'.
Adding the code
<%
'Option Explicit
Dim SQLStmt, sql, RS, ChecklistID, Location, ChecklistDate, Driveup,
ConnectString, conn, objconn
Dim weeds, parking_lot, sidewalk, windows, exterior_trash, door_clean
Dim mats_clean, Notes_page1
Location = Request("Location")
ChecklistDate = Request("ChecklistDate")
Driveup = Request("Driveup")
ChecklistID = Request("ChecklistID")
weeds = Request("weeds")
parking_lot = Request("parking_lot")
sidewalk = Request("sidewalk")
windows = Request("windows")
exterior_trash = Request("exterior_trash")
door_clean = Request("door_clean")
mats_clean = Request("mats_clean")
Notes_page1 = Request("Notes_page1")
ConnectString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
Server.MapPath("../xyz/mydatabase.mdb")
Set conn = Server.CreateObject("ADODB.Connection")
conn.open ConnectString
SQLStmt = "SELECT * FROM Results WHERE ChecklistID =" & ChecklistID & " ; "
Set RS = Server.CreateObject("ADODB.Recordset")
RS.open "Results", conn, 3, 3
RS.Update
RS("ChecklistDate") = ChecklistDate
RS("Driveup") = Driveup
RS("weeds") = weeds
RS("parking_lot") = parking_lot
RS("sidewalk") = sidewalk
RS("windows") = windows
RS("exterior_trash") = exterior_trash
RS("door_clean") = door_clean
RS("mats_clean") = mats_clean
RS("Notes_page1") = Notes_page1
RS.Update
RS.close
set RS = nothing
conn.close
set conn = nothing
response.redirect( "test.asp?ChecklistID=" + ChecklistID )
%>
The browser might be retaining some history with response.redirect. Try using Server.Transfer. Or, if it's the same page, you might not have to re-add the query string.
Solved
I had the same hidden field in there twice causing the issue.

translate asp script to php to access sql server with commands

I would like to renew an asp webapp that works with MS access databases into a new webapp using PHP and Mysql. The webapp relies on one masterquery that pulls data from an sql server used by HP Service Center and then puts the data in a table INCIDENT_DATA.
A former colleague created the asp script and I am by far a seasoned developer.
The script uses
cmd1.CommandText = "[IncidentMap].[uSp_proj_IM_IncidentList_SelectL]"
and I have no idea what it means exactly or where to put it in PHP.
the complete script:
<%
ReDim tmp_tab(1000)
Set cn1 = Server.CreateObject("ADODB.Connection")
Set cmd1 = Server.CreateObject("ADODB.Command")
Set rs1 = Server.CreateObject("ADODB.Recordset")
ds = "Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=PRG_PRD;Data Source=PRG_PRD.sql.somedomain\SQL1;"
cn1.Open ds
Set cmd1.ActiveConnection = cn1
cmd1.CommandText = "[IncidentMap].[uSp_proj_IM_IncidentList_SelectL]"
Set rs1 = cmd1.execute
If Not rs1.EOF Then
DataFound = true
Data = rs1.getrows
Else
DataFound = false
End If
If DataFound = true Then
nb_max_interv=Ubound(Data,2)
ReDim tableau_donnees(Ubound(Data,2))
ligne=0
col=0
For ctr = 1 To Ubound(Data,2)
For nb_col=0 to 27
if Data(nb_col,ctr)<>"" then
'tmp_tab(nb_col)=replace(Data(nb_col,ctr),"'"," ")
tempo=Data(nb_col,ctr)
tempo2=replace(tempo,"'"," ")
tempo3=replace(tempo2,chr(34)," ")
tempo4=replace(tempo3,chr(174)," ")
tempo5=replace(tempo4,chr(132)," ")
tempo6=replace(tempo5,chr(147)," ")
tempo7=replace(tempo6,chr(148)," ")
tempo8=replace(tempo7,chr(171)," ")
tempo9=replace(tempo8,chr(187)," ")
tempo10=replace(tempo9,chr(39)," ")
tempo11=replace(tempo10,chr(145)," ")
tempo12=replace(tempo11,chr(146)," ")
tmp_tab(nb_col)=tempo12
else
tmp_tab(nb_col)=Data(nb_col,ctr)
end if
Next
If tmp_tab(26)<>"" then
tps_restant=datediff("n",now(),tmp_tab(26))
else
tps_restant=0
end if
Tps_depuis_LastUpdate=datediff("n",tmp_tab(25),now())
SQL2="INSERT INTO data_incident (IncidentNumber,Owner,TicketStatus,AlertLevel,IncidentTitle,Description,LastName,FirstName,UserContactInformation,PhoneContactInformation,MobileContactInformation,EmailContactInformation,X1,CP,Location,Address,X2,ConfigurationItem,Hostname,AssignmentGroup,AssigneeName,Urgency,Impact,Priority,OpenedAt,LastUpdatedAt,Expiration,LastUpdatedBy,Temps_Restant,Temps_depuis_LastUpdate) VALUES('"&tmp_tab(0)&"','"&tmp_tab(1)&"','"&tmp_tab(2)&"','"&tmp_tab(3)&"','"&tmp_tab(4)&"','"&tmp_tab(5)&"','"&tmp_tab(6)&"','"&tmp_tab(7)&"','"&tmp_tab(8)&"','"&tmp_tab(9)&"','"&tmp_tab(10)&"','"&tmp_tab(11)&"','"&tmp_tab(12)&"','"&tmp_tab(13)&"','"&tmp_tab(14)&"','"&tmp_tab(15)&"','"&tmp_tab(16)&"','"&tmp_tab(17)&"','"&tmp_tab(18)&"','"&tmp_tab(19)&"','"&tmp_tab(20)&"','"&tmp_tab(21)&"','"&tmp_tab(22)&"','"&tmp_tab(23)&"','"&tmp_tab(24)&"','"&tmp_tab(25)&"','"&tmp_tab(26)&"','"&tmp_tab(27)&"','"&tps_restant&"','"&Tps_depuis_LastUpdate&"')"
Set cat2 = Server.CreateObject("ADODB.Recordset")
cat2.Open sql2, conn, 3, 3
Next
End If
'conn.close
%>
Does anyone have an idea how I could construct a PDO connectionstring and then update a mysql database with the pulled data?

Parameterised query asp classic missing operand error

I am trying to get a paramterised query to work in asp classic. Any help appreciated
Here is the error
Microsoft OLE DB Provider for Visual FoxPro error '80040e14'
Missing operand.
/portal/jobportal/getaddress1.asp, line 141
function paramQuery()
code = ucase(request.querystring("code"))
stype = request.querystring("type")
cAddressType = request.querystring("caddresstype")
Set rs = Server.CreateObject("ADODB.recordset")
Set cmd = server.CreateObject("ADODB.Command")
If IsObject(Session("portal_conn")) Then
Set conn = Session("portal_conn")
Else
Set conn = Server.CreateObject("ADODB.Connection")
cConnString = "Provider=vfpoledb;Data Source="+session("portaldata")+"portal.dbc"
conn.open cConnString,"",""
Set Session("portal_conn") = conn
end if
cmd.ActiveConnection = conn
cmd.Prepared = true
cmd.CommandType = 1
cmd.CommandText = "SELECT * from uaddress where userid = "+cstr(session("userid"))+" and upper(name) like ? + % "+" and type = '"+ trim(cAddresstype)+"' order by add1"
set param1 = cmd.CreateParameter("#name",200,2,40)
cmd.Parameters.append param1
cmd.Parameters("#name") = code
cmd.Execute() <-- missing operand error
rs.Open cmd
end function
When using parameter for SQL like clause you need to pass the % as part of the parameter value.
Also to protect against SQL Injection attacks you really better use parameters for the other values as well:
cmd.CommandText = "SELECT * FROM uaddress WHERE userid=? AND UPPER(name) LIKE ? AND type=? ORDER BY add1"
set param1 = cmd.CreateParameter("#id", 200, 2, 40)
cmd.Parameters.append param1
cmd.Parameters("#id") = cstr(session("userid"))
set param2 = cmd.CreateParameter("#name", 200, 2, 40)
cmd.Parameters.append param2
cmd.Parameters("#name") = "%" & code & "%"
set param3 = cmd.CreateParameter("#type", 200, 2, 40)
cmd.Parameters.append param3
cmd.Parameters("#type") = trim(cAddresstype)
cmd.Execute()
You need quotes around the % character:
... +" and upper(name) like ? + '%' "+ ...
It seems like VFP does not support named parameters , just add your params in the order that apears in the query by using (?) instead of the named param and it will work.
instead of :
cmd.Parameters("#name") = code
Use :
cmd.Parameters("?") = code

Microsoft VBScript runtime error '800a0009'

I recently inherited a website in ASP, which I am not familiar with. Yesterday, one of the pages began to throw an error:
Microsoft VBScript runtime error '800a0009'
Subscript out of range: 'i'
default.asp, line 19
Here is the code from lines 13-27:
<%
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "SELECT * FROM VENDORS_LIST_TBL WHERE inStr('"& dVendorStr &"','|'&ID&'|')", Cn
DIM dTitle(100), dDescription(100), dLink(100)
i = 0 : Do while NOT rs.EOF : i = i + 1
dTitle(i) = rs.fields.item("dTitle").value
dDescription(i) = rs.fields.item("dDescription").value
dLink(i) = rs.fields.item("dLink").value : if dLink(i) <> "" then dTitle(i) = "" & dTitle(i) & ""
if NOT rs.EOF then rs.movenext
Loop
x = i
rs.Close : Set rs = Nothing
%>
Any ideas on what's going on here and how I can fix it?
Thank you!
You've declared dTitle, dDescription and dLink as Arrays with a size of 100. As you are walking through the recordset, you are assigning elements to those arrays. It would appear that you have more than 100 records in your recordset, so the logic is trying to do something like:
dTitle(101) = rs.fields.item("dTitle").value
This will throw an error because your array isn't big enough to hold all of your data.
The "solution" you chose is not very good. What if within 2 years there will be more than 500? You will forget all about this and waste hours yet again.
Instead of fixed size arrays you can just use dynamic arrays:
DIM dTitle(), dDescription(), dLink()
ReDim dTitle(0)
ReDim dDescription(0)
ReDim dLink(0)
i = 0
Do while NOT rs.EOF
i = i + 1
ReDim Preserve dTitle(i)
ReDim Preserve dDescription(i)
ReDim Preserve dLink(i)
dTitle(i) = rs.fields.item("dTitle").value
dDescription(i) = rs.fields.item("dDescription").value
dLink(i) = rs.fields.item("dLink").value
If (Not(IsNull(dLink(i)))) And (dLink(i) <> "") Then
dTitle(i) = "" & dTitle(i) & ""
End If
rs.movenext
Loop
This will start with one (empty) item in each array - for some reason the code seems to need this - then on each iteration one more item will be added, preserving the others.
Note that I've also fixed small issue that might have caused trouble - in case of NULL value in "dLink" field, you would get blank anchors in your HTML because NULL is not empty string in VBScript.
This how GetRows can be used to achieve the same goal.
<%
Function VendorSearch(sVendor)
Dim cn: Set cn = SomeLibraryFunctionThatOpensAConnection()
Dim cmd: Set cmd = Server.CreateObject("ADODB.Command")
cmd.CommandType = adCmdText
cmd.CommandText = "SELECT dTitle, dDescription, dLink FROM VENDORS_LIST_TBL WHERE inStr(?,'|'&ID&'|')"
cmd.Parameters.Append cmd.CreateParameter("Vendor", adVarChar, adParamInput, Len(sVendor), sVendor)
Set cmd.ActiveConnection = cn
Dim rs : Set rs = cmd.Execute()
VendorSearch = rs.GetRows()
rs.Close()
cn.Close()
End Function
Dim arrVendor : arrVendor = VendorSearch(dVendorStr)
Const cTitle = 0, cDesc = 1, cLink = 2
Dim i
For i = 0 To UBound(arrVendor, 2)
If IsNull(arrVendor(cLink, i) Or arrVendor(cLink, i) = "" Then
arrVendor(cTitle, i) = "" & arr(cTitle, i) & ""
End If
Next
%>
Notes:
The Select statement contains only those fields required in the results, the use of * should be avoided
A parameterised command is used to avoid SQL Injection threat from SQL contactenation.
Constants used for field indices into the resulting 2 dimensional array.
Whilst this code replicates the original munging of the title value this is here as an example only. In reality construction of HTML should be left as late as possible and outputing of all such strings as title and description should be passed through Server.HTMLEncode before sending to the response.

Resources