我在我的存储过程中使用光标;我希望从我的SP中删除光标。请帮我提出一个解决方案,用于避免使用dynamic将光标语句恢复为正常更新语句。
以下示例:
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'Test'(variable) and age = 18(variable)
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'kumar'(variable) and age = 19(variable)
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'babu'(variable) and age = 30(variable)
这就是我的光标的工作方式。 300组合动态选择表中的数据并更新到主表
我正在尝试取出游标,并且update语句应该与此类似,而不是编写300个更新语句,我想编写一个更新,其中所有300个组合应该执行。
以下是需要此解决方案的代码:
BEGIN
DECLARE @Type VARCHAR(100)
DECLARE @TargetColumn VARCHAR(100)
DECLARE @SourceColumn VARCHAR(100)
DECLARE @SQL varchar(max)
DECLARE a_cursor CURSOR STATIC
FOR
SELECT [Type],[SourceColumn],[TargetColumn] FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn]
OPEN a_cursor
FETCH NEXT FROM a_cursor INTO @Type,@SourceColumn,@TargetColumn
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = 'UPDATE GCT SET GCT.' + @TargetColumn + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + @SourceColumn + ' = map.[SourceValue]
where map.[Type]=''' + @Type + ''' and map.SourceColumn=''' + @SourceColumn+ ''''
Exec (@SQL)
PRINT @SQL
FETCH NEXT FROM a_cursor INTO @Type,@SourceColumn,@TargetColumn
END
CLOSE a_cursor
DEALLOCATE a_cursor
END
答案 0 :(得分:1)
我没有使用明确的游标或光标巧妙地伪装成while循环,而是更倾向于对这类问题进行行级联操作。
DECLARE @cmd NVARCHAR(MAX) = N'';
SELECT @cmd += N'
UPDATE GCT
SET GCT.' + QUOTENAME(TargetColumn) + ' = map.TargetValue
FROM dbo.EdsMap AS map
INNER JOIN dbo.Table AS GCT
ON GCT.' + QUOTENAME(SourceColumn) + ' = map.SourceValue
WHERE map.[Type] = ''' + [Type] + '''
AND map.SourceColumn = ''' + [SourceColumn]+ ''';'
FROM ref.tblEdsMap
GROUP BY [Type], SourceColumn, TargetColumn;
EXEC sp_executesql @sql;
答案 1 :(得分:0)
当我在过去完成这些操作时,我通常会编写一个事务来包含所需的每个更新。像这样:
CREATE TABLE #targets ([Type] VARCHAR(255),[SourceColumn] VARCHAR(255),[TargetColumn] VARCHAR(255));
INSERT INTO #targets
( [Type], [SourceColumn], [TargetColumn] )
SELECT [Type],[SourceColumn],[TargetColumn] FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn];
DECLARE @sql VARCHAR(MAX);
SET @sql = 'BEGIN TRAN' + CHAR(10) + CHAR(13);
SELECT @sql = @sql +
'UPDATE GCT SET GCT.' + [TargetColumn] + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + [SourceColumn] + ' = map.[SourceValue]
where map.[Type]=''' + [Type] + ''' and map.SourceColumn=''' + [SourceColumn]+ ''';' + CHAR(10) + CHAR(13)
FROM #targets
SELECT @sql = @sql + 'COMMIT TRAN'
PRINT @sql
Exec (@SQL)
更新语句仍然相同,即每个组合获得一次更新。但现在您作为一个交易批次运行。您可能会对动态SQL更有兴趣,因此您只有一个更新语句,但根据我的经验,以这种方式获取不良更新太容易了。
这样做可能不会比光标快。你必须测试才能确定。通过我使用这种方法的示例, 通常是一种更快的方法。
答案 2 :(得分:-2)
尝试使用表变量和WHILE
循环,如下所示:
BEGIN
DECLARE @Type VARCHAR(100)
DECLARE @TargetColumn VARCHAR(100)
DECLARE @SourceColumn VARCHAR(100)
DECLARE @SQL varchar(max)
DECLARE @SomeTable TABLE
(
ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
Type varchar(100),
SourceColumn varchar(100),
TargetColumn varchar(100)
)
DECLARE @Count int, @Max int
INSERT INTO @SomeTable (Type, SourceColumn, TargetColumn)
SELECT [Type],[SourceColumn],[TargetColumn]
FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn]
SELECT @Count = 1, @Max = COUNT(ID)
FROM @SomeTable
WHILE @Count <= @Max
BEGIN
SELECT
@Type = Type,
@SourceColumn = SourceColumn,
@TargetColumn = TargetColumn
FROM @SomeTable
WHERE ID = @Count
-- Your code
SET @SQL = 'UPDATE GCT SET GCT.' + @TargetColumn + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + @SourceColumn + ' = map.[SourceValue]
where map.[Type]=''' + @Type + ''' and map.SourceColumn=''' + @SourceColumn+ ''''
Exec (@SQL)
PRINT @SQL
SET @Count = @Count + 1
END -- while
END