简体   繁体   中英

T-SQL Newline String Concatenation For Exec()

So, I've come across a pretty annoying problem with T-SQL... Essentially, in a table, there are several T-SQL statements. I want a stored procedure to efficiently grab these rows and concatenate them to a variable. Then, execute the concatenated lines with EXEC(@TSQL)

The problem is, string concatenation with newlines seem to be stripped when calling Exec...

For example something like:

declare @sql nvarchar(max) = ''
select @sql += char(13) + char(10) + [sql] from [SqlTable]
exec(@sql) -- Won't always do the right thing
print @sql -- Looks good

I don't want to butcher the code with a Cursor, is there any way around this? Thanks!

Edit: Okay, so it looks like the issue is in fact only with the GO statement, for example:

declare @test nvarchar(max) = 'create table #test4(i int) ' + char(10) + char(13) + 'GO' + char(10) + char(13) +'create table #test5(i int)'
exec(@test)

I guess this go will have to go (no pun intended) I just really didn't want to have to try and parse it in fear of special cases blowing up the whole thing.

A select statement without order by is free to return results in any order.

You'd have to specify the order in which your SQL snippets make sense:

select  @sql += char(13) + char(10) + [sql] 
from    [SqlTable]
order by
        SnippetSequenceNr

As @Bort suggested in the comments, if the snippets are stand-alone SQL, you can separate them with a semicolon. Carriage returns, newlines, tabs and spaces are all the same in T-SQL: they're whitespace.

select  @sql += [sql] + ';'
from    [SqlTable]
order by
        SnippetSequenceNr

Just get rid of the GO "statements". As noted by others you also might need to ensure the string is constructing in the correct statement sequence. Using += is probably not the best idea, though I'm not sure about the dynamic sql idea in the first place. It might actually be more appropriate to use a cursor here.

Sam F,

Your method didn't work with FOR XML method of string concatenation (if you wanted to create a "line" delimited list, based on values found in different rows of a table). However, replace the char(13) with SPACE(13), then it works great.

SELECT PackageNote = SUBSTRING((SELECT (SPACE(13) + char(10) + PackageDescription)
FROM POPackageNote PN2
WHERE PN1.PurchaseOrderNumber = PN2.PurchaseOrderNumber
ORDER BY POPackageNoteID, PackageDescription
    FOR XML PATH( '' ) 
    ), 3, 1000 )
FROM POPackageNote PN1
WHERE (PurchaseOrderNumber = @PurchaseOrderNumber)
GROUP BY PurchaseOrderNumber 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM