請問資料庫 cursor 的問題 |
尚未結案
|
lsh998
中階會員 發表:163 回覆:138 積分:60 註冊:2005-01-07 發送簡訊給我 |
数据库 :SQL SERVER 2000 各位大哥:
我有三个表: 1:TemporaryStoreroomTable //临时新增表 动态的创建 2:StoreroomTable//保存所有 临时新增表的数据 (orderid varchar(50), masterid varchar(50), mastername varchar(100), numbers int, times datetime PRIMARY KEY(IncomeStoreroomId,OperateTime), ) 3:AllStoreroomTable//总数量表 (masterid varchar(50), numbers int, ) 和两个存储过程: //**********每次需要新增数据时,便创建此表,把需要插入的数据 先保存到此表 CREATE procedure ProceCreateTemporaryStoreroomFormTable as if Exists(select 1 from dbo.sysobjects where xtype = 'U' and name = 'TemporaryStoreroomTable') begin drop table TemporaryStoreroomTable end create table TemporaryIncomeStoreroomFormTable ( orderid varchar(50), masterid varchar(50), mastername varchar(100), numbers int, times datetime PRIMARY KEY(IncomeStoreroomId,OperateTime), ) GO //**********每次需要新增数据时,便创建此表,把需要插入的数据 先保存到此表 //如果 TemporaryStoreroomTable 表的数据需要真正的提交才运行此存储过程 CREATE procedure ProcInsertStoreroomTable as declare @orderid varchar(50), @masterid varchar(50), @mastername varchar(100), @numbers int, @times datetime declare @InsertIncomeStoreroom_Cursor CURSOR begin begin tran insert StoreroomTable(orderid,masterid,mastername,numbers,times) select orderid,masterid,mastername,numbers,times from TemporaryStoreroomTable if @@error<>0 begin raiserror('操作不成功',16,1) rollback tran return end SET @InsertIncomeStoreroom_Cursor=CURSOR SCROLL DYNAMIC FOR SELECT orderid,masterid,mastername,numbers,times FROM TemporaryStoreroomTable OPEN @InsertIncomeStoreroom_Cursor FETCH NEXT FROM @InsertIncomeStoreroom_Cursor INTO @orderid,@masterid,@mastername,@numbers,@times WHILE @@FETCH_STATUS=0 BEGIN if exists(select * from AllStoreroomTable where masterid=@masterid) begin update AllStoreroomTable set numbers=numbers @ numbers where masterid=@masterid if @@error<>0 or @@rowcount<>1 begin raiserror('操作不成功',16,1) rollback tran return end end else begin insert AllStoreroomTable(masterid,masterid) values (@masterid,@masterid) if @@error<>0 or @@rowcount<>1 begin raiserror('操作不成功',16,1) rollback tran return end end end FETCH NEXT FROM @InsertIncomeStoreroom_Cursor INTO @orderid,@masterid,@mastername,@numbers,@times end CLOSE @InsertIncomeStoreroom_Cursor DEALLOCATE @InsertIncomeStoreroom_Cursor if @@error=0 commit tran else rollback tran end GO //如果 TemporaryStoreroomTable 表的数据需要真正的提交才运行此存储过程 各位大哥,现在的问题是,ProcInsertStoreroomTable 我用到了游标,他们说游标的速度会很慢(我不知道是不是真的),各位大哥,是不是这样啊?还有可以不通过游标, 利用别的方法可以实现吗? 还有 我对一个字段建立了主键 ,是不是就相当于对此字段建立了主索引啊? 谢谢 各位大哥! |
lsh998
中階會員 發表:163 回覆:138 積分:60 註冊:2005-01-07 發送簡訊給我 |
|
pgdennis
資深會員 發表:41 回覆:526 積分:443 註冊:2002-05-23 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
Hi, 你在 sp 中的 cursor 可以利用下面兩道 command 替代, 效能會更好, update AllStoreroomTable set numbers = numbers (select isnull(sum(numbers), 0) from TemporaryStoreroomTable where masterid = AllStoreroomTable.masterid)
insert into AllStoreroomTable(masterid, numbers) select masterid, sum(numbers) from TemporaryStoreroomTable where masterid not in (select masterid from AllStoreroomTable) group by masterid 但 cursor 效能不好的部分, 看用法, 若是有複雜的運算邏輯, 不得不用的話, 就用吧, 但看你的 code , 應該只是判斷有就 update , 沒有就 insert , 這樣用異動指令就可以完成的話, 就可以不用 cursor 囉!
|
lsh998
中階會員 發表:163 回覆:138 積分:60 註冊:2005-01-07 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
|
lsh998
中階會員 發表:163 回覆:138 積分:60 註冊:2005-01-07 發送簡訊給我 |
|
mike0518tw
一般會員 發表:5 回覆:5 積分:2 註冊:2004-03-24 發送簡訊給我 |
關於crusor 的運用 參考
/*
英文版 Advanced Transact-SQL for SQL Server 2002
作者 : Itzik Ben-Gen / Tom Moreau , Ph.D
中文翻譯 T-SQL 程式設計徹底研究
譯者 : 余宗恩 / 陳永昱
*/
參考第15章 15-1
摘錄一下文章大意
使用cursor的五個理由
1. sql 理解不夠
2. schema 開的不好
3. 特殊 business rule
4. 需要對每ㄧ列作處理的 store procedure
5. 過大的資料切割 .像是一個sql 可能就做出上億的 transaction log ,讓raw device爆掉. 根據在下的本人學習經驗 ,到現在還是, 唉!
都是前兩大理由比較多 ..
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |