删除并重新创建标识列,并在更新语句

时间:2015-07-25 06:50:00

标签: sql sql-server-2012

我有四个名为plandescription,plandetail和analyzedetail的表。 table plandescription包含DetailQuestionID列,它是主列和标识列以及QuestionDescription列。

表plandetail包含主要和标识列的PlanDetailID列,DetailQuestionID,它是plandescription表的外键属性和planID列

第三个表analyzedetail包含一个analyzeID,其主要和标识列,PlanDetailID是plandetail表的外键属性和一个场景。

以下是三个表的架构

我有一个两个Web表单,它将在两个事务中插入,更新和删除这三个表中的数据。一个Web表单将在plandescription和plandetail表中执行CRUD操作。当用户在此Web表单中插入QuestionDescription和planid时,我会在plandescription表中插入QuestionDescription Value并生成DetailQuestionID值,并将此值与planid一起提供给plandetail表。在这里,我将生成一个PlanDetailID。

完成此交易后,我将显示用户进入方案的第二个Web表单,并使用PlanDetailID将其映射到计划描述。

此架构无法更改,因为这是客户端要求。 当我插入值时,我没有任何问题。但是,当我更新现有数据时,我需要删除plandetail表中的现有PlanDetailID,并为该DetailQuestionID和planID重新创建PlanDetailID数据。这是因为,用户将添加或删除与QuestionDescription关联的planID。

一旦我为DetailQuestionID和planID重新创建了PlanDetailID,我需要使用第三个表analyzedetail中的新PlanDetailID更新旧的PlanDetailID,用于关联的analyzeID。

我创建了一个名为#DetailTable的#Temp表来插入值analyzeID,planid和旧的PlanDetailID以及新的PlanDetailID,这样一旦我从plandetail表中删除了该PlanDetailID的数据,我就可以将它们放在update语句中。

然后我从plandetail表中删除了plandetailid,并为该DetailQuestionID重新创建PlanDetailID。在我的娱乐过程中,我将新的PlanDetailID创建到另一个名为#InsertedRows的临时表中

在此之后我运行一个while循环来更新临时表#DetailTable,其中包含新创建的PlanDetailID,用于相应的planID。 问题出在这里。当我有相同数量的planID,例如2 planID 1,2时,我将只有两个旧的PlanDetailID和新的PlanDetailID用于该planID和analyzeID。

但是当我添加新的PlanID或删除现有的planID时,我为新添加或删除的planID获取空值。 这影响了我对analyzedetail表的更新声明,因为PlanDetailID不能为空。

我尝试通过在while循环中运行analyzedetail的更新语句从#DetailTable中删除Null值,但是它不起作用。

任何人都可以帮我解决这个问题吗?下面是我创建的代码。

DECLARE @cID INT = 8
DECLARE @DQID INT = 1380

/*------- I need the query to run for the below three data. 
Here i'm updating my Pids that already exists in my database*/

DECLARE @Pids VARCHAR(MAX) = '2,4,5'

---DECLARE @Pids VARCHAR(MAX) = '2,4'
---DECLARE @Pids VARCHAR(MAX) = '1,2,4'

CREATE TABLE #DetailTable (
    Id INT IDENTITY(1, 1)
    ,analID INT
    ,PlanID INT
    ,OldPlanID INT
    ,NewPlanID INT
    )

INSERT INTO #DetailTable (
    analID
    ,PlanID
    ,OldPlanID
    ) (
    SELECT analID
    ,cfpd.PlanID
    ,cfpd.PlanDID FROM [dbo].[AnalDetail] rd INNER JOIN [dbo].[PlanDetail] cfpd ON rd.PlanDID = cfpd.PlanDID WHERE cfpd.DQID = @DQID
    )

---- Delete previous functionalplan id
DELETE
FROM dbo.PlanDetail
WHERE DQID = @DQID;

---- Insert New plandetail id for the category
CREATE TABLE #InsertedRows (
    Id INT IDENTITY(1, 1)
    ,NewPlanDID INT
    ,PlanID INT
    )

INSERT INTO dbo.plandetail (
    DQID
    ,planid
    )
OUTPUT inserted.PlanDID
    ,inserted.planid
INTO #InsertedRows
SELECT @DQID
    ,data
FROM dbo.fndatasplit(@functionalPids, ',');

--- Get Latest PlanDID
DECLARE @loop INT

SET @loop = 1

DECLARE @NewPlanDID AS INT
DECLARE @FPlanId AS INT

WHILE (
        @loop <= (
            SELECT Count(*)
            FROM #InsertedRows
            )
        )
BEGIN
    IF EXISTS (
            SELECT FunctionPlan
            FROM #DetailTable
            )
    BEGIN
        SELECT @FPlanId = PlanID
        FROM #InsertedRows
        WHERE ID = @loop

        SELECT @NewPlanDID = newPlanDID
        FROM #InsertedRows
        WHERE ID = @loop

        UPDATE #DetailTable
        SET NewPlanID = @NewPlanDID
        WHERE PlanID = @FPlanId

        SET @loop = @loop + 1
    END
END

--- Update AnalDetail Table with New PlanDetail
DECLARE @intFlag INT

SET @intFlag = 1

DECLARE @analID INT
DECLARE @NewPlanID INT

WHILE (
        @intFlag <= (
            SELECT Count(*)
            FROM #DetailTable
            WHERE NewPlanID IS NOT NULL
            )
        )
BEGIN
    SELECT @analID = analID
    FROM #DetailTable
    WHERE ID = @intFlag

    SELECT @NewPlanID = NewPlanID
    FROM #DetailTable
    WHERE ID = @intFlag

    UPDATE dbo.AnalDetail
    SET PlanDID = @NewPlanID
    WHERE analID = @analID

    SET @intFlag = @intFlag + 1
END

SELECT *
FROM #DetailTable

SELECT *
FROM #InsertedRows

SELECT *
FROM AnalDetail

---功能DataSplit

/****** Object:  UserDefinedFunction [dbo].[fnDataSplit]    Script Date: 25-07-2015 12:21:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[fnDataSplit]  
(  
 @RowData nvarchar(2000),  
 @SplitOn nvarchar(5)  
)    
RETURNS @RtnValue table   
(  
 Id int identity(1,1),  
 Data nvarchar(100)  
)   
AS    
BEGIN   
 Declare @Cnt int  
 Set @Cnt = 1  

 While (Charindex(@SplitOn,@RowData)>0)  
 Begin  
  Insert Into @RtnValue (data)  
  Select   
   Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))  

  Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))  
  Set @Cnt = @Cnt + 1  
 End  

 Insert Into @RtnValue (data)  
 Select Data = ltrim(rtrim(@RowData))  

 Return  
END  

1 个答案:

答案 0 :(得分:0)

在Google搜索内容后,我自己找到了答案。

我创建了一个临时表,并使用OUTPUT命令将所插入行的标识值提取到临时表。

来自临时表的

获得了新的标识值。

下面是代码

    INSERT INTO dbo.plandetail (
    DQID
    ,planid
    )
OUTPUT inserted.PlanDID
    ,inserted.planid
INTO #InsertedRows
SELECT @DQID
    ,data
FROM dbo.fndatasplit(@functionalPids, ',');