Delete table in access with String with 3 values - excel

Good day,
Im getting an error (syntax error missing operator in a query expression for "and monitorNumber = Monit)
SQLDel = "DELETE FROM HBAU WHERE Peoplesoft ID ='" & PSID & "' and DATE =#" & InputDate & "# and MonitorNumber = Monit"
can anyone tell me whats missing...

If Monit is VBA variable, try this one:
SQLDel = "DELETE FROM HBAU WHERE [PeoplesoftID] =" & PSID & " and [DATE] =#" & InputDate & "# and [MonitorNumber] = " & Monit
also should Peoplesoft ID be PeoplesoftID? Note if your PeoplesoftID has numeric type, you don't need single quotes around PSID.
Aslo you may want to read this: Global Variables in SQL statement

Related

Expression.Error when dynamically passing in Teradata SQL query (with column aliases) to ODBC query

I have a macro that prompts me for a SQL query (unless it was called by another Sub, in which case it uses the argument that was passed into its optional string parameter as the query) and then executes the query against my Teradata SQL database.
It works fine, unless there's a column alias containing a space in the query.
Example query:
SELECT 2 + 2 AS "Query Result";
Error:
Run-time error '1004':
[Expression.Error] The name 'Source' wasn't recognized. Make sure it's spelled correctly.
The line of code which I believe is the culprit is as follows (my apologies for the readability-- I recorded the macro, modified it just enough to get it to work somewhat dynamically and then haven't touched it since).
ActiveWorkbook.Queries.Add Name:=queryName, formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source = Odbc.Query(""dsn=my-server-name"", " & Chr(34) & code & Chr(34) & ")" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " Source"
I assume it has to do with the fact that the example query above has double quotes for the alias, which are confusing the syntax when trying to be interpolated. Any help would be greatly appreciated!
Here's what the string for the formula is set to in this line:
ActiveWorkbook.Queries.Add Name:=queryName, formula:=<string here>
after all the chr() and concatenation are done:
let
Source = Odbc.Query("dsn=my-server-name", "<code>")
in
Source
That token <code> is replaced by whatever is in your variable code. So I suspect you are correct in that this formula would need to have it's double quotes escaped fully.
In other words this string you are building form Formula is going to be evaluated as code itself, and even in that evaluation it will be passing more code (your SQL) onto the Teradata server to be evaluated there.
You are in code inception. VBA code writing powerquery code writing Teradata code.
Understanding that and guessing a bit here, I'm thinking your current code variable looks something like:
code="SELECT 2 + 2 AS ""Query Result"";"
Your double quotes are already escaped for VBA. BUT because you have to survive another round of eval in powerquery you need to escape once again. Instead:
code="SELECT 2 + 2 AS """"Query Result"""";"
*I think...

SQLClient Command Parameter Query String Length

I am connecting to a SQL Server and am trying to limit the results by adding parameters. The first parameter I added, #sdate, worked just fine. But, now I am trying to add a second parameter which is not working. I want the field, LP_EOC_DATA.PL, to only be returned if the length of the string is greater than 6 characters long. The code below executed, and like I say, the dates returned were correct, but it also returned values from LP_EOC_DATA.PL that had string lengths less than 6. Please let me know if you know how to get this to work. Thanks in advance.
Sub doSQL()
Dim myConn As SqlConnection
Dim myCmd As SqlCommand
Dim myReader As SqlDataReader
Dim sqlString As String = "SELECT LP_EOC_DATA.PL as PLs, LP_EOC_DATA.cDate as ReadDate, LP_EOC_LOV.LOCATION as Location " &
"FROM LP_EOC_DATA INNER JOIN LP_EOC_LOV ON LP_EOC_DATA.PIC = LP_EOC_LOV.PIC " &
"WHERE LP_EOC_DATA.cDate > (#sdate) AND LEN(LP_EOC_DATA.PL) > #slen1 " &
"UNION SELECT dbo.VT_DATA.PL as PLs, dbo.VT_DATA.cDate as ReadDate, dbo.VT_LOV.LOCATION as Location " &
"FROM dbo.VT_DATA INNER JOIN dbo.VT_LOV ON dbo.VT_DATA.PIC = dbo.VT_LOV.PIC " &
"WHERE dbo.VT_DATA.cDate > (#sdate) AND LEN(dbo.VT_DATA.PL) > #slen1 " &
"ORDER BY ReadDate;"
myConn = New SqlConnection("SERVER=ServerName;UID=uName;" &
"PWD=Password;")
myCmd = myConn.CreateCommand
myCmd.CommandText = sqlString
myCmd.Parameters.AddWithValue("#sdate", DateTimePicker1.Value)
myCmd.Parameters.AddWithValue("#slen1", 6)
'myCmd.Parameters.AddWithValue("#rx1", "'%[^0-9a-z]%'")
'myCmd.Parameters.AddWithValue("#rx2", " dbo.VT_DATA.PL NOT LIKE '%[^0-9a-z]%'")
myConn.Open()
myReader = myCmd.ExecuteReader()
Table.Load(myReader)
DataGridView1.Visible = True
DataGridView1.DataSource = Table
lblTotal.Text = Table.Rows.Count
End Sub
Also, as you can see, I am looking to add another parameter that only returns alphanumeric results from the same LP_EOC_DATA.PL field. I haven't got quite that far yet, but if you see something I'm doing wrong there too, I'd appreciate the input.
It helps if you format your SQL a little more. There's some structure, but it still comes off as a big wall of text. It's even harder for us to debug than it is for you, since we don't know your schema at all. There are also a number of other little things you should do different before we even address the question (Using block so connection is closed in case of exception, avoid AddWithValue() for index safety, isolate SQL from user interface, etc):
Function doSQL(StartDate As DateTime) As DataTable
Dim result As New DataTable
Dim sqlString As String = _
"SELECT LP_EOC_DATA.PL as PLs, LP_EOC_DATA.cDate as LPRReadDate, LP_EOC_LOV.LOCATION as Location " &
"FROM LP_EOC_DATA " &
"INNER JOIN LP_EOC_LOV ON LP_EOC_DATA.PIC = LP_EOC_LOV.PIC " &
"WHERE LP_EOC_DATA.cDate > #sdate AND LEN(COALESCE(LP_EOC_DATA.PL,'')) > #slen1 " &
"UNION " &
"SELECT dbo.VT_DATA.PL as PLs, dbo.VT_DATA.cDate as ReadDate, dbo.VT_LOV.LOCATION as LPRLocation " &
"FROM dbo.VT_DATA " &
"INNER JOIN dbo.VT_LOV ON dbo.VT_DATA.PIC = dbo.VT_LOV.PIC " &
"WHERE dbo.VT_DATA.cDate > #sdate AND LEN(COALESCE(dbo.VT_DATA.PL,'')) > #slen1 " &
"ORDER BY ReadDate;"
Using myConn As New SqlConnection("SERVER=ServerName;UID=uName;" &
"PWD=Password;"), _
myCmd As New SqlCommand(sqlString, myConn)
myCmd.Parameters.Add("#sdate", SqlDbType.DateTime).Value = StarDate
myCmd.Parameters.Add("#slen1", SqlDbType.Int).Value = 6
myConn.Open()
result.Load(myCmd.ExecuteReader())
End Using
Return result
End Function
And then call it like this:
Dim tbl As DataTable = doSql(DateTimePicker1.Value)
DataGridView1.Visible = True
DataGridView1.DataSource = tbl
lblTotal.Text = tbl.Rows.Count
As for the question, there are a few possibilities: NULL values can give unexpected results in this kind of situation (the code I posted already accounts for that). You may also have trouble with certain unicode whitespace padding your character count. Another possibility is char or nchar fields instead of varchar or nvarchar, though I don't think that's the issue here.
This is not an answer to the question per se but a reply to the request for an XML literal example. As that requires a few lines of code, I'd rather not put it in a comment.
Dim sql = <sql>
SELECT *
FROM MyTable
WHERE MyColumn = #MyColumn
</sql>
Dim command As New SqlCommand(sql.Value, connection)
Note that the element name can be anything you want but I usually use 'sql' when it's for SQL code.

Passing string result to query then export as csv

Good Afternoon,
I have an access query that contains a list of all my customers lets call that CUS
I have another query that has a list of ORDERS
I would like to write some VBS that cycles through the customer list and exports a csv file containing all orders that belong to that customer.
The vba would then move on to the next customer on the list and perform the same action.
Any help would be great.
Snippet of code below
almost there cant get the WHERE condition working it keeps displaying a popup for me to populate however the same string is feeding the msgbox fine here is a snippet below tht is within the loop
strcustcode = rs!OCUSTCODE
ordercount = rs!orders
TIMEFILE = Format$(Time, "HHMM")
MsgBox ([strcustcode] & " has " & [ordercount] & " orders")
StrSQL = "Select * From [24-ND_Cus] where [24-ND_Cus].[OCUSTCODE] = strcustcode "
Set qd = db.CreateQueryDef("tmpExport", StrSQL)
DoCmd.TransferText acExportDelim, , "tmpExport", "c:file.csv" db.QueryDefs.Delete "tmpExport" –
Don't use [ ] around VBA variables. Don't use parens for the MsgBox when you just want to give user a message. The parens make it a function that requires a response by user to set a variable.
MsgBox strcustcode & " has " & ordercount & " orders"
Concatenate the variable into the SQL statement. If OCUSTCODE is a text type field, use apostrophe delimiters for the parameter.
StrSQL = "Select * From [24-ND_Cus] Where [OCUSTCODE] = '" & strcustcode & "'"
I don't advise code that routinely modifies design and changing a query SQL statement is changing design. If the only change is filter criteria and a dynamic parameterized query won't work, I suggest a 'temp' table - table is permanent, data is temporary. Delete and write records to the table and export the table.

Error handing page not trapping all errors

I have this simple error checking page on my classic ASP website and have a custom error page set up so that scripting errors (500 and 500.100) call this error page so that errors are logged into a MySQL table:
<!--#INCLUDE file="db_connection.asp" -->
<%
On Error Resume Next
'crappy function I use
Function newstr(str)
newstr = Server.HTMLencode(str)
newstr = Replace(newstr, "'","''")
newstr = Replace(newstr, "\","\\")
newstr = Replace(newstr, chr(10), "<br />")
End Function
'get all form data and put it into a variable
For ix = 1 to Request.Form.Count
fieldName = Request.Form.Key(ix)
fieldValue = Request.Form.Item(ix)
bb = bb & fieldName & ": " & fieldValue & vbcrlf
Next
bb = newstr(bb)
set objError = Server.getLastError()
strNumber = objError.AspCode & " : " & Err.Number
strSource = objError.Category
strPage = objError.File
strDesc = objError.Description & " : " & ObjError.ASPDescription & " :: " & Err.Description
strDesc = newstr(strDesc)
strCode = Server.HTMLEncode(objError.Source)
If strCode = "" then strCode = "No code available"
strLine = ObjError.Line
strASPDesc = ObjError.ASPDescription
strRemoteAddr = Request.ServerVariables("REMOTE_ADDR")
strLocalAddr = Request.ServerVariables("LOCAL_ADDR")
ref = request.servervariables("HTTP_REFERER")
str = request.servervariables("QUERY_STRING")
ip_url = strRemoteAddr
ua = newstr(request.servervariables("HTTP_USER_AGENT"))
totalstring = strPage & "?" & str
sql = ""
sql = SQL & " INSERT INTO error_log ("
sql = SQL & " er_time, "
sql = SQL & " er_number, "
sql = SQL & " er_source, "
sql = SQL & " er_page, "
sql = SQL & " er_desc, "
sql = SQL & " er_code, "
sql = SQL & " er_line, "
sql = SQL & " er_remote_addr, "
sql = SQL & " er_local_addr, "
sql = SQL & " er_str, "
sql = SQL & " er_ref, "
sql = SQL & " er_type, "
sql = SQL & " ip_url, "
sql = SQL & " er_br, "
sql = SQL & " er_form"
sql = SQL & " ) VALUES ("
sql = SQL & " now(),"
sql = SQL & " '" &strNumber&"',"
sql = SQL & " '"&strSource&"',"
sql = SQL & " '"&strPage&"',"
sql = SQL & " '"&strDesc&"',"
sql = SQL & " '"&strCode&"',"
sql = SQL & " '"&strLine&"',"
sql = SQL & " '"&strRemoteAddr&"',"
sql = SQL & " '"&strLocalAddr&"',"
sql = SQL & " '"&totalstring&"',"
sql = SQL & " '"&ref&"',"
sql = SQL & " '500',"
sql = SQL & " '"&ip_url&"',"
sql = SQL & " '"&ua&"',"
sql = SQL & " '"&bb&"') "
oConn.Execute(sql)
%>
The trouble I'm finding is that lots of lines keep ending up in the error log, but are not triggering Server.getLastError, because all of the variables from that are NULL. And I know that someone isn't directly visiting the URL of the error page because the "strPage" variable, (set by objError.File) is populated.
However, if I visit the page that is erroring, it always works fine.
The pages which are in the error log always have a querystring associated with them - but the ID of that always varies - so e.g. it might be that the "totalstring" (made up of objError.File concatenated with a question mark followed by request.servervariables("QUERY_STRING") could be:
/music/view.asp?id=192
/designs/page.asp?id=5775
/designs/page.asp?id=5797
They all error in the same place, which is:
e = newstr(request("id"))
Where "newstr" is the function mentioned at the top of this page. I know that that function is a load of crap and risks SQL injections etc.
However, in this case, I can't work out why the pages are erroring as they always work fine for me and most of the site users.
What's strange is that the IP addresses of the users getting the errors are always from the same ISP - generally one ISP in Germany.
Could something suspicious be going on in the background? Is there any additional logging I could do to get to the bottom of this?
Update 30th July 2015
Thanks to answer provided by #John, I was able to get to the bottom of this, and avoided errors by putting this at the top of every page:
<%
''get the cookie data
ck = Request.ServerVariables("HTTP_COOKIE")
'' does the cookie data contain "; = true;" somewhere, does not matter where
v1 = instr(ck, "; =true;")
''if the cookie data starts with "=true;" OR if "; =true;" appears somewhere in the cookie, then redirect somewhere else
if left(ck,6) = "=true;" OR v1 > 0 then response.redirect ("somewhere-else.asp")
%>
More info also here:
https://forums.iis.net/p/1226865/2106015.aspx?Re+Request+Cookies+generate+80004005+2147467259+error+if+cookie+with+no+name
Seems to be some hacking type activity originating from ISP Hetzner Online AG
I have been getting a lot of similar errors where no error number is recorded. I found the problem due to the cookies that were being sent and at least one of the cookies having no name.
When you do Request("id") it checks the querystring, form post and then cookies. Classic ASP does not seem capable of handling cookies where there is no name and fails in this situation with an error.
Looking at the requests I am receiving they do look like unusual hack attempts targeting cookies.
To see if this is the case I would suggest you log the cookie HTTP header as well.
One option would be to change from Request to Request.QueryString or Request.Form depending on how you are expecting the parameter to be passed (GET or POST).
If that is not an option then you could add some code to check for this no name cookie problem, something like this should do the job:
On Error Resume Next
Request.Cookies("test")
If Err.Number <> 0 Then Server.Transfer("/common/500.asp")
On Error Goto 0
This just checks whether it is possible to read a cookie, and it doesn't matter what cookie name you use or whether the cookie exists or not. It will end execution if invalid cookies are sent. If you have an include file that is run on every request you could add this to the beginning.
See my own SO question for some further information.

Help with function in string

I have a variable, emailBody, which is set to a string stored in a database. The email body is set to a string via a dlookup function.
emailBody = DLookup("emailBody", "listAdditions", "Id = " & itemType)
The string that email body is set to includes an IIf function (which includes a dlookup function). When
?emailBody is entered in the immediate window during runtime, it shows that emailBody is set to the following string:
The new commodity is" & Iif(dlookup("IsVague", "CommodityType", "Description= " & newItem)="1", "vague.", "not vague.")
However, I want the dlookup and IIf functions to be evaluated and their results stored in the string. How do I properly format the emailBody string ("the new commodity...") in my database so that the functions will be evaluated and the results stored in the emailBody variable?
Your question is a bit unclear, but if [Id] (Or [Description]) is a string, then you Dlookup must be like this:
emailBody = DLookup("emailBody", "listAdditions", "Id = '" & itemType & "'")
or
emailBody = DLookup("emailBody", "listAdditions", "Id = """ & itemType & """")
That is, your constant should be surrounded by quotes. You can either use ' (single quote) or "" (doubled double quote).
I am somewhat concerned about the value of newitem, but in general you can use Eval:
s = """The new commodity is"" & " _
& "Iif(dlookup(""IsVague"", ""CommodityType"", ""Description= "" & newItem)=""1"", ""vague."", ""not vague."")"
s2 = Eval(s)
I am not sure that this is the way to go, think about it.
So you have this exact string stored in a table field, and you want Access/VBA to evaluate it, correct?
"The new commodity is " & Iif(dlookup("IsVague", "CommodityType", "Description= " & newItem)="1", "vague.", "not vague.")
If so, try the Eval() command:
emailBody = Eval(DLookup("emailBody", "listAdditions", "Id = " & itemType))

Resources