Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.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_Foreach_Cursor - Fatal编程技术网

Sql 将游标替换为“应用于”循环遍历数据库中的所有表

Sql 将游标替换为“应用于”循环遍历数据库中的所有表,sql,foreach,cursor,Sql,Foreach,Cursor,我有一个表集合(100+)所有这些表都包含两个字段 RowChanged bit ChangedFields bit 现在,发生了一个错误,当ChangedFields为空时,将某些条目保留为RowChanged=1。因此,我需要遍历这些字段并将RowChanged=0,其中ChangedFields为空 我通过以下游标实现了这一点 BEGIN TRANSACTION USE DatabaseName --Database name to clean DECLARE @Table_Name

我有一个表集合(100+)所有这些表都包含两个字段

RowChanged bit
ChangedFields bit
现在,发生了一个错误,当ChangedFields为空时,将某些条目保留为RowChanged=1。因此,我需要遍历这些字段并将RowChanged=0,其中ChangedFields为空

我通过以下游标实现了这一点


BEGIN TRANSACTION
USE DatabaseName --Database name to clean

DECLARE @Table_Name VARCHAR(50)
DECLARE @Query VARCHAR(250)
DECLARE Table_Cursor CURSOR FOR SELECT Name FROM sys.tables;
DECLARE @Affected_Rows INTEGER = 0

OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @Table_Name
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @Query = 'Update '+@Table_Name+' Set RowChanged = 0 Where RowChanged = 1 And (LEN(RTRIM(CONVERT(NVARCHAR(100), ChangedFields))) = 0 OR ChangedFields IS NULL)'
    EXEC (@Query)
    SET @Affected_Rows = @Affected_Rows + COALESCE(@@ROWCOUNT, 0)
    FETCH NEXT FROM Table_Cursor INTO @Table_Name
END
SELECT @Affected_Rows AS Affected_Rows

CLOSE  Table_Cursor
DEALLOCATE Table_Cursor

ROLLBACK --Change to COMMIT in order to save changes

虽然这确实有效,但我对使用游标有一种遗传上的厌恶。另外,我刚刚了解到,Apply在很多情况下都可以实现2005年之前的游标

我需要做的是遍历数据库中的所有表,检查RowChanged=1和ChangedFields(如“”或NULL)的条件


我试着用TVFs解决这个问题,但我一直做不到。虽然我可以在一个表中执行操作,但从sys.tables中获取列表并在多个表上执行某些操作却让我不知所措。

您可以用While循环语句替换光标。尝试使用如下语句来获得所需的o/p

select name into #table from sys.tables
while (select count(*) from #table)>0
begin
    set rowcount 1  
    select @Table_Name = name from sys.tables
    set rowcount 0  
    .......
    .......

    delete from #table where name = @Table_Name
end

上面的代码段来自sybase,您可能需要对语法进行一些小的修改。我希望这会有所帮助。

您可以用while循环语句替换光标。尝试使用如下语句来获得所需的o/p

select name into #table from sys.tables
while (select count(*) from #table)>0
begin
    set rowcount 1  
    select @Table_Name = name from sys.tables
    set rowcount 0  
    .......
    .......

    delete from #table where name = @Table_Name
end
declare @stmt nvarchar(max)

select
   @stmt =
      isnull(@stmt + nchar(13) + nchar(10), '') + 
      'update '+ name +' set RowChanged = 0 Where RowChanged = 1 And (LEN(RTRIM(CONVERT(NVARCHAR(100), ChangedFields))) = 0 OR ChangedFields IS NULL)'
from sys.tables

print @stmt

sp_executesql @stmt = @stmt
上面的代码段来自sybase,您可能需要对语法进行一些小的修改。我希望这有帮助

declare @stmt nvarchar(max)

select
   @stmt =
      isnull(@stmt + nchar(13) + nchar(10), '') + 
      'update '+ name +' set RowChanged = 0 Where RowChanged = 1 And (LEN(RTRIM(CONVERT(NVARCHAR(100), ChangedFields))) = 0 OR ChangedFields IS NULL)'
from sys.tables

print @stmt

sp_executesql @stmt = @stmt
还有未记录的存储过程
sp\MSforeachtable
-。事实上,我从来没有在我的工作中使用过它,所以它只是为了提供信息


还有未记录的存储过程
sp\MSforeachtable
-。实际上,我从来没有在我的工作中使用过它,所以它只是为了提供信息。

有人警告我不要使用
sp\MSforeachtable
,当数据库中有很多表时,你似乎不能相信它。更改了答案-我从来没有在工作中使用过它,但听说过,所以我想最好提及它。我更喜欢动态SQL,因为它更易于维护,而且我总是可以打印语句来查看我将执行什么。我被警告不要使用
sp\MSforeachtable
,当数据库中有许多表时,您似乎不能信任它。更改了答案-我在工作中从未使用过它,但听说过它,所以我想提一下会很好。我更喜欢动态SQL,因为它更易于维护,而且我总是可以打印语句来查看我将执行什么