• I have learned to detest code that builds dynamic SQL by repeated concatenation, especially with char functions for line breaks and tabs.  A complex statement is difficult to read when it is pieced together with a bunch of CHAR, CAST, and CONVERT fuctions.

    SQL is perfectly happy to interpret multiline strings with all line breaks and tabs included.  I create a template of the complete SQL statement with tags for all variable parts, then use REPLACE functions to handle the modifications.  This is especially useful when one variation requires changes in the field list, tables, and where clause.  Another advantage of REPLACE is it can do implicit conversions to string of integers and avoid '...' + CAST(x AS VARCHAR) + '...'.

    -- Basic template

    SET @sql = 'SELECT fld1, fld2<fields>

          FROM tbl1

          <joins>

          WHERE tbl1.xyz=0 <filters>'

    -- One logical test controls additional fields, joins, and filter clauses

    -- All replaceable tokens are duplicated in the replacement strings to allow further actions

    IF modification1 = 1

          SET @sql = REPLACE(REPLACE(REPLACE(@sql,

          '<fields>', ', fld3, fld4<fields>'),

          '<joins>', 'INNER JOIN tbl2 ON tbl1.fld1 = tbl2.fld1

          <joins>'),

          '<filters>', '

                AND tbl2.pqr IS NOT NULL <filters>')

    -- Further modifications using the same logic

    -- Strip out any remaining tokens

          SET @sql = REPLACE(REPLACE(REPLACE(@sql,

          '<fields>', ''),

          '<joins>', ''),

          '<filters>', '')