2017-09-28 4 views
0

J'ai cette fonction écrite en T-SQL sur SQL Server 2005. Je ne suis pas aussi contre les curseurs que certains le sont, mais je vois toujours des gens dire que 99% de tous les curseurs peuvent être réutilisés. écrit pour éviter leur utilisation.Comment puis-je réécrire ceci pour éviter un curseur

J'ai cette fonction:

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 

qui va obtenir tous les éléments où une partie est utilisée, PST est ParentStructureTable. Pensez nomenclature (nomenclature)

Il sera utilisé comme ceci:

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

Et retourner quelque chose comme ceci:

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

Comment cela pourrait-il être fait sans l'aide d'un curseur?

EDIT: données exemples

SELECT PST_ParentItemID FROM PST WHERE PST_CompItemID = @ItemID 

peut retourner

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

Il est vraiment simple instruction select, ne sais pas comment le DDL aidera, mais la voici:

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] 
+0

pouvez-vous donner le DDL des tables ou des exemples de données? Cela ressemble vraiment à une table dérivée structurée étrange. – scsimon

Répondre

1

Il semble que vous renvoyez simplement une chaîne concaténée. Essayez ceci

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

SELECT @[email protected]+PST_ParentItemID+', 'FROM PST 
     WHERE PST_CompItemID = @ItemID 

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

Bien! Je ne savais pas que je peux construire une chaîne dans l'instruction select. Je vais changer ma fonction. – John