-1

I'm genuinely curious and not the world's most well-versed in the inner workings of SQL. I apologize in advance if my terminology reflects my ignorance.

I've always been under the impression that using Stored Procedures in SQL allows for more efficient operation because the interpreter can predict the nature of the transaction and optimize it before it is called.

My question has to do with using dynamic table names in Stored Procedures, such as

  USE [EODData]
  GO
  SET ANSI_NULLS ON
  GO
  SET QUOTED_IDENTIFIER ON
  GO
  CREATE PROCEDURE [dbo].[Import_Correlation_CSV] 
@fileURL varchar(500)
  AS
  BEGIN
SET NOCOUNT ON;
    Declare @myTableSQL nvarchar(max);
    SET @myTableSQL = 'BULK INSERT EOD_Stock_Correlations FROM '+@fileURL+' WITH ( FIELDTERMINATOR = '','',ROWTERMINATOR = ''\n'')'
    exec sp_executesql @myTableSQL
    end
    GO

or

  --Just the 'meat' this time:
  Declare @ProductsSQL nvarchar(max);
  SET @ProductsSQL = 'update ' + @table + ' set stats_completed = 0'
  exec sp_executesql @ProductsSQL

Note: In each of the above references, @fileURL and/or @table are varchars used as input to the SP

It seems to me that, by use of a "dynamic table," the coder would lose the benefit of Stored Procedure as the SQL engine couldn't pre-interpret or predict the transaction. My own limited testing has shown nominal if any improvement in performance using this method over executing the SQL as a command rather than a SP.

Question(s) What are the specific benefits of using these "unpredictable" Stored Procedures instead of calling for execution of the SQL as a command (C#:NonQuery())? Do any benefits remain when calling a stored procedure that uses dynamic SQL? Essentially - is there any difference between calling a SP in this manner and using NonQuery()/Standard SQL command?

Mind you, I'm not necessarily asking which one is "better," or seeking opinions. I'm asking anyone who knows the inner workings of SQL what the specific advantages/disadvantages may be.

Thank you very much for your time and in advance for any insight or information you can provide.

Shannon Holsinger
  • 2,293
  • 1
  • 15
  • 21
  • your not using stored procedures in you examples. You are using dynamic sql wich is something else – GuidoG Sep 19 '16 at 11:26
  • Yes, I am. Sorry for the confusion - let me increase the verbosity of the references. – Shannon Holsinger Sep 19 '16 at 11:28
  • Okay. Understood. That makes sense, but it is stored as a SP in SQL and executed as a SP. So, I call it "An SP using Dynamic SQL?" Please don't read sarcasm into this - I'm genuinely asking and will revise the terminology in my question if necessary – Shannon Holsinger Sep 19 '16 at 11:35
  • Okay now I understand. There is no benefit in doing this as opposed to just sending the command. Stored procedures are great for programming lots of DML statements and logic on the database and because they are compiled objects the database can gain performance and you have it all automatic in the same transaction. The first benefit is in my opinion completely gone when you do it like this – GuidoG Sep 19 '16 at 11:38
  • Why do you assume it's about performance? `Import_Correlation_Csv` simply encapsulates the bulk insert logic (and the file format). Stored procedures have other benefits -- for example, they allow you to manage permissions based on operations rather than objects. They also add a layer where the enterprising DBA can tinker without requiring all applications to be rewritten. – Jeroen Mostert Sep 19 '16 at 11:38
  • Thanks, GuidoG - that's what I was thinking as well. @jeroen - that was the "meat" of why I asked this question in the first place. Thank you!! – Shannon Holsinger Sep 19 '16 at 11:40
  • I was probably wrong in stating "performance," as I am curious about the benefits/costs/differences between the two, be they performance-based or otherwise. – Shannon Holsinger Sep 19 '16 at 11:41
  • 1
    @GuidoG: "and you have it all automatic in the same transaction". Statements in a stored procedure do *not* execute in one transaction. You would still have to add the appropriate `BEGIN TRANSACTION`/`COMMIT` yourself (or have the client side start one). Maybe this is what you meant, but I feel it needs explicit pointing out since it's a common misconception -- stored procedures aren't atomic blocks. (Except the newer in-memory native stored procedures that *are* atomic blocks, per the explicit `ATOMIC` keyword.) – Jeroen Mostert Sep 19 '16 at 11:42
  • By the way, @JeroenMostert, I changed the title of my post from "Performance" to "Cost:Benefit." I appreciate your input. – Shannon Holsinger Sep 19 '16 at 11:43
  • @JeroenMostert Yes offcourse that is what i meant. Without a stored proc you have to start a transaction and do your commands in the same transaction and than commit or rollback. With a stored procedure you have to do the same but you only need to put one command in your start / commit code in stead of several. – GuidoG Sep 19 '16 at 12:00

3 Answers3

1

Well, first and foremost the examples you posted are SQL Injection vectors, both of them. When building dynamic SQL special care needs to be taken to properly handle input:

 SET @myTableSQL = 'BULK INSERT EOD_Stock_Correlations FROM '+ QUOTENAME(@fileURL, '''') +...

and

 SET @ProductsSQL = 'update ' + QUOTENAME(@table) + ' set stats_completed = 0'

Next, I urge you to read The Curse and Blessings of Dynamic SQL and Dynamic Search Conditions in T‑SQL.

Do any benefits remain when calling a stored procedure that uses dynamic SQL?

Some cases these are unavoidable, and sometimes there are significant performance benefits, specially in dynamic search conditions. For the exmaples you posted, in BULK INSERT statement syntax the file must be a literal, it cannot be a parameter. Therefore dynamic SQL is required. Whether this occurs on the client (ie. when you create the SqlCommand text) or on the server (like in the example) is hard to draw a line which is better. If the example you posted would have been correct (ie. use proper QUOTENAME) then I would say 'look, a careful DBA make sure those inexperienced devs don't shoot themselves in the foot and introduce SQL injection in the client code'. As is, the SQL injection exists in the SP so really it adds not much value.

The second example (UPDATE... @table) I consider it a counter example, a code smell of bad practices. It shows that the application schema is potentially unknown and someone simply added too many layers of abstraction and too little value. Again, the SQL injection potential is clear and plainly ignored.

In conclusion: read those two links. Whenever you deal with dynamic, always consider SQL injection risks. Unless explicitly handled, dynamic SQL (both client side or server side) is almost always prone to SQL injection (as your two examples both show it).

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • Gotcha - thanks for the input! I agree that this has a bad smell. It's code I'm "taking over" and I can't figure out why it's there. Injection isn't a risk on this application as it has no front-end, but before I go changing things, I thought I'd ask for input as to why these might've been there to begin with. Again, thank you for your input! – Shannon Holsinger Sep 19 '16 at 11:47
  • Don't underestimate SQL injection risks on back-end. First, you never know where the code ends up 3 years from now. But even now the code can be used to mount an attack from a company insider doing a potential privilege escalation attack. Is *sooo* much easier to just fix it. – Remus Rusanu Sep 19 '16 at 11:50
  • Oh you betcha - I'll fix it. I suppose I'm trying to stand up a little bit for previous developer. I need to get confirmation bias out of my head. Thanks! – Shannon Holsinger Sep 19 '16 at 11:52
  • And is not only intentional SQL Injection attacks. Is also also a matter of simple correctness. Your app right now will not work if a valid `@table` value is passed in for a table that contains a space in the name... – Remus Rusanu Sep 19 '16 at 11:56
  • To be fair to the original developer, this is an admin task performed on known tables with data that has already been filtered numerous times - but I do agree with you. – Shannon Holsinger Sep 19 '16 at 12:00
  • @RemusRusanu Please do you think you could take a look at this question : http://stackoverflow.com/questions/40197865/mssql-is-there-any-performance-penalty-for-wrapping-a-select-query-in-a-transa – eddy Oct 22 '16 at 23:34
0

Generally, dynamic sql is the same sql but executed in a separate thread. It incurs quite negligible overhead. In most cases you'll notice no perfomance difference. You may wish to read http://www.sommarskog.se/dynamic_sql.html for more details.

Serg
  • 22,285
  • 5
  • 21
  • 48
  • Might also look at bind parameters: http://use-the-index-luke.com/sql/where-clause/bind-parameters – jleach Sep 19 '16 at 11:44
  • Thanks, Serg! I'll look into those things. I hate changing someone else's code before I understand why they did what they did and why my change makes it better. – Shannon Holsinger Sep 19 '16 at 11:51
0

First of all, this statement "using Stored Procedures in SQL allows for more efficient operation because the interpreter can predict the nature of the transaction and optimize it before it is called" is not true. Optimizer optimizes batches of statements in the same way, stored proc or not. There are differences between parameterized vs non-parameterized queries, of course, but it's something else.

True reasons for using stored procedures are security and maintainability (ease of refactoring, that is).

Furthermore, dynamic code inside a stored procedure is optimized separately and executed in another context, so there's little difference between this and constructing client-side T-SQL.

And I have to add that using variables for tables is a big code smell (unless it's some administrative task in question).

dean
  • 9,960
  • 2
  • 25
  • 26
  • Thank you, Dean - I very much appreciate your input and those tid-bits of knowledge. This is exactly why I asked the question in the first place. I'm kind of perplexed as to why the original code exists as it is - thus the question. – Shannon Holsinger Sep 19 '16 at 11:49