Select columns dynamically

  • Jeff Moden (3/6/2012)


    ...

    That's precisely what I was going to tell Eugene... the use of sp_ExecuteSQL doesn't necessarily mean that it prevents SQL Injection when someone uses it incorrectly. If you concatenate table or column names from user input, even if you use sp_ExecuteSQL, you're opening yourself up for SQL Injection.

    That's precisely what I said in my post! sp_executeSQL should be used with parameters, not as simple contcatination from input.

    Ok, it may be wasn't too clear.

    But the main point is: Properly used Dynamic SQL doesn't constitute a security risk 😉

    At the end if the table and column's names are passed as input parameters, they can be validated against sys.tables/columns isn't it?

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Yes Jeff,

    I dislike to make dynamic SQL like that.

    (SQL Inject prone AND no statistics AND recompilations...)

    Is it possible to use the @tableName and @columnName in a safe way with sp_executeSQL?

    Anyway.

    If I have to use something like that in an app I can use some tricks.

    A good one for this case is validate the variables with regular expressions.

  • jcb (3/7/2012)


    ...

    Is it possible to use the @tableName and @columnName in a safe way with sp_executeSQL?

    ...

    Simples:

    IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = @tableName )

    BEGIN

    RAISERROR ...

    END

    IF NOT EXISTS(SELECT 1 FROM sys.columns WHERE name = @columnName )

    BEGIN

    RAISERROR ...

    END

    -- build SQL

    ...

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thanks Eugene a nice sugestion!:w00t:

    But I want to know if there any way to trick SP_ExecSQL to pass a object name as a varible do a dynamic SQL as a parameter.

  • jcb (3/7/2012)


    Thanks Eugene a nice sugestion!:w00t:

    But I want to know if there any way to trick SP_ExecSQL to pass a object name as a varible do a dynamic SQL as a parameter.

    What's is wrong with my suggestion?

    It's not possible to do what you're asking for, but what difference would it make if it could be possible?

    The problem with SQL Injection is happen when you concatinate non-validatable input parameters into SQL string. For example if input parameter is the search text, it's impossible to validate it, as it may well be an SQL your are trying to search (if your searchable table holds some SQL). TableName and ColumnName (or lists of them) are easely validated, therefore do not constitute the SQL injection risk.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • No problem with your sugestion.

    It's realy a nice one.

    I just wondering if there are some trick to pass objects names as parameters to a dynamic SQL.

    As fair I know its not possible so if there are any obscure method I want to learn.

  • This works without leaving you open to SQL injection.

    DECLARE @TableName AS NVARCHAR(20) = 'work', @sql AS NVARCHAR(MAX);

    WITH p1 AS (

    SELECT sqlStmt, ROW_NUMBER() OVER(ORDER BY ord, (SELECT NULL)) AS rn, col, colname

    FROM (SELECT 'SELECT COUNT(*) AS [all]' AS sqlStmt, 1 AS ord, '[all]' AS col, NULL AS colname

    UNION ALL

    SELECT sqlStmt + ' AS ' + QUOTENAME(ROW_NUMBER() OVER(ORDER BY (SELECT NULL))), 2, QUOTENAME(ROW_NUMBER() OVER(ORDER BY (SELECT NULL))),

    colname

    FROM (SELECT ', ' + CHAR(13) + CHAR(10) + 'COUNT('+name+')', name

    FROM sys.columns

    WHERE OBJECT_NAME(object_id) = @TableName) a(sqlStmt,colname)

    UNION ALL

    SELECT CHAR(13) + CHAR(10) + 'FROM ' + QUOTENAME(name), 3, NULL, NULL

    FROM sys.tables

    WHERE OBJECT_NAME(object_id) = @TableName) a),

    p2(sqlStmt) AS (

    SELECT 'DECLARE @sql AS NVARCHAR(MAX);' + CHAR(13) + CHAR(10)

    UNION ALL

    SELECT 'SELECT @sql = ' + CHAR(39) + 'SELECT '+ CHAR(39) +' +'+'STUFF('

    UNION ALL

    SELECT 'CASE WHEN '+col+' > 0 THEN '+CHAR(39)+','+CHAR(39)+' + CHAR(13) + CHAR(10) + '+CHAR(39)+colname+CHAR(39)+' ELSE '+CHAR(39)+CHAR(39)+' END +'

    FROM p1

    WHERE col IS NOT NULL AND col <> '[all]'

    UNION ALL

    SELECT CHAR(39)+CHAR(39)+',1,3,'+CHAR(39)+CHAR(39)+') + CHAR(13) + CHAR(10) + ' + CHAR(39) + 'FROM ' +

    QUOTENAME(name) + CHAR(39) + CHAR(13) + CHAR(10) + 'FROM ('

    FROM sys.tables

    WHERE OBJECT_NAME(object_id) = @TableName

    UNION ALL

    SELECT sqlStmt

    FROM p1

    UNION ALL

    SELECT ')a;'

    UNION ALL

    SELECT CHAR(13)+CHAR(10) + 'EXECUTE sp_executesql @sql;')

    SELECT @sql = COALESCE(@SQL,'') + sqlStmt

    FROM p2;

    EXECUTE sp_executesql @sql;


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Gentlemen, looks like you have a lot of free time...

    Can some one come up with the reasonable idea for doing it in the first place?

    I do not beleive it's a good design at all! Recordsets are already dynamic enough to contain variable number of rows. There will be hard to find the reason why would you want to have it with variant number of columns.

    Don't try to tell me that the Object's in OOD may be implemented to have optional properties - will not play for SQL... :hehe:

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (3/7/2012)


    Gentlemen, looks like you have a lot of free time...

    Can some one come up with the reasonable idea for doing it in the first place?

    I do not beleive it's a good design at all! Recordsets are already dynamic enough to contain variable number of rows. There will be hard to find the reason why would you want to have it with variant number of columns.

    Don't try to tell me that the Object's in OOD may be implemented to have optional properties - will not play for SQL... :hehe:

    In my business, there is no reason for doing this.

    In the OPs? I wouldn't know, I'm not employed by his company. The original question was reasonably interesting and the dynamic SQL for any table was an entertaining intellectual challenge.


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Cadavre (3/7/2012)


    ... The original question was reasonably interesting and the dynamic SQL for any table was an entertaining intellectual challenge.

    Have you heard about solving SUDOKU in T-SQL?

    http://www.sqlservercentral.com/scripts/67539/

    I guess the next challenge will be: "Creating 3D-Animation with T-SQL" :hehe:

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (3/7/2012)


    Cadavre (3/7/2012)


    ... The original question was reasonably interesting and the dynamic SQL for any table was an entertaining intellectual challenge.

    Have you heard about solving SUDOKU in T-SQL?

    http://www.sqlservercentral.com/scripts/67539/

    I guess the next challenge will be: "Creating 3D-Animation with T-SQL" :hehe:

    *Ahem* --> http://www.sqlservercentral.com/Forums/FindPost1164676.aspx


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Only assefam can tell but

    Sometimes bizarre or non trivial requirements arrive at my desk and sometimes they are valid.

    Sometimes I cannot tell they are valid but there are cases where the client/big boss dont accept a NO even if you have a good and valid point to not do it that way.

    If a requirement "dont show a columns if it never got a not null value" I can:

    a) Check if is feasible to drop that columns;

    b) Get a list of invalid columns ahead and turns they not visible at the report (at app level);

    c) Code it;

    d) Yell to the client it is bad design.

    Maybe I can ask Steve to make it the next QotD.

    😀

  • jcb (3/7/2012)


    Sometimes bizarre or non trivial requirements arrive at my desk and sometimes they are valid.

    And sometimes they are just misunderstood.

    [..]

    a) Check if is feasible to drop that columns;

    b) Get a list of invalid columns ahead and turns they not visible at the report (at app level);

    c) Code it;

    c) Yell to the client it is bad design.

    [..]

    I'd bet that your (b) is actually the right answer... because it was what the higher-level boss/client really wanted; s/he just expressed it incoherently.

    Note that, if we explore the request directly with the user, to find this out properly, this is not the same as your second (c), "Yell to the client it is bad design"!

    Which is not to say that I don't *also* perform your second (c) pretty frequently these days, after we've had a meeting of the minds to clarify the requirement. My version of your second (c) is usually as follows: "Don't tell me how to implement! That's *my* job! Yours is to explain what you want to see, not how you want to make it happen!"

    It's really hard to get somebody to focus on the original business need sometimes. Once they do, you usually find out that the requirement isn't outré at all. Then you can go back and explain to the app-level developer (in this case) what needs to happen to satisfy it, which is often (and probably, in this case) laughably trivial.

    One reason it's really hard: the OP may have been dealing with a PM or BA rather than the original user/requestor of the feature. Maybe the OP doesn't have access to the original person, and can't raise the question directly. Now s/he has to convince (and, usually, to coach) the PM or BA to do *their* job properly <shrug> instead of just repeating the request like a robot, without thinking it through.

    >L<

  • Lisa Slater Nicholls (3/7/2012)


    jcb (3/7/2012)


    Sometimes bizarre or non trivial requirements arrive at my desk and sometimes they are valid.

    And sometimes they are just misunderstood.

    [..]

    a) Check if is feasible to drop that columns;

    b) Get a list of invalid columns ahead and turns they not visible at the report (at app level);

    c) Code it;

    c) Yell to the client it is bad design.

    [..]

    I'd bet that your (b) is actually the right answer... because it was what the higher-level boss/client really wanted; s/he just expressed it incoherently.

    Note that, if we explore the request directly with the user, to find this out properly, this is not the same as your second (c), "Yell to the client it is bad design"!

    Which is not to say that I don't *also* perform your second (c) pretty frequently these days, after we've had a meeting of the minds to clarify the requirement. My version of your second (c) is usually as follows: "Don't tell me how to implement! That's *my* job! Yours is to explain what you want to see, not how you want to make it happen!"

    It's really hard to get somebody to focus on the original business need sometimes. Once they do, you usually find out that the requirement isn't outré at all. Then you can go back and explain to the app-level developer (in this case) what needs to happen to satisfy it, which is often (and probably, in this case) laughably trivial.

    One reason it's really hard: the OP may have been dealing with a PM or BA rather than the original user/requestor of the feature. Maybe the OP doesn't have access to the original person, and can't raise the question directly. Now s/he has to convince (and, usually, to coach) the PM or BA to do *their* job properly <shrug> instead of just repeating the request like a robot, without thinking it through.

    >L<

    That is called "broken phone" game played by kids in Russia.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (3/7/2012)


    That is called "broken phone" game played by kids in Russia.

    And "Chinese whispers" in at least some parts of New Zealand, I have no idea why.

    Personally it always makes me think of A A Milne. I can't tell you how many times I have hummed to myself "The king asked the queen and the queen asked the dairymaid..." when given an assignment third-hand. Ref: http://www.poemhunter.com/poem/the-king-s-breakfast/ Not exact analogy, but still.

    FWIW: the degradation of signal doesn't even take *one* degree of separation. It only takes one person who doesn't like to think hard.

    >L<

Viewing 15 posts - 31 through 45 (of 49 total)

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