0

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

我能够编写以下 C# 伪代码,但我不知道如何在 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;
4

3 回答 3

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 
于 2013-06-03T16:40:52.527 回答
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

当然,这会对您的表格做出一些假设。另外(当然)像这样的综合示例实际上显示了一种非常简单的方法。

于 2013-06-03T16:43:34.420 回答
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 
于 2013-06-04T05:57:48.077 回答