sqlserver游标使用误区
在使用游标出现逻辑错误时,查阅资料,只有改掉while中的游标取值在while循环最后,没有说明while以前会出现的错误,而且没有具体说明原因,今天在工作中解决了这个问题,写了这个博客,希望对使用游标少的园友有帮助,也给自己提个醒。
按照游标的规则使用时,在使用游标取到数据时后进行操作在逻辑上正确,但是会造成数据异常,在正常流程下逻辑正确,所以很难发现其中的逻辑错误,下面是工作时的例子,以及解决的具体流程。
好久没用游标,今天查了下资料开始使用,但是出现问题:
--插入客户信息
create synonym synonym_project for [192.168.159.134].[VisualNet].[dbo].project
declare @prjkey varchar(50)
declare @customername varchar(50)
declare @khbh char(4) declare cursor_project cursor for
select prjname,prjkey from synonym_project open cursor_project fetch next from cursor_project into @customername,@prjkey if not exists(select 1 from Customers where gsmc = @customername)
select @khbh = MAX(khbh)+1 from Customers
insert into Customers(khbh,gsmc,gsdz,gsdh) values(@khbh,@customername,'','') while @@FETCH_STATUS=0
begin
fetch next from cursor_project into @customername,@prjkey if not exists(select 1 from Customers where gsmc = @customername)
select @khbh = MAX(khbh)+1 from Customers
insert into Customers(khbh,gsmc,gsdz,gsdh) values(@khbh,@customername,'','') end close cursor_project
deallocate cursor_project drop synonym synonym_project
这里使用同义词和游标远程查询数据。
因为:
open cursor_project fetch next from cursor_project into @customername,@prjkey
打开游标后需要先取一条数据才能进行while循环读取,所以我在取到数据后进行插入操作
然后while循环中也会再进行数据读取,在读取后再进行插入操作。
但是执行后发生错误:违反唯一约束
我查看了远程表,所有的数据都完整的插入到表中,并没有遗失的数据,不知道从哪里多了一条数据,所以讲数据处理换为打印查看数据:
--插入客户信息
create synonym synonym_project for [192.168.159.134].[VisualNet].[dbo].project
declare @prjkey varchar(50)
declare @customername varchar(50)
declare @khbh char(4) declare cursor_project cursor for
select prjname,prjkey from synonym_project open cursor_project fetch next from cursor_project into @customername,@prjkey
print @customername while @@FETCH_STATUS=0
begin
fetch next from cursor_project into @customername,@prjkey
print @customername end close cursor_project
deallocate cursor_project drop synonym synonym_project
结果如下:
Test1
南通心智慧
港闸区
港闸区
但是在远程表中'港闸区'只有一个,所以是最后一条数据重复了,然后百度一下看看别人是不是出现过:http://zhidao.baidu.com/link?url=wNi65XcABENt3DV_VJJHILlHWTNYdsMYzX7b25RmGACPIwsLjAUkWVz0qIFzlfwC7fK5S5-71t5196I5wJ4gRa
回答是说取数据应该是在while后面,所以我把游标获取数据放在循环最后:
--插入客户信息
create synonym synonym_project for [192.168.159.134].[VisualNet].[dbo].project
declare @prjkey varchar(50)
declare @customername varchar(50)
declare @khbh char(4) declare cursor_project cursor for
select prjname,prjkey from synonym_project open cursor_project fetch next from cursor_project into @customername,@prjkey
print @customername while @@FETCH_STATUS=0
begin print @customername
fetch next from cursor_project into @customername,@prjkey
end close cursor_project
deallocate cursor_project drop synonym synonym_project
运行结果:
Test1
Test1
南通心智慧
港闸区
发现第一条数据重复,也就是说两次打印有一次是多余的,因为要遍历数据,所以循环里面的打印肯定是必须的,上面的打印可能是多余的,如果把上面的打印删除,游标取数据在打印之后,循环内部打印在游标取数据之前,就不会有上一条数据丢失:
--插入客户信息
create synonym synonym_project for [192.168.159.134].[VisualNet].[dbo].project
declare @prjkey varchar(50)
declare @customername varchar(50)
declare @khbh char(4) declare cursor_project cursor for
select prjname,prjkey from synonym_project open cursor_project fetch next from cursor_project into @customername,@prjkey while @@FETCH_STATUS=0
begin print @customername
fetch next from cursor_project into @customername,@prjkey
end close cursor_project
deallocate cursor_project drop synonym synonym_project
结果如下:
Test1
南通心智慧
港闸区
这样就正确了,相同于打印, 对数据进行插入操作的逻辑也是这样,讲打印改成需要的数据操作:
--插入客户信息
create synonym synonym_project for [192.168.159.134].[VisualNet].[dbo].project
declare @prjkey varchar(50)
declare @customername varchar(50)
declare @khbh char(4) declare cursor_project cursor for
select prjname,prjkey from synonym_project open cursor_project fetch next from cursor_project into @customername,@prjkey while @@FETCH_STATUS=0
begin if not exists(select 1 from Customers where gsmc = @customername)
select @khbh = MAX(khbh)+1 from Customers
insert into Customers(khbh,gsmc,gsdz,gsdh) values(@khbh,@customername,'','')
fetch next from cursor_project into @customername,@prjkey
end close cursor_project
deallocate cursor_project
这样就正确了,对游标使用很少经常会出现这个问题,因为普通的逻辑就会出现最后数据重复,必须使用游标的逻辑格式。
sqlserver游标使用误区的更多相关文章
- Sqlserver游标复习
经常写存储过程,但今天在游标使用过程中还是疏忽了一些事情,执行过程中一直执行不下去,后来直接sqlserver挂了,教训啊! 代码虽简单,望铭记: Create PROCEDURE [dbo].[te ...
- SqlServer游标的创建与使用
前言 大家都对SqlServer视图.存储过程.触发器的创建与使用有一定的了解了,我们来看下什么是游标,怎么使用,什么时候用. SqlServer视图的创建与使用 SqlServer存储过程的创建与使 ...
- sqlserver 游标的使用
declare @temp_temp uniqueidentifier--临时变量 DECLARE aaa CURSOR for select Id from A ------------------ ...
- SqlServer游标简介
游标实例: Declare MyCusror Cursor Scroll For Select * From Master_Goods Order By GoodsID Ope ...
- sqlserver 游标
DECLARE ChangeInvCodeCursor CURSOR FOR SELECT A.name AS tablecolumn,C.name AS tablename FROM sys.col ...
- SQLServer游标(Cursor) (B)
游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力.我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许 ...
- SQLServer 游标 (A)
游标 游标分为客户端游标和服务器端游标.Sql通过游标可以对一个结果集进行逐行处理.对于使用服务器端游标的过程有:声明.打开.读取.关闭.释放. 1 声明游标 1.1 SQL-92标准的声明 Decl ...
- SQLserver游标原理和使用方法
在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句.但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录.那么如何解决这种问题呢 ...
- (转)sqlserver游标概念与实例全面解说
首先声明:该文章转自http://www.cnblogs.com/wudiwushen/archive/2010/03/30/1700925.html 的博客 引言 我们先不讲游标的什么概念,步骤 ...
随机推荐
- POJ 1201 差分方程分析
POJ 1201 给你N个闭区间.每个区间分别为[ai,bi],你必须在这个区间上至少取ci个不同的整数. 现要求所有区间满足各自的条件. 问最少需要选多少个点. 例如[3,7](3) [8,10] ...
- 【链表】2017多校训练三 HDU 6058 Kanade's sum
acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k ...
- 【HDOJ6298】Maximum Multiple(数论)
题意:给定n,求x,y,z三个整数,使得x|n,y|n,z|n,且xyz最小 n<=1e6 思路: 不定方程1/x+1/y+1/z=1 只有(2,3,6)(2,4,4) (3,3,3)三组正整数 ...
- iOS 用cornerstone 创建分支
第一步:在cornerstone中添加服务器上的代码路径,如下: 第二步:选中服务器路径下的代码,选择“分支”按钮 第三步:开始创建分支 第四步:效果图如下 第五步:选择分支下的路径下载代码并进行修改 ...
- Cooking Schedule Problem Code: SCHEDULE(优先队列)
Cooking Schedule Problem Code: SCHEDULE Chef is a well-known chef, and everyone wishes to taste his ...
- 洛谷——P1951 收费站_NOI导刊2009提高(2)
https://www.luogu.org/problem/show?pid=1951 题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,…,n. 这个国家的政府修建了m条双向的公路.每条公 ...
- Spring基础入门(二)
一.AOP 1.AOP概念 aop:面向切面编程,扩展功能不修改源代码实现. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码. 2.AOP原理 (1)第一种情况,有接口情况,使用动态代理创建 ...
- java课堂测试—根据模板完成一个简单的技术需求征集系统
课堂上老师发布了一个页面模板要求让我们实现一个系统的功能,模仿以后后端的简单工作情况. 然后在这个模板的基础上,提供了一个注册的网页模板,接着点击注册的按钮,发现register里面调用了zhu/zh ...
- 2018.11.5 PION模拟赛
期望:30 + 40 + 50 = 120 实际:30 + 50 + 40 = 120 ‘’ 思路:最重要的是发现 是完全没有用的,然后这个题目就可以转成DP来做. /* 期望的分:30 */ #in ...
- 使用Spring Data Redis操作Redis(单机版)
说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...