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.
Recommendation
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.
10 thoughts on “Native Database Query Security Prompts”
Hi Ken,
Interesting - thanks
I think there is a typo - the Case 2 is the worst performing should be Case 3
--Charlie
Thanks Charlie. I've edited that to correct it. Appreciate the heads up!
April 2015 update (version 2.22.4007.242) had a new options to disable this prompt!
True enough, it does. You should still try to avoid it anyway though, as it breaks your query folding performance.
Hi Ken, what do you do when you have an advanced query you want to bring in? So for an simple filtering and transforming base on a server you pick the right table and load the table and then start to transform, right?
Regards, Rik
I guess it depends on the definition of Advanced. If you're just connecting to a view, then you can connect, transform it further and you're good to go. If you want to connect to the table and transform it, that works too.
The database I was connecting to was quite large. It would take 30+ minutes to refresh PQ which was unusable. Executing a native database query only took 3 minutes to refresh. So I ended up going this route.
Hi Jonathan,
That sounds like query folding got broken, and that the majority of data was being pulled to the client to process. Depending on the driver in play, (ODBC can break folding pretty easily,) a native query could be a better option.
I was looking all over the place for this kind of information. TY very much..... but...
My question is if these standards apply also to other data base platforms ? for example I interact via ODBC with Actian Pervasive SQL, or MS Access, would your advice also work in environments different than mssql ?
Hi Jorge, yes, it should work with other database systems, but with caveats. If you have a native driver (MSSQL, MYSQL, Access, or the like), use that, as it is built to leverage query folding.
In the case of Actian Pervasive SQL, there is no native driver, so you need to fall back to ODBC (most likely). The challenge with ODBC is that it supports some query folding, but being a "one size fits all" connector, it may break folding. At that point a SQL statement may be better.
And to add extra layers, you could always build a custom connector for your set (over ODBC) that DOES support query folding. If you're interested in that, let me know as I colleague does this kind of work. Just be aware that it is custom development.