In a comment on my Parameter Tables post, Talha asks why we get prompted with a Native Database Query message each time the value of the parameter used in a SQL query changes:
I had a question. The value I grab from my parameter table, I store it in a variable and use it in my SQL query. However, every time I change the parameter, I get the following prompt:
NATIVE DATABASE QUERY
You are about to run a native database query. Native queries can make changes to the database. Would you like to run the following query?
Is there any way I can make this go away?
To answer this, it helps to understand why this message comes up.
Replicating The Issue
When you connect to a SQL server database in Power Query, there are three parts to the initial dialog:
Server and Database are pretty straight forward, but the SQL Statement is marked as optional, and is actually hidden under the arrow at the left. Now, for anyone who has written SQL in the past, you open up that little window, pop in your SQL and click OK. And you’ll get prompted with a message about trusting a Native Database Query.
On the other hand… if you DON’T fill in a SQL statement, you’ll be taken to a list of all tables and views in the database that you have access to, and will be able to bring those in to start working with them. Do that, and you’ll NEVER SEE THIS PROMPT.
Why Prompt About a Native Database Query?
A native database query is basically SQL code that you provide to pass to the database. Power Query treats this as potentially dangerous, so gives you a warning when you do this. And every time you change the underlying SQL query (pass one parameter to it to change it in some way), the Query is seen as “new” and again, potentially dangerous.
I tend to agree that this is a bit overkill. I’m not a SQL expert, by any means, but if the query is just a SELECT query, then I’m not sure why we need to be warned about it. You’d think that would be easy enough for the PQ team to parse out, looking for keywords like ALTER, DROP, UPDATE, DELETE and such, but regardless, that’s the way it is.
Avoiding the Error
Now that we know what is doing it, how do we avoid it? The answer is actually more simple, but harder to swallow than you might like. Don’t use the Native Database Query functionality!
I really struggled with this at first. I saw Power Query as a “SQL Sever Management Studio Light” for Excel pros. It’s not. It’s totally different. What the PQ team has built is a way for non-power users to be able to query, clean, restrict and reshape their data. And if you do it their way, then you won’t get this irritating prompt.
In the case of grabbing data from SQL Server, you’d simply connect to the server, grab the table/view you want, then start setting your filters in Power Query to restrict down the data you want. The UI makes this easy, and it’s a lot easier to tweak the data to get it right than forcing an Excel person to go back and tweak their SQL.
And here’s the cool part… once you’ve done this, Power Query takes advantage of a technology called “Query Folding”, which folds up all the reshaping commands you’ve issued. It passes those to the SQL server as a single command to bring back your data. In layman’s terms (although not perfectly technically correct), you can look at this as if Power Query is allowing you a graphical way to write your SQL for you behind the scenes, then pass it to the server. And because Power Query knows it won’t do anything dangerous, it doesn’t prompt you about potential problems.
What About Performance?
A few months ago I asked someone at Microsoft this question… the thrust of my question was if Power Query would be more or less efficient than passing an optimal SQL query. His reply was that no, if someone was a SQL Ninja, they could certainly come up with something that performed better in some situations. Having said that, for the majority of Excel pros, Power Query will do a better job, as we don’t tend to be SQL optimization experts.
Further to this, the very worst thing you can do for performance is provide a base query then try to do further filtering. Look at these three cases:
|Case 1||Use Power Query to:
Connect to table Transactions
Filter to Dept <> 150
|Case 2||Native Database Query:
Select * From Transactions Where Dept <> 150
|Case 3||Native Database Query:
Select * From Transactions
Use Power Query to filter:
Dept <> 150
Case 1 is the preferred method when dealing with Power Query. It will roll both steps up into a single statement, and retrieve the requested set from the server.
Case 2 returns the same data as Case 1, but prompts you with a Native Database Query on each computer you run the solution on. (You can’t even save the connection with the workbook, it’s a user specific trust flag.)
Case 3 is the worst performing. The reason is that the initial table has to be brought to Power Query in it’s entirety, and THEN you can start filtering. Why? Because Power Query cannot query fold it’s commands into the SQL you provided.
Even though connecting to a table, then re-creating all the filtering steps seems less graceful at first, this is the method I’d recommend you take. In fact, I’ve actually made it a habit to remove any Native Database Queries from project I wrote in the past, replacing them with the recommended method.
To me this offers two benefits:
- No security prompting. May seem minor, but when you put a Power Query error in front of non-tech users, they tend to freak out. Why put them through that?
- It makes the query easier to follow/tweak when you need to debug it later. And let’s face it, sooner or later you’ll need to do this.