You probably know how to concatenate multiple values from multiple rows of a table. This technique is useful when you need to provide multiple values in a single variable. For example, when you're calling a stored procedure, you might need to pass in multiple values in a single parameter, as Listing 2 shows.
However, when you use this type of concatenation, you're limited to 8,000 characters, which can be problematic in several ways. First, you might need many local variables to hold all the values in a table. Then, there's the problem of trying to figure out which variables are full and which variables still have room for more values. Another problem can occur when a table value is too large for a local variable. In such cases, you might need to split a table value across multiple local variables. You might even be forced into some kind of cursor or looping structure to address this particular problem.
If you've experienced any of these concatenation woes, have I got the solution for you: dbo.fn_AddToBuffer. Although dbo .fn_AddToBuffer won't eliminate unwanted belly fat or make you rich quick, it will eliminate concatenation problems and make your job easier because it uses any number of local variables as a buffer to work around the 8,000-character limitation. As Listing 3 shows, using this user-defined function (UDF) requires a bit more typing, but you end up with an elegant solution that's simple to read and works well. This UDF works on SQL Server 2005 and SQL Server 2000.
Here's how you use dbo.fn_AddToBuffer. The UDF needs three parameters. The first parameter is a varchar(8000) variable that represents the value you want to add to the "buffer" (i.e., the set of local variables). The second parameter is an integer that represents the starting buffer position for each local variable. The third parameter is an integer that represents the total buffer length prior to adding the current value. The UDF will evaluate just how many characters and which portion of the input value should be parsed and returned for each local buffer variable.
You can use dbo.fn_AddToBuffer for any number of local variables. In each local variable, it uses every available character position. I've found this function most useful when the called stored procedure performs dynamic SQL execution. When you use the EXEC statement for dynamic SQL, there's no practical limitation to how long the statement can be, so concatenating multiple 8,000-character strings together isn't a problem.
For example, suppose you have a SELECT statement that includes an IN clause. You can provide the IN values as parameters so that the dynamic SQL statement looks something like
EXEC (‘SELECT * FROM InvoiceDetails WHERE InvoiceNumber IN (‘ + @x1 + @x2 + @x3 + @x4 + @x5 + ‘)' "
In the example in Listing 3, the values need to be delimited by a space, so I added a single space to the end of each InvoiceNumber. However, in other situations, you might not need a delimiter or you might need a different delimiter. Your values might not even be characters (e.g., they're INT values), or you might need your values properly quoted. You can determine what you need in the SELECT LIST of the subquery by using the CAST or CONVERT operators and adding your preferred delimiter and/or quotation marks.
If you often need to provide multiple values in a variable but find a single variable too limiting, give dbo.fn_AddToBuffer a try. This UDF isn't available at any store, and you won't find it advertised on TV. You can only find it on SQL Server Magazine's Web site.