Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 创建一个临时表并遍历行,以便对另一个表执行更新_Sql_Sql Server - Fatal编程技术网

Sql 创建一个临时表并遍历行,以便对另一个表执行更新

Sql 创建一个临时表并遍历行,以便对另一个表执行更新,sql,sql-server,Sql,Sql Server,我试图将现有表中的数据更改为临时表,并在行中循环,以便对现有表数据执行更新 我需要剥离DeviceName列并强制转换为INT,以便提取对现有表执行更新所需的DeviceId。第一个表显示了未格式化DeviceName的示例。第二个表显示了格式化DeviceName DeviceIntModified的示例。然后,我需要获取这些设备ID,以便可以使用它们对现有表执行更新 我的原始桌面设备: 我在从这个诱惑中选择数据和循环数据时遇到了问题 DECLARE @RowCount INT WITH te

我试图将现有表中的数据更改为临时表,并在行中循环,以便对现有表数据执行更新

我需要剥离DeviceName列并强制转换为INT,以便提取对现有表执行更新所需的DeviceId。第一个表显示了未格式化DeviceName的示例。第二个表显示了格式化DeviceName DeviceIntModified的示例。然后,我需要获取这些设备ID,以便可以使用它们对现有表执行更新

我的原始桌面设备:

我在从这个诱惑中选择数据和循环数据时遇到了问题

DECLARE @RowCount INT WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 9) AS DeviceNameModidfied 
   FROM
      tblDevices 
   where
      StationID = 14 
)
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 500 
SET
   @RowCount = 
   (
      SELECT
         COUNT(DevicesID) 
      from
         tempTable
   )
   DECLARE @I INT 
SET
   @I = 1 WHILE (@I <= @RowCount) 
   BEGIN
      DECLARE @rowID INT 
      --I'm getting invalid column/object name when trying to select from tempTable here
      SELECT
         @rowID = DevicesID 
      from
         tempTable 
         UPDATE
            anotherTable                
            SET CheckBox = 'T'
         WHERE
            DevicesID = @rowID 
         SET
            @I = @I + 1 
   END

您可以直接更新CTE,但在这种情况下,您可以简单地使用exists子句。如果您的示例不准确,则连接条件可能不同。exists子句用于内部联接,因为您不需要查看返回的记录,因此这种方法更可取

WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 12) AS DeviceNameModidfied
   FROM
      tblDevices 
   where
      StationID = 14 
)
, TempTable_2 as (
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 467
)
Update SomeOtherTable
Set CheckBox = 'T'
where exists (select 1 from TempTable_2 tt where DeviceID = tt.DeviceID);

您可以直接更新CTE,但在这种情况下,您可以简单地使用exists子句。如果您的示例不准确,则连接条件可能不同。exists子句用于内部联接,因为您不需要查看返回的记录,因此这种方法更可取

WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 12) AS DeviceNameModidfied
   FROM
      tblDevices 
   where
      StationID = 14 
)
, TempTable_2 as (
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 467
)
Update SomeOtherTable
Set CheckBox = 'T'
where exists (select 1 from TempTable_2 tt where DeviceID = tt.DeviceID);

如果您使用更新语法,允许您在查询本身中加入“anotherTable”,则可以避免循环甚至CTE

update      other.checkbox = 't'
from        anotherTable other 
join        tblDevices td on td.devicesId = other.devicesId
cross apply (select DeviceNameMod = convert(int,right(DeviceName, len(DeviceName) - 12))) ap
where       td.StationID = 14 
and         ap.DeviceNameMod > 464 
and         ap.DeviceNameMod < 500;

但是如果你继续你原来的方法,你的一个大问题是你的@rowID像迭代器一样被使用,应该是从0到n-1或者从1到n,但是你正在用“DeviceId”填充它,如果您使用允许您直接在查询本身中加入“另一个表”的更新语法,则可以避免循环甚至CTE

update      other.checkbox = 't'
from        anotherTable other 
join        tblDevices td on td.devicesId = other.devicesId
cross apply (select DeviceNameMod = convert(int,right(DeviceName, len(DeviceName) - 12))) ap
where       td.StationID = 14 
and         ap.DeviceNameMod > 464 
and         ap.DeviceNameMod < 500;

但是如果你继续你原来的方法,你的一个大问题是你的@rowID就像一个迭代器一样被使用,应该是从0到n-1或者从1到n,但是你用“DevicesId”填充它,这肯定不起作用。

在DBMS中循环几乎总是一个坏主意;他们对这样的过程很在行。基于集合的方法很可能会非常有效。@Shane。如果您解释了如何使用第一个查询的结果,这将非常有帮助。这是如何使用的并不明显。@GordonLinoff-我编辑了我的原始帖子,以更详细地解释这一点。当我尝试你的代码时,我得到了无效的对象名“诱惑”。这是因为WITH的上下文中有多个语句,这是不允许的WITH子句至少有一个错误,它前面必须加分号:当CTE用于批处理的一部分语句时,它前面的语句后面必须加分号。此外,还有多个引用CTE的语句,这是不允许的;他们对这样的过程很在行。基于集合的方法很可能会非常有效。@Shane。如果您解释了如何使用第一个查询的结果,这将非常有帮助。这是如何使用的并不明显。@GordonLinoff-我编辑了我的原始帖子,以更详细地解释这一点。当我尝试你的代码时,我得到了无效的对象名“诱惑”。这是因为WITH的上下文中有多个语句,这是不允许的WITH子句至少有一个错误,它前面必须加分号:当CTE用于批处理的一部分语句时,它前面的语句后面必须加分号。此外,还有多个引用CTE的语句,这是不允许的。
WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 12) AS DeviceNameModidfied
   FROM
      tblDevices 
   where
      StationID = 14 
)
, TempTable_2 as (
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 467
)
Update SomeOtherTable
Set CheckBox = 'T'
where exists (select 1 from TempTable_2 tt where DeviceID = tt.DeviceID);
update      other.checkbox = 't'
from        anotherTable other 
join        tblDevices td on td.devicesId = other.devicesId
cross apply (select DeviceNameMod = convert(int,right(DeviceName, len(DeviceName) - 12))) ap
where       td.StationID = 14 
and         ap.DeviceNameMod > 464 
and         ap.DeviceNameMod < 500;