2012-11-16 40 views
4

我有一个表主键为event_id。我需要将PlantIM17更改为SG18如何为插入/选择中的每一行增加变量

我不想删除行(由于历史原因而被保留)。执行以下SQL时,我遇到PK违例。

DECLARE @plant CHAR(4) 
DECLARE @l_event_id INT 

SELECT @plant = 'SG18' 
SET @l_event_id = (SELECT MAX(cast(event_id as int)) FROM dbo.event_header) 

INSERT INTO dbo.event_header (
      event_id, scenario_name, actor_code, method_code, 
      SAP_plant_code, object_id,serial_no 
      ) 
    SELECT @l_event_id + 1 , eh.scenario_name, eh.actor_code, 
      eh.method_code, @plant, eh.object_id, eh.serial_no 
    FROM dbo.event_header eh 
    WHERE eh.SAP_plant_code = 'IM17'; 
+1

如果'event_Id'是'INT IDENTITY'列 - 那么SQL Server将处理所有这些自动更新id值的细节信息** –

+0

这将会很容易** dbo.event_header是一个“繁忙”表吗? (有很多用户/交易插入到该表吗?) – pkmiec

+0

@marc_s是的,这将是伟大的,但它是一个传统的数据库和PK是varchar(20):( – CodeMonkey

回答

4

你的方法是行不通的,因为你评估MAX(cast(event_id as int))只有一次 - 再尝试插入具有相同值的N个新行的event_id ....

你需要使用这样的事情让你完成工作:

DECLARE @plant CHAR(4) = 'SG18' 

DECLARE @l_event_id INT 
SELECT @l_event_id = MAX(CAST(event_id AS INT)) FROM dbo.event_header) 

;WITH CTE AS 
(
    SELECT 
     eh.scenario_name, 
     eh.actor_code, 
     eh.method_code, 
     eh.object_id, 
     eh.serial_no, 
     RowNum = ROW_NUMBER() OVER (ORDER BY eh.serial_no) 
    FROM dbo.event_header eh 
    WHERE eh.SAP_plant_code = 'IM17'; 
) 
INSERT INTO 
    dbo.event_header (event_id, scenario_name, actor_code, method_code, SAP_plant_code, object_id,serial_no) 
    SELECT 
     @l_event_id + RowNum, 
     scenario_name, actor_code, method_code, 
     @plant, 
      object_id, serial_no 
    FROM 
     CTE 

基本上,这CTE(公共表表达式),让你需要的所有值,再加上它采用ROW_NUMBER()生成连续的数字(从1到行选择数为@plant = 'IM17')。

当您将RowNum添加到之前的最大值,并且没有其他任何数据现在将数据插入到目标表中时 - 那么您将有可能获得成功!

+1

谢谢,这段代码片段正在我的个人存储库。 – CodeMonkey

相关问题