我已经基于通过您的存储过程传递的变量构建了一个动态查询。我的文字被评论为正在发生的事情。
首先,您需要一个表值函数来拆分您的参数,以便其中列出的每个公司都是结果返回表中的一行。下面是一个函数,你需要在你的数据库上创建它:
CREATE FUNCTION [dbo].[ufnSplit]
(
@string VARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @output TABLE(Item VARCHAR(MAX)
)
BEGIN
DECLARE @start INT, @end INT
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (Item)
VALUES(SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
END
RETURN
END
接下来在存储过程中,我们使用此函数将您的参数拆分为行,放到一个名为#Companies 的临时表中。然后,我们使用循环遍历#Companies 来创建您的UNION 查询(或者,如果只有一个值,则不创建)。再一次,我对我正在做的事情发表了很多评论。
USE [DatabaseName]
GO
CREATE PROCEDURE uspLevelReports
@param VARCHAR(MAX)
/* Use this for testing your parameters:
EXEC uspLevelReports @param = 'A,B,D'
*/
AS
BEGIN TRY
IF OBJECT_ID('tempdb..#Companies') IS NOT NULL
DROP TABLE #Companies
-- use the split function to put each company into a table, and assign it a row number (necessary for the loop below)
SELECT
Item
,ROW_NUMBER() OVER(ORDER BY Item ASC) AS RowNo
INTO #Companies
FROM dbo.ufnSplit(@param,',')
-- Select below is for testing so you can see the effect:
-- SELECT * FROM #Companies
-- Create the basic query here, with the company suffix
DECLARE @sql NVARCHAR(4000) = 'SELECT * From tempdb..##Level'
-- Start to loop through #Companies, for each row no higher than 1, a union will be added
-- First, tell the loop where to start and end:
DECLARE @RowNo INT = 1 -- Your starting RowNo, should always be 1 so won't do a MIN() here
DECLARE @MaxNo INT = ( -- The highest RowNo in #Companies
SELECT
MAX(RowNo)
FROM #Companies
)
DECLARE @originalSQL NVARCHAR(4000) = @sql -- @Sql will be modified in the loop but we still need the original form to keep adding to each union if one is there
WHILE @RowNo <= @MaxNo -- we will increase the value of @RowNo by 1 each time,the loop will break when @RowNo gets higher than @MaxNo
BEGIN
-- Find the company that corresponds to the @RowNo value in #Companies and add it to a variable:
DECLARE @suffix VARCHAR(100) = (
SELECT
Item
FROM #Companies
WHERE RowNo = @RowNo)
IF @RowNo = @MaxNo -- If statement for the final Item in #Companies, this stops us adding UNION where we've finished the query
SET @sql += @suffix
ELSE
SET @sql += @suffix + ' UNION ' + @originalSQL;
SET @RowNo += 1 -- Add one to move to next RowNo in #Companies
PRINT @sql -- This is for testing so you can see in Messages how the query is being built each loop
END
PRINT 'Final query: ' + @sql -- This is for testing so you can see in Messages what your final query is
-- Create your level all table
IF OBJECT_ID('tempdb..##LevelAll') IS NOT NULL
DROP TABLE ##LevelAll
-- You need to create your ##LevelAll table with all the columns needed, so amend them with their datatypes below mine is just for example:
CREATE TABLE ##LevelAll(
Company CHAR(1)
,value INT
)
--- insert into your level all table
INSERT INTO ##LevelAll
-- by executing the statement inside your string variable
exec sp_executesql @sql
-- publish the results
SELECT * FROM ##LevelAll
END TRY
BEGIN CATCH
-- Your error trapping variables
END CATCH