How to use a SQL Select statement with Power Query against an Access database? - sql

I've got a query that joins 4 tables that I need to run against 4 different Access .mdb files (all have the same schema) so I can compare the results in Excel. Instead of creating 16 Power Queries and joining them into 4 queries (20 total query objects) I want to write a SQL statement that joins the tables and run it against each of the 4 different data sources. There's a chance that the SQL statement may need to be updated, so having it stored in one place will make future maintenance easier.
I could not find examples of this online and the way that Power Query writes M for an Access connection is based on one table at a time. I did not want a solution that used VBA.

Poking around with the various Power Query connectors I found that I can use the ODBC connector to connect to an Access database. I was able to adjust the parameters and pass it a standard SQL statement.
I put the SQL statement in a cell (C16 in the image) and named that range Package_SQL. I also have 4 cells where I put the path and filename of the 4 Access .mdb files I want to query. I name those ranges Database1 through Database4.
This is the configuration screen to set the database paths and set the SQL statement
let
// Get the Access database to work with.
dbPath = Excel.CurrentWorkbook(){[Name="Database1"]}[Content]{0}[Column1],
// Get the SQL statement from the named range
SQL = Excel.CurrentWorkbook(){[Name="Package_SQL"]}[Content]{0}[Column1],
Source = Odbc.Query("dbq=" & dbPath & "; defaultdir=C:\Temp;driverid=25;
fil=MS Access;maxbuffersize=2048;pagetimeout=5;dsn=MS Access Database", SQL),
#"Changed Type" = Table.TransformColumnTypes(Source,
{{"Issue_Date", type date}, {"Revision_Issue_Date", type date}})
in
#"Changed Type"
As you can see the magic is done in the following line. I didn't want the defaultdir to be hard coded to a folder that everyone may not have so I set it to C:\Temp. You may need to change it or even remove it and see if it makes a difference.
Source = Odbc.Query("dbq=" & dbPath & "; defaultdir=C:\Temp; driverid=25;
fil=MS Access;maxbuffersize=2048; pagetimeout=5; dsn=MS Access Database", SQL),
I made 4 instances of that query and created another query to combine the results. The query runs as fast as most any other Access query. I am very satisfied with this solution. The query can be altered and/or repurposed from the Excel sheet without digging through the Power Query scripts.
Note that this solution does not use any VBA.

Related

How to run thousands of queries in Ms Access?

I've discovered the SQL VIEW in Ms Access to execute some queries, but I need to execute about 20.000 UPDATE queries I have in a .sql file.
When I paste in the SQL VIEW it says the "Text is too long to modify".
How can I run those UPDATE's ?
The limit to the number of characters in an Access SQL query is "about 64000" - see here https://support.office.com/en-us/article/Access-2010-specifications-HA010341462.aspx. And unfortunately you cannot execute multiple statements in a query. I think this will mean quite a bit of work for you in VBA. Here is an example approach (pseudocode):-
open file
read line into variable
while not EOF
currentdb.execute variable, dbfailonerror
read next line
wend
close file
Probably a nasty surprise for you if you are used to executing huge batches of statements using other RDBMS!
An alternative suggestion: we don't know exactly what your file looks like or where it comes from, but if it is generated from another RDBMS which you have access to, then I would very strongly recommend that you set up an ODBC connection to it, and query out the data you need (either by linking the tables or writing a pass through query), then inserting into your local Access tables. This will be many orders of magnitude faster than executing thousands of individual statements.
If your only source of the data is the SQL statements then you may still be better of if you can parse the SQL text into relevant columns (for example PK, and value to be updated, or if inserting, then all column values), then save as a csv file, import into Access, add keys as necessary, and then run a single update statement as an updateable query against the imported data and the existing tables. Dumping the file into Excel and using the various string functions may enable you to parse the data quite quickly.
There may be an easier way but you could write VBA code that reads the text file line by line and then uses DoCmd.RunSQL to run each query.

Import sql query on ODBC table in MS Access 2007

Using MS Access 2007 I would like to retrieve only part of an ODBC table.
I can import the whole table in Access but I don't need all of it and it would be a waste of space and performance to store the whole table when I only need certain columns.
In Excel I wrote a SQL query that let me retrieve only the part I'm interested in. What I'd like to know is: is it possible to import only the result of a SQL query in Access or do I have to retrieve the whole table and then run the query on it?
Is it possible using built-in Access module or should I turn to VBA?
Edit: Basically I would like to run the ODBC data connection below (currently used in Excel) in Access.
Connection string:
DSN=BLA1;
UID=BLA2;
DBQ=BLA3;
PWD=BLA4;
DBA=W;
APA=T;
EXC=F;
FEN=T;
QTO=T;
FRC=10;
FDL=10;
LOB=T;
RST=T;
GDE=F;
FRL=F;
BAM=IfAllSuccessful;
MTS=F;
MDI=F;
CSR=F;
FWC=F;
PFC=10;
TLO=0;
Command string:
SELECT *
FROM TEST TEST
WHERE (TEST.DATE_STAMP=?)
When I try to link the database I get the error The database engine can't find 'WTD.DATAPOINT_5/1000'. Make sure it is a valid parameter or alias name, that it doesn't include characters or punctuation, and that the name isn't too long. but when I use the Excel database connection I get no error and everything is updated.
You don't need to import the whole table. You could link to the ODBC table and then run a make-table query against that linked table to copy in only the rows and columns that you need.

forging a sql statement that crosses db servers for use in a perl script using DBI

perl 5.10
Access 2010
SqlServer 2008 R2
So I need to update a column in table A with data in table B where A and B have a column I can JOIN on.
This would work great
$sqlCmd = "UPDATE aa SET aa.foo = bb.fancyfoo " .
"FROM [dbo.serverOne] AS aa " .
"RIGHT JOIN [noteTable] AS bb " .
"ON aa.[recid] = bb.[recid] " ;
$sth = $dbh->prepare( $sqlCmd);
IF both tables were in the same database since there's only one database handle in play.
But my tables reside on different databases , and in fact in different servers -- dbo.ServerOne lives in an instance of SqlServer while noteTable resides in an Access database ( sorry ).
And for extra added spice, bb.fancyfoo is defined as a MEMO and aa.foo is defined as a nvarchar(max)
Frankly I can't see how this can be achieved in one pass - can a sql command make use of more than one db handle?
If not , and I have to use two separate commands ie an UPDATE on dbo.ServerOne and SELECT on noteTable, how do I set this up to work for MEMO/nvarchar(max) fields? I mean, how should I store the data while its in beteween tables? CLOB?
TIA,
Still-learning Steve
Your luck is in - both tables can be in the same database.
What you need to google for is "linked tables". There is a brief overview here but basically it lets you add an external table via ODBC (or other supported connection method).
You can either link the Access table in to the SQL Server DB or the other way around. Which will depend on whether the Access file is in a fixed location and where the majority of your data is. It's probably more efficient to link to the smaller from the larger.
Having said that, I'd expect SQL Server to be smarter about planning/executing the query so I'd try that first.
Since we're already schlepping data out the the Access tables into SqlServer tables I decided to do the JOIN via adding fields from both tables to a hashref keyed on the shared key field. Not as elegant as I'd like, but it works.
Thanks to all who replied!
CASE CLOSED
Still-learning Steve

Importing Data from .txt file to SQL Server 2005 Express

I have a tab separated .txt (Very Small file with just 10 to 15 datasets) and this file is having some columns as PrdName, PrdSize, PrdWeight, PrdCode and so on.
Now I want to import the two columns which are PrdSize and PrdCode and import it in the columns of my Database table.
I have created the columns but how do I create import clause and transfer data from .txt file to SQL Server? Thanks
Take a look at this post: Import/Export data with SQL Server 2005 Express, there are multiple options that you can use.
Since you have the express edition you'll need to either use BCP or write a program with something else.
If you have a large amount of data, or need to automate the process, definitely look into BCP as mentioned already. However, I often use excel to load one-time data sources (a few hundred to a few thousand) rows of data from odd sources into SQL Server by doing the following:
Get the data into excel (that's usually easy), assuming you get column A with 'Prdsize' and column B with PrdCode, in column C put the formula:
="INSERT INTO MYTABLE(PRDSIZE, PRODCODE) VALUES (" & a1 & "," & B1 & ")"
(in other words create syntactically correct SQL using an Excel formula - you may need to add quotes around string values etc)
and then paste that formula all the way down the column C. Then copy/paste the resultant sql insert statements into SQL Management Studio, or any other tool that can execute SQL and execute it.
Defintely a 'manual' effort, but for one-time data loads it words great.
PS: You'll need to verify the XL formula and the resultant sql syntax - my example is close, but I didn't test it.

Combining data from Excel with database

This is probably a simple question, but I really don't know what I'm doing in Excel, so hopefully someone can help me out.
I've been given an Excel spreadsheet that has two relevant columns to my task. The first column is an "External ID", and the second column is an "Internal ID". I need to select a bunch of data out of our databases (with various joins) using the Internal ID as the key, but then all of this data needs to be linked back to the External ID, and the only link between Internal/External is this spreadsheet.
For example, say a row of the spreadsheet looks like this:
ExtID IntID
AB1234 2
I need to select all the data relevant to the item with ID #2 in our database, but I have no way to get "AB1234" from the database, so I need to somehow relate this data back to "AB1234" using the spreadsheet.
What's the easiest way to accomplish this? The version of Excel is Excel 2007, and the database is Oracle, if that's relevant.
Note that I only have read permission to the production databases, so creating tables and importing the spreadsheet data to do a join is not an option.
Edited based on a comment
1 - Use MS Access to import the Excel sheet as a table.
2 - Link to your database table, also from within MS Access
External Data tab->other data sources->ODBC connection->choose yours->pick the table(s) you want
3 - Write an Access query to compare the values you want
Create->Query Design->Drop the tables you want, drag lines between them for relationships, click Run
Usually I use copy-paste and a good column-mode editor with macros to accomplish such tasks. It works fine if you only have a couple of Excel files.
Alot depends on how familiar you are with the tools you have available to you.
DO you have a tool you are familiar with that would make it easy to use the IntID to find those records? If so, can you do the query and paste the results back into the original spreadsheet in the column to the right of the column with the IntID?
If so, you will have what you want, a spreadsheet with the following columns:
ExtID (original)
IntID (original)
IntID (from Oracle)
Col1 (from Oracle)
Col2 (from Oracle) etc....
I'm not familiar with Oracle, but I know a lot of databases let you prepend a table name with # or something like that and create a temp table. Others have a temporary database where you can create things. Sometimes you can create a temp table even if you can't do anything else but select.
If you have access to do that, I would do the function as JosephStyons suggests (#2), insert your records into the temp table, and do a query based on that.
With Excel and VBA, you can use ActiveX Data Objects (ADO) as a high level way of using the OLE DB provider for a particular database. This lets you read the data from the database and you can then query that data and store the results in the spreadsheet.
Oracle OLE DB provider
ADO Guide