Sql server 2012 从CTE和Case语句更新SQL Server表

Sql server 2012 从CTE和Case语句更新SQL Server表,sql-server-2012,sql-server-2014,common-table-expression,Sql Server 2012,Sql Server 2014,Common Table Expression,我有以下代码: WITH CTE AS ( SELECT LTRIM(RTRIM([EMP_ID])) AS empID FROM [SAMPLE].[dbo].[segments] ) SELECT (CASE WHEN LEN(LTRIM(RTRIM(EMPID))) = 5 THEN RIGHT(('100' + EMPID), 8) WHEN LEN(LTRIM(RTRIM(EMP

我有以下代码:

WITH CTE AS
(
    SELECT 
        LTRIM(RTRIM([EMP_ID])) AS empID
    FROM 
        [SAMPLE].[dbo].[segments]
)
SELECT
    (CASE WHEN LEN(LTRIM(RTRIM(EMPID))) = 5 
             THEN RIGHT(('100' + EMPID), 8)
          WHEN LEN(LTRIM(RTRIM(EMPID))) = 6 
             THEN RIGHT(('10' + EMPID), 8)
          WHEN LEN(EMPID) = 7 
             THEN RIGHT('10' + (LEFT(LTRIM(EMPID), 6)), 8)
          ELSE empID
     END) EMP_ID
FROM CTE
我要做的是使用上述状态将我的
emp\u id
列更新为新的8位id。运行脚本会正确返回ID,现在我只需要更新表

我尝试了下面的方法,所有的ID都是一样的

WITH CTE AS 
(
    SELECT 
        LTRIM(RTRIM([EMP_ID])) AS empID
    FROM 
        [SAMPLE].[dbo].[segments]
)
UPDATE segments
SET EMP_ID = (case when len(ltrim(rtrim(EMPID))) = 5 then right(('100' + EMPID),8 )
        when len(ltrim(rtrim(EMPID))) = 6 then right(('10' + EMPID),8 )
        when len(EMPID) = 7 then right('10'+(left(ltrim(EMPID),6)),8)
      else empID
      end) 
FROM CTE

用于此操作的正确的
UPDATE
语句是什么?

在中包括基列,并直接更新
cte

;with cte as (
  select 
      emp_id
    , empid = '1'+replicate('0',7-len(ltrim(rtrim([emp_id]))))+ltrim(rtrim(emp_id))
  from segments
  where len(ltrim(rtrim([emp_id]))) < 8
)

update cte set emp_id = empid;

select *
from segments;
从该测试设置:

create table segments (emp_id char(8))
insert into segments values 
 ('88888888')
,('7777777')
,('666666')
,('55555')
,('4444')
,('333')
,('22')
,('1');

将基列包括在中,并直接更新
cte

;with cte as (
  select 
      emp_id
    , empid = '1'+replicate('0',7-len(ltrim(rtrim([emp_id]))))+ltrim(rtrim(emp_id))
  from segments
  where len(ltrim(rtrim([emp_id]))) < 8
)

update cte set emp_id = empid;

select *
from segments;
从该测试设置:

create table segments (emp_id char(8))
insert into segments values 
 ('88888888')
,('7777777')
,('666666')
,('55555')
,('4444')
,('333')
,('22')
,('1');

如果修剪后的emp_id最左边的5或6个字符都是数字,则可以执行以下操作:

UPDATE [SAMPLE].[dbo].[segments]
SET EMP_ID = cast(10000000 + cast(ltrim(rtrim( case when len(ltrim(rtrim(emp_id))) > 6 then left(ltrim(rtrim(emp_Id)),6) else ltrim(rtrim(emp_id)) end)) as int) as char(8))
如果您通过两个步骤来完成此操作,则可以使其更易于理解:

UPDATE [SAMPLE].[dbo].[segments]
SET Emp_ID = rtrim(ltrim(Emp_ID))

UPDATE [SAMPLE].[dbo].[segments]
SET EMP_ID = cast(10000000 + cast(case when len(emp_id) > 6 then left(emp_Id,6) else emp_id end as int) as char(8))
尽管我强烈怀疑这是没有必要的,而且您的EMP_ID值已经被修剪了。如果您知道7个字符的场景也是数字的,那么它可能会变得更简单


最后,我对没有
WHERE
UPDATE
查询感到非常紧张。有可能这次你是认真的。。。但是运行起来仍然很可怕。

如果修剪后的emp\u id最左边的5或6个字符都是数字,您可以执行以下操作:

UPDATE [SAMPLE].[dbo].[segments]
SET EMP_ID = cast(10000000 + cast(ltrim(rtrim( case when len(ltrim(rtrim(emp_id))) > 6 then left(ltrim(rtrim(emp_Id)),6) else ltrim(rtrim(emp_id)) end)) as int) as char(8))
如果您通过两个步骤来完成此操作,则可以使其更易于理解:

UPDATE [SAMPLE].[dbo].[segments]
SET Emp_ID = rtrim(ltrim(Emp_ID))

UPDATE [SAMPLE].[dbo].[segments]
SET EMP_ID = cast(10000000 + cast(case when len(emp_id) > 6 then left(emp_Id,6) else emp_id end as int) as char(8))
尽管我强烈怀疑这是没有必要的,而且您的EMP_ID值已经被修剪了。如果您知道7个字符的场景也是数字的,那么它可能会变得更简单


最后,我对没有
WHERE
UPDATE
查询感到非常紧张。有可能这次你是认真的。。。但是跑步仍然很可怕。

如果没有CTE,你可以试试

UPDATE segments
SET EMP_ID = (case when len(ltrim(rtrim(EMP_ID))) = 5 then right(('100' + EMP_ID),8 )
    when len(ltrim(rtrim(EMP_ID))) = 6 then right(('10' + EMP_ID),8 )
    when len(EMP_ID) = 7 then right('10'+(left(ltrim(EMP_ID),6)),8)
  else emp_ID
  end)
或者如果你想使用CTE,你可以试试

With CTE
As 
(
SELECT ltrim(rtrim([EMP_ID])) as empIDTrim
, Emp_ID

FROM [SAMPLE].[dbo].[segments]
)
UPDATE CTE
SET EMP_ID = (case when len(empIDTrim)= 5 
then right('100' + empIDTrim,8 )
    when len(empIDTrim)= 6 
then right('10' + empIDTrim ,8 )
    when len(empIDTrim) = 7 
  then right('10'+left(empIDTrim,6),8)
  else empIDTrim
  end) 

没有CTE,你可以试试

UPDATE segments
SET EMP_ID = (case when len(ltrim(rtrim(EMP_ID))) = 5 then right(('100' + EMP_ID),8 )
    when len(ltrim(rtrim(EMP_ID))) = 6 then right(('10' + EMP_ID),8 )
    when len(EMP_ID) = 7 then right('10'+(left(ltrim(EMP_ID),6)),8)
  else emp_ID
  end)
或者如果你想使用CTE,你可以试试

With CTE
As 
(
SELECT ltrim(rtrim([EMP_ID])) as empIDTrim
, Emp_ID

FROM [SAMPLE].[dbo].[segments]
)
UPDATE CTE
SET EMP_ID = (case when len(empIDTrim)= 5 
then right('100' + empIDTrim,8 )
    when len(empIDTrim)= 6 
then right('10' + empIDTrim ,8 )
    when len(empIDTrim) = 7 
  then right('10'+left(empIDTrim,6),8)
  else empIDTrim
  end) 

为什么不使用简单的更新呢?为什么是CTE?是否有EMPID包含非数字字符?哦,当您已经检查了字符串的长度为5个字符,并且在3之前加上前缀时,您不需要再次将字符串修剪回8。6和2也一样。为什么不使用简单的更新呢?为什么是CTE?是否有EMPID包含非数字字符?哦,当您已经检查了字符串的长度为5个字符,并且在3之前加上前缀时,您不需要再次将字符串修剪回8。6和2也一样。谢谢Joel Coehoorn,非常感谢。是的,我明白你的意思,但这将是一次性交易-我们正在将所有EMP_ID从5,6,7位移到8位。因此,我拥有的任何历史数据都需要转换为新的8位数ID。感谢Joel Coehoorn,这也很有效。是的,我明白你的意思,但这将是一次性交易-我们正在将所有EMP_ID从5、6、7位数移到8位数。因此,我拥有的任何历史数据都需要转换为新的8位ID。感谢SqlZim的解释和提示。这也很有效。非常感谢。感谢SqlZim的解释和提示。这也很有效。非常感谢。