SQL Server使用游标或临时表遍历数据

摘要:
方法一:使用游标(此方法适用所有情况,对标结构没有特殊要求。

方法一:使用游标(此方法适用所有情况,对标结构没有特殊要求。)

declare @ProductName nvarchar(50)
declare pcurr cursor for select ProductName fromProducts
open pcurr
fetch next frompcurr into @ProductName
while (@@fetch_status = 0)
begin
 print (@ProductName)
 fetch next frompcurr into @ProductName
end
close pcurr
deallocate pcurr  

--给空的sort进行赋值 从1开始按顺序排
declare @id int declare cursor1 cursor for
select ClassId from [content] group by ClassId
open cursor1
fetch next from cursor1 into @id
while @@fetch_status=0
begin
select ROW_NUMBER()over(order by id) as pid,id into #ttttt from [content] where classid=@id;
update [content] set sort = pid from #ttttt where #ttttt.id = [content].id;
drop table #ttttt;
fetch next from cursor1 into @id
end close cursor1

在关系数据库中,我们对于查询的思考是面向集合的。而游标打破了这一规则,游标使得我们思考方式变为逐行进行.

对于游标一些优化建议

  • 如果能不用游标,尽量不要使用游标
  • 用完用完之后一定要关闭和释放
  • 尽量不要在大量数据上定义游标
  • 尽量不要使用游标上更新数据
  • 尽量不要使用insensitive, static和keyset这些参数定义游标
  • 如果可以,尽量使用FAST_FORWARD关键字定义游标
  • 如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数
  • 参考:http://www.cnblogs.com/moss_tan_jun/archive/2011/11/26/2263988.html

方法二:使用循环(此方法适用于表带有自动增加标识的字段)

declare @ProductName nvarchar(50)
declare @ProductID int
select @ProductID=min(ProductID) fromProducts
while @ProductID is not null
begin
 select @ProductName=ProductName from Products where
ProductID=@ProductID
 print(@ProductName);
 select @ProductID=min(ProductID) from Products where
ProductID>@ProductID
end
--删除临时表#Tmp
create table #Tmp  --创建临时表#Tmp
(
    ID   int IDENTITY (1,1)     not null, --创建列ID,并且每次新增一条记录就会加1
    WokNo                varchar(50),   
    primary key (ID)      --定义ID为临时表#Tmp的主键      
);
--declare @temp table   
--(   
--   [id] int IDENTITY(1,1),   
--   [Name] varchar(10)   
--)   
Select * from #Tmp    --查询临时表的数据
truncate table #Tmp  --清空临时表的所有数据和约束
相关例子:
Declare @Wokno Varchar(500)  --用来记录职工号
Declare @Str NVarchar(4000)  --用来存放查询语句
Declare @Count int  --求出总记录数      
Declare @i int
Set @i = 0
Select @Count = Count(Distinct(Wokno)) from#Tmp
While @i <@Count 
    Begin
       Set @Str = 'Select top 1 @Wokno = WokNo from #Tmp Where id not in (Select top ' + Str(@i) + 'id from #Tmp)'
       Exec Sp_ExecuteSql @Str,N'@WokNo Varchar(500) OutPut',@WokNo Output
       Select @WokNo,@i  --一行一行把职工号显示出来
       Set @i = @i + 1
    End
--drop table #temp
USE Test_DBData;
GO
--修正表中REC_CreateBy,REC_ModifyBy
CREATE TABLE #temp
    (
      id INT IDENTITY(1, 1) ,
      tablename NVARCHAR(100)
    );
DECLARE @tablename NVARCHAR(100);
DECLARE @n INT;
DECLARE @count INT;
DECLARE @str NVARCHAR(4000);
  --用来存放查询语句
DECLARE @tableCreateBy NVARCHAR(150);
DECLARE @tableModifyBy NVARCHAR(150);
SELECT  @n = 1;
INSERT  #temp
        ( tablename
        )
        SELECT  name
        FROM    sysobjects
     WHERE type = 'U '
AND (name <> 'Dim_Employee')
AND (name <> 'Fct_ChannelType')
    AND (name <> 'Rel_TPOCommodityMessage')
AND (name LIKE 'Dim%' OR name LIKE 'Fct%' OR name LIKE 'Rel%');
SELECT  @count =@@rowcount;
WHILE @n <=@count
    BEGIN
        SELECT  @tablename =( SELECT   tablename
                               FROM     #temp
                               WHERE    id =@n
                             );
        SET @tableCreateBy = @tablename + '.REC_CreateBy';
        SET @tableModifyBy = @tablename + '.REC_ModifyBy';
        SET @str = 'IF EXISTS ( SELECT  *
            FROM    ( SELECT    '+@tableCreateBy+'
                      FROM      '+@tablename+'
                                INNER JOIN dbo.Dim_Employee ON '+@tableCreateBy+' =Dim_Employee.LoginName
                    ) tb)
    BEGIN
        UPDATE  '+@tablename+'
        SET     REC_CreateBy =Dim_Employee.EmployeeId
        FROM    '+@tablename+'
                INNER JOIN dbo.Dim_Employee ON '+@tableCreateBy+' =Dim_Employee.LoginName;
    END;    
    IF EXISTS ( SELECT  *
            FROM    ( SELECT    '+@tableModifyBy+'
                      FROM      '+@tablename+'
                                INNER JOIN dbo.Dim_Employee ON '+@tableModifyBy+' =Dim_Employee.LoginName
                    ) tb )
    BEGIN
        UPDATE  '+@tablename+'
        SET     REC_ModifyBy =Dim_Employee.EmployeeId
        FROM    '+@tablename+'
                INNER JOIN dbo.Dim_Employee ON '+@tableModifyBy+' =Dim_Employee.LoginName;
    END;    
    ';
EXEC(@str);
        SELECT  @n = @n + 1;
        DELETE  FROM #temp
        WHERE   tablename =@tablename;
    END;
--删除临时表
IF OBJECT_ID(N'tempdb.dbo.#temp') IS NOT NULL
    BEGIN
        DROP TABLE #temp;
    END
1.分批更新数据库
declare @x int
set @x=1 
while(@x<=51) 
begin 
begin tran 
update UserFavorite set UserFavorite.firstpublishtime =product.lastpublishtime
from UserFavorite,product where UserFavorite.productid =product.id 
and UserFavorite.id between (@x-1)* 10000 and @x*10000
commit tran
set @x=@x+1
WAITFOR DELAY '00:00:30'; --等待5秒
end

免责声明:文章转载自《SQL Server使用游标或临时表遍历数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Unity创建动画的步骤GDB调试汇编堆栈过程分析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Netty之EventLoop-netty学习笔记(11)-20210813

线程模型概述 基本的线程池化模式可以描述为: 从池的空闲线程列表中选择一个 Thread,并且指派它去运行一个已提交的任务(一个Runnable 的实现);当任务完成时,将该 Thread 返回给该列表,使其可被重用。 虽然池化和重用线程相对于简单地为每个任务都创建和销毁线程是一种进步,但是它并不能 消除由上下文切换所带来的开销,其将随着线程数量的增加很快...

SQL 03

********************2017年8月10日******************** 安装mysql Typical :典型安装Custom :自定义安装Complete:完全安装 简单认知mysql默认端口号是:3306mysql的超级用户叫:root 在cmd中启动mysql服务:net start mysql在cmd中登录mysq...

php连接数据库(一)

1、php链接数据库: 1、链接数据库  2、判断是否连接成功 3、设置字符集 4、选择数据库 5、准备SQL语句 6、发送SQL语句 7、处理结果集 8、释放资源(关闭数据库)   $result = mysqli_querry($link,$sql) //返回一个对象   mysqli_fetch_assoc($result) 一个一个往下读,返回的时...

SQL 语句实现查询子父节点

1. 查询所有父节点 SELECT T2.* FROM ( SELECT @R AS _id, ( SELECT @R := PARENT_ID FROM sys_org WHERE ID = _id ) AS PARENT_ID, @L := @L + 1 AS LVL FROM...

Sql 动态行转列 pivot

最近朋友有个需求:将产品中为“期刊”的书品以行转列的形式展现,同时需要关联工单主表及工单明细表,显示内容为,工单号、操作日期、产品名称及数量,由于期刊的产品数量较多,静态的虽然可以实现,但不利于后续内容的添加,就想着如何能以动态的形式展现,自动拼接sql语句处理,具体实现过程如下。  产品信息表需用到的字段内容: select ProductCode,Na...

ORA-01653: 表 xxxx 无法通过 8192 (在表空间 USERS 中) 扩展

Oracle中增加表空间大小的四种方法 1:给表空间增加数据文件 ALTER TABLESPACE app_data ADD DATAFILE ‘D:ORACLEPRODUCT10.2.0ORADATAEDWTESTAPP03.DBF’ SIZE 50M; 2:新增数据文件,并且允许数据文件自动增长 ALTER TABLESPACE app_data AD...