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