Is it possible to submit data into a SQL database, wait for that to finish, and then return the ID generated from SQL, using Classic ASP? - sql

I have an ASP form that needs to submit data to two different systems. First the data needs to go into an MS SQL database, which will get an ID. I then need to submit all that form data to an external system, along with that ID.
Pretty much everything in the code works just fine, the data goes into the database, and the data will go to the external system. The problem is I am not getting my ID back from SQL when I execute that query. I am under the impression this is happening because of how fast everything occurs in the code. The database is adding it's row at the same time my post page runs it's query to get the ID back, I think.
I need to know of a way to wait until SQL finished the insert or wait for a specific amount of time maybe. I already tried using the hacks to "sleep" with ASP, that did not help.
I am sure I could accomplish this in .Net, my background is more .Net than ASP, but this is what I have to work with on my current project.
Any ideas?
EDIT: Code from the the function writing to the DB.
driis - That was my understanding of how this should be working, but my follow up query for the ID returns nothing, so my though is that the row hasn't finished being inserted or updated yet. Maybe I am wrong on that, if so, that complicates this more. :(
Either way here is the code from the function to update the DB. Mind you this code is inherited, the rest of my project is being written by me, but I am stuck using these functions from a previous developer.
Sub DBWriteResult
Dim connLeads
Dim sSQL
Dim rsUser
Dim sErrorMsg
Dim sLeads_Connection
' Connect to the Leads database
' -------------------------------------------------------------------
sLeads_Connection = strDatabaseConnection
Set connLeads = CreateObject("ADODB.Connection")
connLeads.Provider = "SQLOLEDB.1"
On Error Resume Next
connLeads.Open sLeads_Connection
If Err.number <> 0 Then
' Bad connection display error
' -----------------------------------------------------------------
Response.Write "Database Write Error: 001 Contact Programmer"
Set connLeads = Nothing
Exit Sub
Else
' Verify the transaction does not already exist.
' -----------------------------------------------------------------------
Set rsUser = Server.CreateObject("ADODB.Recordset")
rsUser.LockType = 3
rsUser.CursorLocation = 3
sSQL = "SELECT * "
sSQL = sSQL & " FROM Leads;"
rsUser.Open sSQL, connLeads, adOpenDynamic
Response.Write Err.Description
If Err.number = 0 Then
' Add the record
' -----------------------------------------------------------
rsUser.AddNew
rsUser.Fields("LeadDate") = Date()&" "&Time()
rsUser.Fields("StageNum") = ESM_StageNum
rsUser.Fields("MarketingVendor") = ESMSourceData
rsUser.Fields("FirstName") = ESM_FirstName
rsUser.Fields("Prev_LName") = Request.Form ("Prev_LName")
rsUser.Fields("LastName") = ESM_LastName
rsUser.Fields("ProgramType") = ESM_ProgramType
rsUser.Fields("ProgramofInterest") = ESM_ProgramofInterest
rsUser.Fields("Phone1") = Phonenumber
rsUser.Fields("Phone2") = ESM_Phonenumber2
rsUser.Fields("Address1") = ESM_Address
rsUser.Fields("Address2") = ESM_Address2
rsUser.Fields("City") = ESM_City
rsUser.Fields("State") = ESM_State
rsUser.Fields("Region") = ESM_Region
rsUser.Fields("Zip") = ESM_Zip
rsUser.Fields("Country") = ESM_Country
rsUser.Fields("Email") = ESM_Email
rsUser.Fields("MilitaryBranch") = ESM_MilitaryBranch
rsUser.Fields("MilitaryStatus") = ESM_MilitaryStatus
rsUser.Fields("BestTimeToCall") = ESM_BestTimeToCall
rsUser.Fields("DateofBirth") = ESM_DateofBirth
rsUser.Update
Else
' There was an error
Response.Write "There was an error. Error code is: "&Err.number&" "&Err.Desc
End if
End If
' Close the recordset
' ---------------------------------------------------------------
Call rsUser.Close
Set rsUser.ActiveConnection = Nothing
Set rsUser = Nothing
' Destroy the connection to the database
' -------------------------------------------------------------------
Set connLeads = Nothing
End Sub

It sounds like you're trying to do this:
Insert some data in DB 1
Retrieve an ID from the inserted data
Send data + the ID to DB 2
It's been a good five years but I believe it looked something like this:
dim connStr1
connStr1 = "[connection string 1]"
dim conn1
set conn1 = server.createobject("adodb.connection")
conn1.open connStr1
dim sql
sql = " SET NOCOUNT ON " & vbCrLf & _
" INSERT FOO (a, b, c) VALUES (1, 2, 3) " & vbCrLf & _
" SET NOCOUNT OFF " & vbCrLf & _
" SELECT SCOPE_IDENTITY() "
dim rs
set rs = conn1.execute(sql)
rs.close
dim id
set id = CInt(rs(0))
conn1.close
dim connStr2
connStr2 = "[connection string 2]"
dim conn2
set conn2 = server.createobject("adodb.connection")
conn2.open connStr2
conn2.execute("INSERT FOO (id, a, b, c) VALUES (" & id & ", 1, 2, 3)")
conn2.close
Good luck, and get off my lawn!

Ok, so I figured this one out. The problem was insane, a typo. I am spoiled with .Net and the fact that if I use a variable that doesn't really exist, I get errors. I guess ASP doesn't care so much.
On the up side, driis was correct. The code does not continue until the database transaction is completed. That was my major concern, that had incorrectly assumed that was the case. I am glad I was right.
Thanks for the help, and hopefully the next time I post it'll be something better than a tyop.
;)

Related

"IF" code is not working inside for each?

so im learning to use socket and thread things in the networking software. so far, the software (which is not created by me) is able to chat in multiple group, but i'm tasked to allow user to code whisper feature. However, im stuck in the coding area, which im sure will work if the "if" function work inside "for each" function, anyhow here is my code mainly
Private clientCollection As New Hashtable()
Private usernameCollection As New Hashtable()
clientCollection.Add(clientID, CData)
usernameCollection.Add(clientID, username)
oh and before i forgot, the code above and below is on the server form page
on the client side, i write the code:
writer.write("PMG" & vbnewline & txtReceiverUsername & Message)
then next is the checking part on the server reading the message:
ElseIf message.Substring(0, 3) = "PMG" Then
'filter the message, check who to send to
Dim newMessage As String = message.Substring(3)
Dim messagearray As String() = newMessage.Split(vbNewLine)
Dim receiver As String = messagearray(1)
'0 = "", 1 = receiver, 2 = message
as i write before, clientcollection contain (clientID , connection data*) and usernamecollection contain (clientID, username). In my case, i only have the username data, and i need to trace it until the connection data on clientcollection hash table.
'find realid from usernamecollection, then loop clientcollection
Dim clientKey As String = 0
For Each de As DictionaryEntry In usernameCollection
'''''
'this if part Is Not working
If de.Value Is receiver Then
clientKey = de.Key
End If
'''''
Next de
'match objKey with clientcollection key
For Each dec As DictionaryEntry In clientCollection
If dec.Key = clientKey Then
Dim clients As ClientData = dec.Value
If clients.structSocket.Connected Then
clients.structWriter.Write("PMG" & messagearray(2))
End If
End If
Next dec
End If
so, how do i know that the if part is the wrong one? simply i tried these code before the "next de" code
For Each client As ClientData In clientCollection.Values
If client.structSocket.Connected Then
client.structWriter.Write("PMG" & "receiver:" & messagearray(1))
client.structWriter.Write("PMG" & "loop username: " & de.Value)
client.structWriter.Write("PMG" & "loop key: " & de.Key)
client.structWriter.Write("PMG" & "receiver key:" & clientKey)
End If
Next
the code allow me to check the de.key and de.value. they were correct, however the only thing that did not work is the code inside the "if" area.
Can anyone suggest other code maybe beside "if de.key = receiver"? I've also tried using the if de.key.equal(receiver) and it did not work too

ASP classic, reading and then writing to database

I have a page where a database lookup is done, and if a value is found some response is sent back to the user and then the database value is deleted.
I'm calling my delete sub after I've checked the variable but it's like this never happened, although i know the sub ran since the value is now gone from the database.
It seems like the page is loading twice and on the second pass the database value has gone and so it shows as if the database value was never found, but it had to have been found in order to have deleted it (as this was a condition for running the delete sub).
I realize this sounds insane but I've been on this for 2 days and have no idea what's going on. I've tried disabling caching from within IIS and also changing my code so that a value is posted to the database instead of deleting a record and I still get the same thing where my server seems to check the future value of the database before calling the routine that changes it.
Has anyone seen similar behavior to this when reading and writing to the same record on a single page?
Code:
referer = Request.ServerVariables ("HTTP_REFERER")
session("testcode") = right(referer,16)
testcode = session("testcode")
set objcommand = server.createObject("adodb.command")
objcommand.activeconnection = strconnect2
objcommand.commandtext="SELECT codeval,stamp,used from code where codeval like '" & testcode & "'"
objcommand.commandtype = 1
set objrs = objcommand.Execute
set objcommand = nothing
countvar = 0
While not objrs.EOF
if not objrs("used") = true then
foundcode = true
countvar = countvar+1
end if
objrs.MoveNext
wend
if foundcode = true then
response.write "Found you!"
set objcomm5 = server.createobject("adodb.command")
objcomm5.activeconnection = strconnect2
objcomm5.commandtext = "update code set used = true where codeval like '"& testcode &"' "
objcomm5.commandtype = &H0001
objcomm5.execute
else
response.write "Can't be found!"
end if

Excel drop down values from a SQL Server source

I am trying to get a cell drop-down values in Excel from a SQL Server. I don't want to use the method of putting all the data to another sheet and the use data validation to control the drop down values. That always give my a bunch of empty lines towards the end since I want to make sure I have room for any addition in the DB.
Is there a way to retrieve the drop-down values directly from SQL Server? Using a statement something like:
Select name from employees
Thanks for your help...
Use ADODB to retrieve the values you want, and use the retrieved values to populate a dropdown shape in Excel which you can create dynamically.
In a similar situation, since the source data was basically static, I populated a global array from an ADODB recordset when the application started and used that array when populating the items in the dropdown. Here's a snippet of that code:
Dim InstrumentIDs() As String
Dim InstrumentIDReader As Integer
Dim InstrumentIDCount As Integer
Public PositionRange As String
Public Sub GetInstrumentIDs()
'
'Populate InstrumentIDs array from current contents of Instrument table in EMS database
'
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim sql As String
Dim loader As Integer, sn As String
InstrumentIDReader = 0
On Error GoTo GetInstrumentError
conn.ConnectionString = "Provider=sqloledb; Data Source=myServer; Initial Catalog=myDatabase; User ID=myUser;Password=myPassword"
conn.Open
sql = "Select Count([SerialNo]) As [Number] From [Instrument]"
rs.Open sql, conn, adOpenStatic
InstrumentIDCount = CInt(rs![Number])
ReDim InstrumentIDs(InstrumentIDCount - 1)
rs.Close
sql = "Select [SerialNo] From [Instrument] Order By [SerialNo]"
rs.Open sql, conn, adOpenForwardOnly
loader = 0
rs.MoveFirst
Do While Not rs.EOF
sn = CStr(rs![SerialNo])
InstrumentIDs(loader) = sn
loader = loader + 1
rs.MoveNext
Loop
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
Exit Sub
GetInstrumentError:
MsgBox "Error loading instruments: " & Err.Description
End Sub
You must set a reference to Microsoft ActiveX Data Objects m.n Library (latest version on my computer is 2.8) from Tools > References in VBA editor.
See article
http://www.thespreadsheetguru.com/blog/2014/5/14/vba-for-excels-form-control-combo-boxes for tips on how to manage dropdown boxes in Excel.
You can use the MS Query Wizard in Excel to store a query and use it's data any time.
This this link for details http://www.techrepublic.com/article/use-excels-ms-query-wizard-to-query-access-databases/

Runtime Error 3061 Help (ms access)

I've been wracking my brain trying to find what is wrong with this query and I just don't see it. I'm trying to open a record set and I keep getting runtime error 3061: "Too few parameters: Expected 1."
Here's my code...
Dim ansRs As Recordset
Dim qRs As Recordset
Dim ansQuery As String
Dim qQuery As String
Dim i As Integer
qQuery = "Select * From TrainingQuizQuestions Where TrainingQuizID = (Select TrainingQuiz.TrainingQuizID From TrainingQuiz Where QuizName = Forms!MainMenu!txtVidName);"
ansQuery = "Select * From TrainingQuizQuestAns"
Set qRs = CurrentDb().OpenRecordset(qQuery)
Set ansRs = CurrentDb().OpenRecordset(ansQuery)
I'm getting the error from the line "Set qRs = CurrentDb().OpenRecordset(qQuery)". I copied and pasted that query into access and ran it and it returned exactly what I want to get in my record set, yet when I run it in VBA I get the error. Am I missing something really simple? Any help would be greatly appreciated.
First ensured that your form is open, then put the form reference outside your quotes.
qQuery = "Select * From TrainingQuizQuestions Where TrainingQuizID = " _
& "(Select TrainingQuiz.TrainingQuizID From TrainingQuiz Where QuizName = '" _
& Forms!MainMenu!txtVidName) & "';"
The form value is not available to a recordset used in VBA.

Help with protection agains SQL-injection

I need some help regarding SQL-injection. Ive been reading about it, but still don’t understand how to protect myself against it.
I have a simple Access database with a table (“course”) containing names and dates among other things. I then have a old ASP page with a search form. Below the search form I have a div (“schema”) that I want to populate with the search result through AJAX. Everything works fine, but is there something I need to do to protect me from an SQL-injection? Here is a simplified version of my code:
ASP Searchpage with AJAX and form (index.asp)
$("#search").keyup(function() {
var varSearch;
varSearch = $("#search").attr("value").replace(/\s/g,"+");
$("#schema").load('ajax.asp?q=' + varSearch + '');
});
<input type="text" name="search" id="search" value="Search.." />
<div id=”schema”></div>
ASP resultpage (ajax.asp):
q = request.querystring("q")
SQL = "SELECT * FROM course WHERE startDate >= #" & Now & "# AND (courseName like '%" & q & "%');"
While Not dbRS.EOF
str courseName = dbRS("courseName ")
Respone.Write courseName
dbRS.MoveNext
Wend
Any help would be much appreciated. Thanks.
Update:
Here is what I've got so far. This is the whole page. I cant see whats missing. Do I need to do something with the Access database, or is it working straight away?
<!--#include file="includes/adovbs.inc" -->
<%
q = request.querystring("q")
SQL = "SELECT * FROM info WHERE (cNamn Like '%?%');"
Set cn = Server.CreateObject("ADODB.Connection")
set comm = CreateObject("ADODB.Command")
set parameter1 = CreateObject("ADODB.Parameter")
cn.Open ("db.mdb")
Set cn.ActiveConnection = cn
parameter1.Type=adVarChar 'for example
parameter1.Size=25 'for example
parameter1.Direction=adParamInput
parameter1.Value=q
comm.Parameters.Append parameter1
Set recordset = comm.Execute
recordset.Close
cn.Close
Set recordset= Nothing
Set comm = Nothing
Set cn = Nothing
%>
The error I get right now is "[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified" on the line "cn.Open ("db.mdb")". I've tried with "cn.Open server.mappath("db.mdb")" but the error I get then is "[Microsoft][ODBC Driver Manager] Data source name too long"
SQL injection occurs when you do what you have there: taking user input and directly putting it into a SQL command. Someone with malicious intent could try and submit text that would append additional SQL statements to the one you are trying to run.
The first line of defense would be to try and parse for characters that would allow injection. For example, someone adding a single quote ( ' ) would end your string in the SQL statement, and allow them to try and begin a new statement. If you run your q variable through a parse function you can try and prevent that. Replacing one single-quote with two single-quotes will pass the single-quote through as intended by the user, and prevent SQL injection from someone malicious.
Additionally, you are better served by using stored procedures and parameters if you can.
The danger is in allowing the q variable to be processed by SQL as an instruction.
you can protect yourself by doing:
q = request.querystring("q")
SQL = "SELECT * FROM course WHERE startDate >= #?# AND (courseName like '%?%');"
ConnStr = "driver=Microsoft Access Driver (*.mdb);uid=;dbq=" & Server.MapPath ("db.mdb")
Set cn = Server.CreateObject("ADODB.Connection")
set comm = CreateObject("ADODB.Command")
set parameter1 = CreateObject("ADODB.Parameter")
set parameter2 = CreateObject("ADODB.Parameter")
cn.Open ConnStr
Set comm.ActiveConnection = cn
comm.CommandText = SQL
parameter1.Type=adVarChar 'for example
parameter1.Size=25 'for example
parameter1.Direction=adParamInput
parameter1.Value=value1
parameter2.Type=adVarChar 'for example
parameter2.Size=25 'for example
parameter2.Direction=adParamInput
parameter2.Value=value2
comm.Parameters.Append parameter1
comm.Parameters.Append parameter2
Set recordset = comm.Execute
...you ASP code here...
'when your done dont forget to clean up the resources
recorderset.Close
cn.Close
Set recordset= Nothing
Set comm = Nothing
Set cn = Nothing
Also, if you know a parameter is going to be a number , or a date, checking that it is indeed so , is good protection too.