Avoid dynamic SQL

  • Greeetings all,

    Sample data and question to follow.

    CREATE TABLE #Accounts

    (

    Account varchar (10)

    )

    INSERT INTO #Accounts

    SELECT 'Account1' UNION

    SELECT 'Account2' UNION

    SELECT 'Account3' UNION

    SELECT 'Account4' UNION

    SELECT 'Account5'

    CREATE TABLE #AccountGroups

    (

    AccountGroup varchar (10)

    )

    INSERT INTO #AccountGroups

    SELECT 'Group1' UNION

    SELECT 'Group2 '

    CREATE TABLE #AccountGroupMembers

    (

    AccountGroup varchar (10),

    Account varchar (10)

    )

    INSERT INTO #AccountGroupMembers

    SELECT 'Group1','Account1' UNION

    SELECT 'Group1','Account2' UNION

    SELECT 'Group2','Account3' UNION

    SELECT 'Group2','Account4' UNION

    SELECT 'Group2','Account5'

    CREATE TABLE #Sales

    (

    Account varchar (10),

    AmountSold int

    )

    INSERT INTO #Sales

    SELECT 'Account1', 3 UNION

    SELECT 'Account1', 4 UNION

    SELECT 'Account2', 6 UNION

    SELECT 'Account2', 12 UNION

    SELECT 'Account2', 1 UNION

    SELECT 'Account4', 4 UNION

    SELECT 'Account4', 9 UNION

    SELECT 'Account5', 3

    SELECT * FROM #Accounts

    SELECT * FROM #AccountGroups

    SELECT * FROM #AccountGroupMembers

    SELECT * FROM #Sales

    --The parameter passed to my procedure can either be a group or an account

    DECLARE @param1 varchar (15)

    SET @param1 = 'Account1' --test for account

    --SET @param1 = 'Group1' --test for group

    --I can then determine whether the parameter is a group or an account

    --An account can not have the same name as a group and vice versa

    DECLARE @Account_or_Group varchar(7)

    IF EXISTS

    (

    SELECT Account FROM #Accounts WHERE Account = @param1

    )

    BEGIN

    SET @Account_or_Group = 'Account'

    END

    ELSE

    BEGIN

    SET @Account_or_Group = 'Group'

    END

    PRINT @Account_or_Group

    --Based on the @Account_or_Group I sum sales

    IF @Account_or_Group = 'Account'

    BEGIN

    SELECT SUM(AmountSold) FROM #Sales WHERE Account = @param1

    END

    ELSE

    BEGIN

    SELECT SUM(AmountSold) FROM #Sales

    WHERE Account IN

    (

    SELECT Account FROM #AccountGroupMembers WHERE AccountGroup = @param1

    )

    END

    DROP TABLE #Accounts

    DROP TABLE #AccountGroups

    DROP TABLE #AccountGroupMembers

    DROP TABLE #Sales

    My two sales summary statements are actually a lot more complicated. My goal is to have one SELECT statement to maintain. So I want to avoid the "If @Account_or_Group = x Do this else do this" method. I also do not want to use dynamic SQL.

    Possible?

  • You could simplify the query *somewhat* by using a couple of conditionals in the WHERE clause (which would at least leave the SELECT portion of the query common to both cases):

    WHERE ((@Account_or_Group = 'Account') and (Account = @param1))

    OR

    (Account IN (SELECT Account FROM #AccountGroupMembers WHERE AccountGroup = @param1))

    Not sure if that really helps your cause any....

    Rob Schripsema

    Rob Schripsema
    Propack, Inc.

  • Agreed, the WHERE clause can combine both, but also you can do away with the @Account_Or_Group variable and associated lookup code.

    You said the two lookups are mutually exclusive, so there is no real need to worry about them....

    SELECT SUM(AmountSold) FROM #Sales WHERE Account = @param1

    OR Account IN

    (

    SELECT Account FROM #AccountGroupMembers WHERE AccountGroup = @param1

    )

    With your test data, because you have the same number of records in tables #Accounts and #AccountGroupMembers, both forms of the queries will perform about the same - your form has to query #Accounts to see if it is an Account lookup - this form queries #AccountGroupMembers, but not #Accounts. Both have to read #Sales.

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • Heh... poor ol' dynamic SQL... nobody loves it anymore.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden (2/26/2010)


    Heh... poor ol' dynamic SQL... nobody loves it anymore.

    It's sad, when the cure is worse than the disease.

    Oh well, I'll be killing swine and birds all weekend for the CDC... 😀

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • emily:

    Why do you want to cram two different functional tasks into one procedure? Thats been bad design in software development for over forty years. This obviously belongs in two different routines and that's how you should write it.

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • ...

    For better, quicker answers on T-SQL questions, click on the following...
    http://www.sqlservercentral.com/articles/Best+Practices/61537/

    For better answers on performance questions, click on the following...
    http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Welsh Corgi (2/26/2010)


    I agree with the distinguished Forum Members with respect to the use of Dynamic SQL.

    There are many reasons to avoid this. If you want SQL Injection and put your Business at risk then SQL Injection is for you.

    This practice is reckless and any responsible DBA would not allow it.:w00t:

    Only if you're silly about it. SQL Injection is very easy to avoid. Responsible DBA's know how to get all the benefits of dynamic SQL without the risks.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden (2/26/2010)


    Welsh Corgi (2/26/2010)


    I agree with the distinguished Forum Members with respect to the use of Dynamic SQL.

    There are many reasons to avoid this. If you want SQL Injection and put your Business at risk then SQL Injection is for you.

    This practice is reckless and any responsible DBA would not allow it.:w00t:

    Only if you're silly about it. SQL Injection is very easy to avoid. Responsible DBA's know how to get all the benefits of dynamic SQL without the risks.

    dang! Ya beat me to it Jeff.

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • ...

    For better, quicker answers on T-SQL questions, click on the following...
    http://www.sqlservercentral.com/articles/Best+Practices/61537/

    For better answers on performance questions, click on the following...
    http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Welsh Corgi (2/26/2010)


    I accept your critisisim.

    There are many ways to exploit Dynamic SQL and this is well documented.

    In my humble;e opinion you have to take steps to minimize the risk whether it be in SQL Server or Oracle.

    But if you could please provide you solution to this security risk it would be greatly appreciated.

    You have to be careful when you use Dynamic SQL but I appreciate your criticism but consider of offering a solution or recommendation when doing so.

    Perhaps you could provide a document that outlines the do's and dont's with respect to the security risk associated with dynamic SQL?

    Do you have any white papers on this subject material? If so please share when you criticize.

    I appreciate a positive constructive dialogue.

    I did not intend to be negative.

    The comment that you could not wait to jump in suggest that your motives are not positive;but who am I to judge.

    Thank you for your feedback and providing your perspective on this issue:-)

    Regards,

    WC

    It wasn't a criticism of you nor was I trying to be negative. And a simple Google search on the subject will give you much more than I could write in a single post.

    Don't throw away a perfectly good tool just because you get sparks in your eyes... wear goggles. 😉

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • ...

    For better, quicker answers on T-SQL questions, click on the following...
    http://www.sqlservercentral.com/articles/Best+Practices/61537/

    For better answers on performance questions, click on the following...
    http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • ...

    For better, quicker answers on T-SQL questions, click on the following...
    http://www.sqlservercentral.com/articles/Best+Practices/61537/

    For better answers on performance questions, click on the following...
    http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Welsh Corgi (2/26/2010)


    OK, Jeff & Barry you point is

    well taken. I appreciate critisism but when you present a problem you should provide a solution...

    I'm good at using goggle but there is a lot of misinformation out there what do you recommend?

    What are your best practices?

    I have used Dynamic SQL and if you take precautions you can protect yourself from vulnerabilities from using Dynamic SQL?

    Please share with me you wealth of knowledge on this subject matter.

    Regards,

    WC

    You didn't provide any links to white papers and the like when you first said the use of dynamic SQL was "reckless". Google it like anyone else would. You've already found all the negative stuff... now look for the postive stuff.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • RBarryYoung (2/26/2010)


    Jeff Moden (2/26/2010)


    Welsh Corgi (2/26/2010)


    I agree with the distinguished Forum Members with respect to the use of Dynamic SQL.

    There are many reasons to avoid this. If you want SQL Injection and put your Business at risk then SQL Injection is for you.

    This practice is reckless and any responsible DBA would not allow it.:w00t:

    Only if you're silly about it. SQL Injection is very easy to avoid. Responsible DBA's know how to get all the benefits of dynamic SQL without the risks.

    dang! Ya beat me to it Jeff.

    Heh... for a change... :hehe:

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Viewing 15 posts - 1 through 15 (of 79 total)

    You must be logged in to reply to this topic. Login to reply