Importing data from Excel into Access using DAO and WHERE clause - excel

I need to import certain information from an Excel file into an Access DB and in order to do this, I am using DAO.
The user gets the excel source file from a system, he does not need to directly interact with it. This source file has 10 columns and I would need to retrieve only certain records from it.
I am using this to retrieve all the records:
Set destinationFile = CurrentDb
Set dbtmp = OpenDatabase(sourceFile, False, True, "Excel 8.0;")
DoEvents
Set rs = dbtmp.OpenRecordset("SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536]")
My problem comes when I want to retrieve only certain records using a WHERE clause. The name of the field where I want to apply the clause is 'Date (UCT)' (remember that the user gets this source file from another system) and I can not get the WHERE clause to work on it. If I apply the WHERE clause on another field, whose name does not have ( ) or spaces, then it works. Example:
Set rs = dbtmp.OpenRecordset("SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE Other = 12925")
The previous instruction will retrieve only the number of records where the field Other has the value 12925.
Could anyone please tell me how can I achieve the same result but with a field name that has spaces and parenthesis i.e. 'Date (UCT)' ?
Thank you very much.
Octavio

Try enclosing the field name in square brackets:
SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE [Date (UCT)] = 12925
or if it's a date we are looking for:
SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE [Date (UCT)] = #02/14/13#;
To use date literal you must enclose it in # characters and write the date in MM/DD/YY format regardless of any regional settings on your machine

Related

Cognos Static prompt values to be passed to SQL

I have a static prompt which is a single select. In that I have two values lets call it A and B. So when I select option 'A' my report pulls all data from the DB which is expected. So when user Select option 'B' the report should pull only the records whose code = 'M'. Here code is a column name in the report.
Note: For option 'A' I don't need to set any prompt in the report because it should pull all records by default.
Let's assume your parameter name is param and data item is named item.
Filter expression:
if (?param? = 'A')
then ([item])
else ('M')
= [item]
Note: You absolutely need to use a prompt. The result of selecting A should be to not filter.
I think I understand, try this:
Make the prompt a single value (i.e. B) with a use value of 'M'
Make the HEADER TEXT for the prompt A (so it is not an actual selection)
Make the filter optional
if the user selects A - the prompt is NULL and the optional filter is ignored
if the user selects B - the filter [Some data item] = ?YourParm? will occur
Also, if you prefer to not have header text
you can make static values A, B and modify the optional filter to be like this:
(?YourParm? <> 'M') OR ([Some data item] = ?YourParm?)

is there a difference between `quote_ident()` and parametized queries in psycopg2?

In python3 and postgresql12, is there a safety difference between parametizing SQL queries the "proper" way or just escaping potentially dangerous content using psycopg2.quote_ident()?
For example, consider these two options.
Option 1:
name = get_unsafe_input_from_web_form()
cursor.execute("SELECT * FROM students WHERE name = %s;", (name,))
Option 2:
from psycopg2.extensions import quote_ident
name = get_unsafe_input_from_web_form()
cursor.execute(f"SELECT * FROM students WHERE name = {quote_ident(name, cursor)};"
The documentation is not particularly explicit. Is Option 2 totally equivalent in terms of safety against injection attacks?
quote_ident() would be the wrong thing to use, as it is for identifiers e.g table, column names. You would want quote_literal() which does not exist in psycopg2.extensions. I would stick with the first option, but using the psycopg2.sql module:
https://www.psycopg.org/docs/sql.html
Safety-wise, both parameterized queries and quote_ident can safely handle untrusted input and will not open you to SQL injection issues. But you can't use quote_ident for values as you're trying to do in your example. The string you're passing to cursor.execute() will end up being (for name foobar) SELECT * FROM students WHERE name = "foobar";, which will try to find rows where the name column is equal to the foobar column, not where name is equal to the string 'foobar'.

Flag difference in a string variable in SQL

I have data as:
Image of data I have
I want to add flag variables in the data as:
Image of data I want
I have tried the lag function but it didn't work due to the variable being character.
I want to flag any change in string variable.Please help.
I solved this using the query along the lines of:
CREATE TEMP TABLE WANT AS(
SELECT *, CASE WHEN LAG(NAME) OVER(PARTITION BY ID ORDER BY ID) != NAME
THEN 1
ELSE 0
END AS FLAG1
FROM DATA_HAVE
ORDER BY
ID);
No judging, just sharing.

Condition IF In Power Query's Advanced Editor

I have a field named field, and I would like to see if it is null, but I get an error in the query, my code is this:
let
Condition= Excel.CurrentWorkbook(){[Name="test_table"]}[Content],
field= Condition{0}[fieldColumn],
query1="select * from students",
if field <> null then query1=query1 & " where id = '"& field &"',
exec= Oracle.Database("TESTING",[Query=query1])
in
exec
but I get an error in the condition, do you identify the mistake?
I got Expression.SyntaxError: Token Identifier expected.
You need to assign the if line to a variable. Each M line needs to start with an assignment:
let
Condition= Excel.CurrentWorkbook(){[Name="test_table"]}[Content],
field= Condition{0}[fieldColumn],
query1="select * from students",
query2 = if field <> null then query1 & " some stuff" else " some other stuff",
exec= Oracle.Database("TESTING",[Query=query2])
in
exec
In query2 you can build the select statement. I simplified it, because you also have conflicts with the double quotes.
I think you're looking for:
if Not IsNull(field) then ....
Some data types you may have to check using IsEmpty() or 'field is Not Nothing' too. Depending on the datatype and what you are using.
To troubleshoot, it's best to try to set a breakpoint and locate where the error is happening and watch the variable to prevent against that specific value.
To meet this requirement, I would build a fresh Query using the PQ UI to select the students table/view from Oracle, and then use the UI to Filter the [id] column on any value.
Then in the advanced editor I would edit the generated FilteredRows line using code from your Condition + field steps, e.g.
FilteredRows = Table.SelectRows(TESTING_students, each [id] = Excel.CurrentWorkbook(){[Name="test_table"]}{0}[fieldColumn])
This is a minor change from a generated script, rather than trying to write the whole thing from scratch.

Error using TransferSpreadsheet to import an Excel spreadsheet

I have a routine that helps me locate a the row of word in a standardized worksheet.
Based on the location of the word - for example, I search in column 'A'
It finds the word on row 7.
I now know that I can use the range A8:M14 as the data I want to import into my table, so I created a function 'GETBASELINE' that would just return that string - "A8:M14"
So now I have a table called tbl_TEMP_Import with these fields
BASELINE|OCT|NOV|DEC|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP
I call it like so:
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, "tbl_TEMP_Import", strPath, False, GetBASELINE(strPath, strSheet)
I get Error 2391 Field 'F1' doesn't exist in destination tbl_TEMP_Import
If I change it to 'True' for 'has field names'
I get Error 3270 'Property Not Found'
I wish I could get better debugging. Doesn't seem too complex to accomplish this.
Answer with 'True' for 'has field names':
You have to give the table the field heading as well... so the code for GETBASELINE must equal "A7:M8" ... (I'm not sure where 14 came from)
A7:M7 are Field names
A8:M8 are 1st set of values
Answer with 'False' for 'has Field names':
You must change the field names, because the call brings in temp field names, F1,F2 and so on
Manually you can change the names. It is programmable as well.
In any event, once you call the script one way, be careful not to 'mix' them with each other! Delete one before you call the next

Resources