error '80020009' - But I'm not in a query - sql

I have a system that places an order in ASP, and when an order is submitted, a notification email goes out.
When I submit the order, I get error '80020009' and the line it points to is this:
email_text = email_text & "<html>" & _
That's a simple line that just starts building the html string that fills the email! Isn't error '80020009' supposed to be for SQL statements? Or am I missing something?
The page still continues on and completes the order process, it just shows that error message first.
I realize this question doesn't really provide much detail, but I don't know what else to specify, I'm just at a loss.
EDIT: Here's some SQL that is a few lines up from that line. Not sure how this would cause the issue, since it's telling me it's on that email line, but it can't hurt to throw it in:
str = "SELECT creation_date, supplier FROM argus.PURCHASE_ORDER WHERE purchase_order = '" & Trim(Request.Form("order_id")) & "' AND customer = '" & Session("customer_id") & "' AND store = '" & Session("store_id") & "' AND userid = '" & Session("user_id") & "'"
Set rst = ConnFW.Execute(str)
str2 = "SELECT a.store_name, a.address1, a.address2, a.city, a.state_cd, a.zipcode, b.customer_name, c.supplier_account FROM argus.STORE a, argus.CUSTOMER b, argus.ELIGIBLE_SUPPLIER c WHERE a.customer = b.customer AND a.customer = c.customer AND a.store = " & Session("store_id") & " AND b.customer = " & Session("customer_id") & " AND c.supplier = " & Trim(rst("supplier")) & ""
Set rst2 = ConnFW.Execute(str2)

Can you provide additional code? There isn't anything wrong with your code except you need to make sure you have something on the line following the underscore:
email_text = email_text + "<html>" & _
""
-- EDIT
Thanks for posting your edits. I see a couple potential issues. In your second recordset object, your trying to access rst("supplier"), but that field hasn't been read yet. Instead of using connfw.execute(str) which is used to execute sql statements like INSERT, UPDATE and DELETE, use rst.open which is used with SELECT.
Try something like:
supplier = ""
rst.open str, connfw
if not rst.eof then
supplier = rst("supplier")
end if
rst.close
Then use supplier in your 2nd sql statement. Also, if the supplier field from the eligible_supplier table is a string, you need to wrap single quotes around that field in your where clause.

Related

Run Time error 3061 Too Few parameters. Expected 6. Unable to update table from listbox

All,
I am running the below SQL and I keep getting error 3061. Thank you all for the wonderful help! I've been trying to teach myself and I am 10 days in and oh my I am in for a treat!
Private Sub b_Update_Click()
Dim db As DAO.Database
Set db = CurrentDb
strSQL = "UPDATE Main" _
& " SET t_Name = Me.txt_Name, t_Date = Me.txt_Date, t_ContactID = Me.txt_Contact, t_Score = Me.txt_Score, t_Comments = Me.txt_Comments" _
& " WHERE RecordID = Me.lbl_RecordID.Caption"
CurrentDb.Execute strSQL
I am not sure but, you can try somethink like that
if you knom the new value to insert in the database try with a syntax like this one
UPDATE table
SET Users.name = 'NewName',
Users.address = 'MyNewAdresse'
WHERE Users.id_User = 10;
Now, if you want to use a form (php)
You have to use this
if(isset($_REQUEST["id_user" ])) {$id_user = $_REQUEST["id_user" ];}
else {$id_user = "" ;}
if(isset($_REQUEST["name" ])) {$name= $_REQUEST["name" ];}
else {$name = "" ;}
if(isset($_REQUEST["address" ])) {$address= $_REQUEST["adress" ];}
else {$adress= "" ;}
if you use mysql
UPDATE table
SET Users.name = '$name',
Users.address = '$adress'
WHERE Users.id_User = 10;
i don't know VBA but I will try to help you
Going on from my comment, you first need to declare strSQL as a string variable.
Where your error expects 6 values and access doesn't know what they are. This is because form objects need to be outside the quotations of the SQL query, otherwise (as in this case) it will think they are variables and obviously undefined. The 6 expected are the 5 form fields plus 'strSQL'.
Private Sub b_Update_Click()
Dim db As DAO.Database
dim strSQL as string
Set db = CurrentDb
strSQL = "UPDATE Main" & _
" SET t_Name = '" & Me.txt_Name & "'," & _
" t_Date =#" & Me.txt_Date & "#," & _
" t_ContactID =" & Me.txt_Contact & "," & _
" t_Score =" & Me.txt_Score & "," & _
" t_Comments = '" & Me.txt_Comments & "'," & _
" WHERE RecordID = '" & Me.lbl_RecordID.Caption & "';"
CurrentDb.Execute strSQL
end sub
Note how I have used double quotes to put the form fields outside of the query string so access knows they aren't variables.
If your field is a string, it needs encapsulating in single quotes like so 'string'. If you have a date field it needs encapsulating in number signs like so #date# and numbers/integers don't need encapsulating.
Look at the code I have done and you can see I have used these single quotes and number signs to encapsulate certain fields. I guessed based on the names of the fields like ID's as numbers. I may have got some wrong so alter where applicable... Or comment and I will correct my answer.

Issues with SQL Query

as may be quiet aparent, i have very little experience with SQL queries.
I'm having problems with the following Query that i'm generating within my Vb.net application
UPDATE Payments SET B1Code = '12345', ARInvoice = '54321', INV2Go = '00000' WHERE PatientID = '400' AND Product = 'Consultation' AND Catagory = 'Orthotics'
(i have created a test record in the database matching the above information)
Its being constructed with the following code in vb.net:
Dim query As String = "UPDATE Payments SET B1Code = '" & txtB1Code.Text & "', ARInvoice = '" & txtARInvoice.Text & "', INV2Go = '" & txtInv2GoCode.Text & "' WHERE PatientID = '" & Integer.Parse(txtID.Text) & "' AND Product = '" & txtProduct.Text & "' AND Catagory = '" & txtPatientType.Text & "'"
Then being passed the my execute query function like this:
DatabaseFunctions.ExecuteQuery(query)
and the function:
Public Shared Sub ExecuteQuery(ByVal SQL As String)
CheckConnection()
Dim cmd As New OdbcCommand(SQL, con)
cmd.ExecuteNonQuery()
End Sub
The function works perfectly, i've used it time and time again for creating/editing records using simple sql queries built in similar ways as above.. The problem is this particular query returns an error:
ERROR [07002ض] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1.
Maybe someone with more sql experience than me can see what i'm missing ?
Thanks
This error indicates, that one of the columsn you use in your query does not exist.
Check your query again: did you mean Catagory OR Category ?

Joining Tables with MYSQL queries in VBA (excel)

I am completely new to Visual Basic. I am working with a MYSQL data base and I want to use VB in excel so I can work with more complex queries. For some reason, when I try to join tables in vb, I get an error message. Can somebody tell me what is wrong with my code.
strSql = "SELECT COUNT(*)FROM `order`" & _
"JOIN user ON user.id = order.destination_id" & _
"WHERE payment_status = 'pay';"
rs.Open strSql, oConn, adOpenDynamic, adLockPessimistic
res = rs.GetRows
rs.Close
Range("A1", "A6") = res(0, 0)
your current query will produce this string,
SELECT COUNT(*)FROM `order`JOIN user ON user.id = order.destination_idWHERE payment_status = 'pay';
^ ^ ^
you lack space during your concatenation, in order to correct that, simply add space before double quote.
strSql = "SELECT COUNT(*) FROM `order` " & _
"JOIN user ON user.id = order.destination_id " & _
"WHERE payment_status = 'pay';"

VBA string length problem

I have an Access application where everytime a user enters the application, it makes a temp table for that user called 'their windows login name'_Temp. In one of my reports I need to query using that table, and I can't just make a query and set it as the recourdsource of the report, since the name of the table is always different.
What I tried then was to programatically set the recordset of the report by running the query and setting the form's recordset as the query's recordset. When I tried this, it kept giving me an error about the query.
I tried to debug, and I found that the string variable isn't able to contain the whole query at once. When I ran it with break points and added a watch for the string variable, it shows me that it cuts off the query somewhere in the middle.
I've experienced this problem before, but that was with an UPDATE query. Then, I just split it into two queries and ran both of them separately. This one is a SELECT query, and there's no way I can split it. Please help!
Thank you
Heres what I've tried doing:
ReturnUserName is a function in a module that returns just the login id of the user
Private Sub Report_Open(Cancel As Integer)
Dim strQuery As String
Dim user As String
user = ReturnUserName
strQuery = "SELECT " & user & "_Temp.EmpNumber, [FName] & ' ' & [LName] AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM (tblCourse INNER JOIN (" & user & "_Temp INNER JOIN tblEmpCourses ON " & _
user & "_Temp.EmpNumber = EmpNo) ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN tblEmp_SuperAdmin ON " & user & "_Temp.EmpNumber = tblEmp_SuperAdmin.EmpNumber" & _
"WHERE (((" & user & "_Temp.EmpNumber) = [Forms]![Reports]![txtEmpID].[Text])) " & _
"ORDER BY CourseName;"
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim rsCmd As ADODB.Command
Set rsCmd = New ADODB.Command
rsCmd.ActiveConnection = CurrentProject.Connection
rsCmd.CommandText = strQuery
rs.Open rsCmd
Me.Recordset = rs
rs.Close
End Sub
This what strQuery contains when I add a breakpoint on rsCmd.CommandText = strQuery:
SELECT myusername_Temp.EmpNumber, [FName]
& ' ' & [LName] AS [Employee Name],
CourseName, DateCompleted,
tblEmp_SuperAdmin.[Cost Centre] FROM
(tblCourse INNER JOIN (myusername_Temp
INNER JOIN tblEmpCourses ON
myusername_Temp.EmpNumber = EmpNo) ON
tblCourse.CourseID=
(It's all one line, but I've written it like this because the underscores italicize the text)
And the error I get says Run Time Error: Join not Supported.
Not quite what I was hoping for, but guessing, for:
strQuery = "long query goes here"
Try:
strQuery = "some long query goes here "
strQuery = strQuery & "more query goes here "
BASED ON NEW INFORMATION:
strQuery = "SELECT " & user & "_Temp.EmpNumber, [FName] & ' ' & [LName] AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM (tblCourse " & _
"INNER JOIN tblEmpCourses ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN (Temp INNER JOIN tblEmp_SuperAdmin " & _
"ON Temp.EmpNumber = tblEmp_SuperAdmin.EmpNumber) " & _
"ON Temp.EmpNumber = tblEmpCourses.EmpNo " & _
"WHERE " & user & "_Temp.EmpNumber = " & [Forms]![Reports]![txtEmpID] & _
" ORDER BY CourseName;"
Note that in VBA:
& [Forms]![Reports]![txtEmpID].[Text] &
That is, the reference to the form must go outside the quotes so you get the value.
NEW INFORMATION #2
Your best bet would be to add these tables to the Access query design window and create the joins that you want, then switch to SQL view and use the string generated for you. I do not believe that the string is too long, only that the SQL is incorrect. The SQL I posted above should work, but it may not be what you want.
You can programmatically create a querydef that fits the user. So, when your report is called, you
Delete LoginName_Query_Temp (CurrentDb.QueryDefs.Delete), if it already exists.
Create the querydef (CurrentDB.CreateQueryDef), using LoginName_Temp as the table name.
Set the RecordSource of your Report to LoginName_Query_Temp.
Open the report.
I don't see what purpose the table myusername_Temp serves here. Is that where the name fields are? If so, avoid the join entirely:
Dim lngEmpNumber As Long
Dim strName As String
Dim strSQL As String
lngEmpNumber = Forms!Reports!txtEmpID
strName = DLookup("[FName] & ' ' & [LName]", "myusername_Temp", "EmpNumber=" & lngEmpNumber
strSQL = "SELECT " & Chr(34) & strName & Chr(34) & " AS [Employee Name], " & _
"CourseName, DateCompleted, tblEmp_SuperAdmin.[Cost Centre] " & _
"FROM tblCourse " & _
"INNER JOIN tblEmpCourses " & _
"ON tblCourse.CourseID = tblEmpCourses.CourseID) " & _
"INNER JOIN tblEmp_SuperAdmin " & _
"ON tblEmp_SuperAdmin.EmpNumber = tblEmpCourses.EmpNo " & _
"WHERE tblEmp_SuperAdmin.EmpNumber = " & lngEmpNumber & _
" ORDER BY CourseName;"
Now, the parentheses may need to be changed in the join (I always do my equi-joins in the Access QBE and let it take care of the getting the order and parens correct!), and my assumptions about the purpose of the temp table may be wrong, but I don't see it being used for anything other than as an intermediate link between tables, so I guessed it must be there to provide the name fields.
If that's wrong, then I'm at a loss as to why the temp table needs to be there.
Also, in your second post you referred to the control on the form as:
Forms!Reports!txtEmpID.Text
...the .Text property of Access controls is accessible only when the control has the focus. You could use the .Value property, but since that's the default property of Access controls, you should just stop after the name of the control:
Forms!Reports!txtEmpID
...you'll see this is how I did it in my suggested code.
I find the idea of your name-based temp table to be highly problematic to begin with. Temp tables don't belong in a front end, and it's not clear to me that it is actually a temp table. If it's temp data, put it in a shared table and key the record(s) to the username. Then you don't have to worry about constructing the table name on the fly.

Improve asp script performance that takes 3+ minutes to run

I use an SQL statement to remove records that exist on another database but this takes a very long time.
Is there any other alternative to the code below that can be faster? Database is Access.
email_DB.mdb is from where I want to remove the email addresses that exist on the other database (table Newsletter_Subscribers)
customers.mdb is the other database (table Customers)
SQLRemoveDupes = "DELETE FROM Newsletter_Subscribers WHERE EXISTS (select * from [" & strDBPath & "Customers].Customers " _
& "where Subscriber_Email = Email or Subscriber_Email = EmailO)"
NewsletterConn = "Driver={Microsoft Access Driver (*.mdb)};DBQ=" & strDBPath & "email_DB.mdb"
Set MM_editCmd = Server.CreateObject("ADODB.Command")
MM_editCmd.ActiveConnection = NewsletterConn
MM_editCmd.CommandText = SQLRemoveDupes
MM_editCmd.Execute
MM_editCmd.ActiveConnection.Close
Set MM_editCmd = Nothing
EDIT: Tried the SQL below from one of the answers but I keep getting an error when running it:
SQL: DELETE FROM Newsletter_Subscribers WHERE CustID IN (select CustID from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email or Subscriber_Email = EmailO)
I get a "Too few parameters. Expected 1." error message on the Execute line.
I would use WHERE Subscriber_Email IN (Email, Email0) as the WHERE clause
SQLRemoveDupes = "DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _
(select * from [" & strDBPath & "Customers].Customers where Subscriber_Email IN (Email, EmailO)"
I have found from experience that using an OR predicate in a WHERE clause can be detrimental in terms of performance because SQL will have to evaluate each clause separately, and it might decide to ignore indexes and use a table scan. Sometime it can be better to split it into two separate statements. (I have to admit I am thinking in terms of SQL Server here, but the same may apply to Access)
"DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _
(select * from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email)"
"DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _
(select * from [" & strDBPath & "Customers].Customers where Subscriber_Email = EmailO)"
Assuming there's an ID-column present in the Customers table, the following change in SQL should give better performance:
"DELETE FROM Newsletter_Subscribers WHERE ID IN (select ID from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email or Subscriber_Email = EmailO)"
PS. The ideal solution (judging from the column names) would be to redesign the tables and code logic of inserting emails in the first place. DS
Try adding an Access Querydef and calling that.
It sounds like you do not have an index on the subscriber_enail field. This forces a table scan ( or several). Add an index on this field and you should see significant improvement.
I would have coded the query
DELETE FROM Newsletter_Subscribers where (Subscriber_Email = Email or Subscriber_Email = EMail0)
I would try splitting this into two separate statements with separate database connections.
First, fetch the list of email addresses or IDs in the first database (as a string).
Second, construct a WHERE NOT IN statement and run it on the second database.
I would imagine this would be much faster as it does not have to interoperate between the two databases. The only possible issue would be if there are thousands of records in the first database and you hit the maximum length of a sql query string (whatever that is).
Here are some useful functions for this:
function GetDelimitedRecordString(sql, recordDelimiter)
dim rs, str
set rs = db.execute(sql)
if rs.eof then
str = ""
else
str = rs.GetString(,,,recordDelimiter)
str = mid(str, 1, len(str)-len(recordDelimiter))
end if
rs.close
set rs = nothing
GetDelimitedRecordString = str
end function
function FmtSqlList(commaDelimitedStringOrArray)
' converts a string of the format "red, yellow, blue" to "'red', 'yellow', 'blue'"
' useful for taking input from an html form post (eg a multi-select box or checkbox group) and using it in a SQL WHERE IN clause
' prevents sql injection
dim result:result = ""
dim arr, str
if isArray(commaDelimitedStringOrArray) then
arr = commaDelimitedStringOrArray
else
arr = split(commaDelimitedStringOrArray, ",")
end if
for each str in arr
if result<>"" then result = result & ", "
result = result & "'" & trim(replace(str&"","'","''")) & "'"
next
FmtSqlList = result
end function