我如何重写它以避免游标

How do I rewrite this to avoid a cursor

我在 SQL Server 2005 上用 T-SQL 编写了这个函数。我并不像某些人那样反对游标,但我总是看到人们说 99% 的游标都可以重新使用- 为避免使用而编写。

我有这个功能:

CREATE FUNCTION WhereUsed(@ItemID varchar(100))
    RETURNS varchar(MAX)
    AS
    BEGIN
    DECLARE @Items CURSOR
    DECLARE @ParentItem varchar(100)
    DECLARE @WhereUsed varchar(MAX)

    SET @WhereUsed = ''
    SET @Items = CURSOR FAST_FORWARD
        FOR 
        SELECT PST_ParentItemID FROM PST WHERE PST_CompItemID = @ItemID

    OPEN @Items 
    FETCH NEXT FROM @Items 
        INTO @ParentItem
    WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @WhereUsed = @WhereUsed + @ParentItem + ', '
            FETCH NEXT FROM @Items 
                INTO @ParentItem
        END

    IF LEN(@WhereUsed) > 2
        SET @WhereUsed = LEFT(@WhereUsed, LEN(@WhereUsed) - 2)

    RETURN @WhereUsed

    END

这会得到一个part用到的所有item,PST就是ParentStructureTable。思考 BOM(物料清单)

会这样使用:

SELECT Field1, Field2, dbo.WhereUsed(ItemID), Field3 FROM Item

并且 return 是这样的:

S6110-23350-41, 61070-10161-012, R6112-23027-41

不使用游标怎么能做到这一点?

编辑: 样本数据

SELECT PST_ParentItemID FROM PST WHERE PST_CompItemID = @ItemID

可以return

PST_ParentItemID
----------------
S6110-23350-41  
61070-10161-012 
R6112-23027-41  

它确实是一个简单的 select 语句,不确定 DDL 将如何提供帮助,但它是:

CREATE TABLE [dbo].[ProductStructure](
    [PST_RecordID] [uniqueidentifier] NOT NULL,
    [PST_PSH_RecordID] [uniqueidentifier] NOT NULL,
    [PST_IMA_RecordID] [uniqueidentifier] NOT NULL,
    [PST_EffStartDate] [datetime] NOT NULL,
    [PST_EffStopDate] [datetime] NULL,
    [PST_DisplayOrder] [int] NOT NULL CONSTRAINT [DF__ProdStruc__PST_DisplayOrder]  DEFAULT ((0)),
    [PST_Available] [bit] NOT NULL CONSTRAINT [DF__ProdStruc__PST_Available]  DEFAULT ((1)),
    [PST_AddDate] [datetime] NOT NULL CONSTRAINT [DF__ProdStruc__PST_AddDate__192BAC54]  DEFAULT (getdate()),
    [PST_QtyPerAssy] [float] NOT NULL CONSTRAINT [DF__ProdStruc__PST_QtyPerA__1A1FD08D]  DEFAULT ((1)),
    [PST_ScrapQty] [float] NOT NULL CONSTRAINT [DF__ProdStruc__PST_ScrapQt__1B13F4C6]  DEFAULT ((0)),
    [PST_PlanType] [nvarchar](11) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF__ProdStruc__PST_PlanTyp__1C0818FF]  DEFAULT ('MRP'),
    [PST_ScrapPercent] [float] NOT NULL CONSTRAINT [DF__ProdStruc__PST_ScrapPe__1CFC3D38]  DEFAULT ((0)),
    [PST_LeadTimeOffsetDays] [smallint] NOT NULL CONSTRAINT [DF__ProdStruc__PST_LeadTim__1DF06171]  DEFAULT ((0)),
    [PST_RoutSeqID] [nvarchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_EngChangeOrderID] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_FindID] [nvarchar](5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_Comments] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_UseAbsQtyFlag] [bit] NOT NULL CONSTRAINT [DF__ProdStruc__PST_UseAbsQ__1EE485AA]  DEFAULT ((0)),
    [PST_IgnoreCostFlag] [bit] NOT NULL CONSTRAINT [DF__ProdStruc__PST_IgnoreC__1FD8A9E3]  DEFAULT ((0)),
    [PST_PlanningPercent] [float] NOT NULL CONSTRAINT [DF__ProdStruc__PST_Plannin__20CCCE1C]  DEFAULT ((0)),
    [PST_EMP_RecordID] [uniqueidentifier] NULL,
    [PST_LastModifiedDate] [datetime] NULL,
    [PST_PurchPOWO] [bit] NOT NULL CONSTRAINT [DF__ProdStruc__PST_PurchPO__21C0F255]  DEFAULT ((0)),
    [PST_AgileCreatedDate] [datetime] NULL,
    [PST_ArchiveDate] [datetime] NULL,
    [PST_UserDef1] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_UserDef2] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_UserDef3] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_UserDef4] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PST_UserDef5] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [timestamp] [timestamp] NULL,
    [PST_SWImportFlag] [bit] NOT NULL CONSTRAINT [DF_ProductStructure_PST_SWImportFlag]  DEFAULT ((0)),
    [PST_CopiedFromRecordID] [uniqueidentifier] NULL,
    [PST_OnPicklist] [bit] NOT NULL DEFAULT ((1)),
    [PST_CID_DocumentID] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
 CONSTRAINT [PK_ProductStructure] PRIMARY KEY NONCLUSTERED 
(
[PST_RecordID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

看来您只是返回了一个串联的字符串。试试这个

DECLARE @WhereUsed varchar(MAX)
SET @WhereUsed = ''

SELECT @whereUsed=@whereUsed+PST_ParentItemID+', 'FROM PST 
      WHERE PST_CompItemID = @ItemID

IF LEN(@WhereUsed) > 2
        SET @WhereUsed = LEFT(@WhereUsed, LEN(@WhereUsed) - 2)