如何为每个执行SP并且联合所有结果?

时间:2013-06-03 14:58:30

标签: sql-server tsql stored-procedures for-loop union

我有一张包含某些记录的表格,我们称之为优先级表格。对于此表中的每条记录,我需要执行一个名为GetProductsBasedOnPriorityRecord的存储过程,该过程返回 Product 表中的记录。 所有这些结果都需要作为一个UNION返回,没有重复。

我可以编写以下C#pseodo代码,但我不知道如何在SQL中执行此操作:

//DECLARE resultVariable
var products = new List<Product>();

//SELECT * FROM Priority and FOREACH over this
foreach(var prio in Priority) {
    //EXEC GetProductsBasedOnPriorityRecord and UNION this on the resultVariable
    products.Union(GetProductsBasedOnPriorityRecord(prio));
}

//RETURN resultVariable
return products;

3 个答案:

答案 0 :(得分:3)

如果您需要在相对较好的情况下执行它,则不应该在循环中编写SQL代码。但这就是我在这种情况下会做的事情。

-- build some variables
declare @prio           table (prio varchar(100) not null)
declare @singlePrio     varchar(50)
declare @sqlcmd         varchar(50)

-- assuming that the output of the stored procedure is just a table of INTs
declare @output         table (outputID int not null)

-- build the list to loop over
insert into @prio (prio)
select * from [Priority]

while exists (select 1 from @prio)
begin
    select @singlePrio = (select top 1 prio from @prio)
    --
    insert into @output exec GetProductsBasedOnPriorityRecord @singlePrio
    --
    delete from @prio where prio = @singlePrio
end

-- using distinct because you want a 'union' but didnt say 'union all'
select distinct outputID from @output 

答案 1 :(得分:1)

你应该能够用光标做到这一点。这并不总是最好的方式。我假设你被迫使用现有的存储过程。

示例表

CREATE TABLE [dbo].[Products](
    [ProductID] [int] IDENTITY(1,1) NOT NULL,
    [ProductName] [nchar](10) NULL,
    [PriorityID] [int] NULL)

CREATE TABLE [dbo].[Priority](
    [PriorityID] [int] IDENTITY(1,1) NOT NULL,
    [PriorityCode] [nchar](10) NULL)

(使用PK等)。

示例存储过程:

ALTER PROCEDURE [dbo].[GetProductsBasedOnPriorityRecord] 
    -- Add the parameters for the stored procedure here
    @PriorityID int = 0
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT * FROM Products WHERE PriorityID = @PriorityID
END

然后是这样的:

DECLARE @PriorityID INT
DECLARE @table TABLE (ProductID INT, ProductName NCHAR(10), PriorityID INT)
DECLARE cur CURSOR FOR SELECT PriorityID FROM Priority
OPEN cur
FETCH NEXT FROM cur INTO @PriorityID

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO @table EXEC GetProductsBasedOnPriorityRecord @PriorityID
    FETCH NEXT FROM cur INTO @PriorityID
END

CLOSE cur
DEALLOCATE cur

SELECT DISTINCT * FROM @table

当然这会对你的表做出一些假设。此外(当然)像这样的合成例子实际上显示了一种非常简单的做事的冗长方式。

答案 2 :(得分:1)

试试这个 -

DECLARE @SQL NVARCHAR(MAX)

IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
    DROP TABLE #temp

CREATE TABLE #temp (outputID INT NOT NULL) 

SELECT @SQL = (
    SELECT CHAR(13) + '
        INSERT INTO #temp(outputID) 
        EXEC dbo.GetProductsBasedOnPriorityRecord ''' 
            + prio + ''''
    FROM dbo.[Priority]
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')

PRINT @SQL

EXEC sys.sp_executesql @SQL

SELECT DISTINCT outputID 
FROM #temp