Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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,当前代码: DECLARE thisLoop CURSOR FOR SELECT IdOld, IdNew FROM @fieldNewOld; OPEN thisLoop; FETCH NEXT FROM thisLoop INTO @fIdOld, @fIdNew; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE dbo.mel SET melCode = REPLACE(melCode, '_' + CONVERT(va

当前代码:

DECLARE thisLoop CURSOR FOR  
SELECT IdOld, IdNew  
FROM @fieldNewOld;  

OPEN thisLoop;  

FETCH NEXT FROM thisLoop INTO @fIdOld, @fIdNew;  
WHILE @@FETCH_STATUS = 0  
BEGIN

UPDATE dbo.mel
      SET melCode = REPLACE(melCode, '_' + CONVERT(varchar(50),@fIdOld), '_' + CONVERT(varchar(50),@fIdNew))
      where fID = (select IdNew from @newForm) and melCode LIKE ('%_'  + CONVERT(varchar(50), @fIdOld) + '%')

    FETCH NEXT FROM thisLoop INTO @fIdOld, @fIdNew 
END;  

CLOSE thisLoop;  
DEALLOCATE thisLoop;
这方面的工作还有很多,但基本上我是在复制一个数据集@fieldNewOld包含旧id和新id。dbo.mel中的melCode包含用专有语言编写的代码,可以引用所有旧id。它将被引用为类似“myVar_1234”的内容,其中1234将是旧id之一。复制时,我想用melCode中的新id替换所有旧id

我可以用上面所示的游标循环来完成,但是当有一个大数据集时,它的速度非常慢。我也尝试了下面的代码,但如果melCode中有多个旧id,它将尝试多次更新同一行并抛出错误:

MERGE INTO dbo.mel b
   USING @fieldNewOld a
      ON b.fID = (select IdNew from @newForm) and b.melCode LIKE ('%_' + CONVERT(varchar(50), a.IdOld) + '%')
WHEN MATCHED THEN
   UPDATE 
      SET b.melCode = REPLACE(b.melCode, '_' + CONVERT(varchar(50),a.IdOld), '_' + CONVERT(varchar(50),a.IdNew));
有没有办法以基于集合的方式实现这一点,或者我被光标循环的缓慢所困扰

示例数据:

@菲尔德纽奥尔德

IdOld | IdNew
1234 | 5678
1235 | 5679
1236 | 5680
melCode(所有这些将在一行中)

复制后,我希望melCode看起来像这样:

userok("My variable: " + myVar_5678)
myVar_5678 = "this is a test"
newVar_5680 = "here is some more data"

可以在更新中使用联接

UPDATE m
SET melCode = REPLACE(melCode, '_' + CONVERT(varchar(50),IdOld), '_' + CONVERT(varchar(50),fIdNew))
FROM dbo.mel m
JOIN @fieldNewOld fno ON m.melCode LIKE ('%_'  + CONVERT(varchar(50), IdOld) + '%')
where fID = (select IdNew from @newForm) ;

这似乎在melCode中有一个复合值。我的建议是将该值拆分为2列或更多列,并将melCode作为计算列。

考虑使用最终表格和表格变量的
JOIN
进行更新:

UPDATE m
SET m.melCode = REPLACE(m.melCode, '_' + CONVERT(varchar(50), f.IdOld), 
                        '_' + CONVERT(varchar(50), f.IdNew))
FROM dbo.mel m
JOIN @fieldNewOld f 
  ON m.melCode LIKE ('%_'  + CONVERT(varchar(50), f.IdOld) + '%')
JOIN @newForm n 
  ON m.fID = n.IdNew 

由于您需要多次更新同一个文本,请考虑在一个迭代更新中运行上述代码,该更新遍历<代码>字段NeWordOrd < /Cord>IDS:< /P>中的行数。

DECLARE @Counter INT
DECLARE @ID_Count INT

SET @Counter = 0
SET @ID_Count = (SELECT COUNT(*) FROM @fieldNewOld)

WHILE @Counter <= @ID_Count

BEGIN
    UPDATE m
    SET m.melCode = REPLACE(m.melCode, '_' + CONVERT(varchar(50), f.IdOld), 
                            '_' + CONVERT(varchar(50), f.IdNew))
    FROM dbo.mel m
    JOIN @fieldNewOld f 
      ON m.melCode LIKE ('%_'  + CONVERT(varchar(50), f.IdOld) + '%')
    JOIN @newForm n 
      ON m.fID = n.IdNew 

    SET @Counter += 1
END
DECLARE@Counter INT
声明@ID\u Count INT
设置@Counter=0
设置@ID\u Count=(从@fieldNewOld中选择Count(*)

而@Counter你可以使用
加入
。嗨,菲尔!请提供输入示例和所需输出/状态?@Cowthulhu示例输入和所需输出已添加,谢谢!通常,您可以(也应该)始终使用基于集合的逻辑,除非您在循环中调用另一个存储过程。即使如此,也只有在调用系统存储过程的情况下才应该这样做。注意
之类的
和通配符匹配<代码>%
将匹配一堆字符,(有趣的事实!)
\u
将匹配一(一)个字符。所以,
像“%\u1”
很可能不会做您认为它会做的事情。在转义字符中工作:
类似“%[\]”
。。。但是要进行大量测试,以确保它按预期工作。根据我在上面输入的示例数据,您提供的代码只更新一个id,而不是多个id。因此,在上面的示例中,myVar_1234将更改为myVar_5678,但newVar_1236不会使用您提供的代码更改为newVar_5680。@Phil您从哪里得到这个想法?你说的不是真的。@LuisCazares我刚刚运行了代码,它只更新了一个变量。也许我错过了什么。我会再试一次。@Phil Parfait的代码或我的代码中没有任何内容会将更新的行限制为一行。@LuisCazares只有一行数据需要更新,所以这不是问题所在。问题在于,单行数据包含对多个id的多个引用,这些引用都需要更新以反映新id。使用提供的连接代码,这个
userok(“我的变量:+myVar_1234)myVar_1234=”这是一个测试“newVar_1236=”这里还有一些数据“
变成了这个
userok(“我的变量:+myVar_5678)myVar_5678=”这是一个测试“newVar_1236=”这里还有一些数据“
DECLARE @Counter INT
DECLARE @ID_Count INT

SET @Counter = 0
SET @ID_Count = (SELECT COUNT(*) FROM @fieldNewOld)

WHILE @Counter <= @ID_Count

BEGIN
    UPDATE m
    SET m.melCode = REPLACE(m.melCode, '_' + CONVERT(varchar(50), f.IdOld), 
                            '_' + CONVERT(varchar(50), f.IdNew))
    FROM dbo.mel m
    JOIN @fieldNewOld f 
      ON m.melCode LIKE ('%_'  + CONVERT(varchar(50), f.IdOld) + '%')
    JOIN @newForm n 
      ON m.fID = n.IdNew 

    SET @Counter += 1
END