1. 程式人生 > >Sql Server在儲存過程裡面使用遊標遍歷一個表

Sql Server在儲存過程裡面使用遊標遍歷一個表

這裡關於SqlServer有兩個知識點:一個是使用遊標遍歷表,另一個是使用if not exists的sql語句進行插入。

一、使用遊標遍歷表

  這個表可以是資料庫的表,也可以是外面DataTable型別的引數傳進去,使用遊標可以概括為以下步驟:宣告遊標、開啟遊標、讀取資料、操作資料、讀取資料、關閉遊標、釋放遊標。

二、在insert語句使用if not exits

  使用了if not exists的語句的insert操作,意思是,在找不到相關資料時才進行insert操作。不同資料庫,有不同的使用語法。

下面是建立儲存過程:

USE [CapacityManagement]
GO

/****** Object:  StoredProcedure [dbo].[USP_uploadResGpMaster]    Script Date: 2018/10/23 16:09:03 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

create type ResGpCap as table
(
ResGp varchar(10),
Plant varchar(12),
Dept varchar(12),
workDate date,
WkHrPerDaily int,
DailyAva int,
Remark varchar(250),
CreateDate datetime,
CreateBy char(8),
ChangeDate datetime,
ChangeBy char(8)
)

go

CREATE PROCEDURE [dbo].[USP_uploadResGpCapacity] @ResGpCap ResGpCap readonly,@OperationType nvarchar(3) 
AS
BEGIN    
	
	SET NOCOUNT ON;
	begin try
	begin transaction
	declare @ResGp varchar(10),
		@Plant varchar(12),
		@Dept varchar(12),
		@workDate date,
		@WkHrPerDaily int,
		@DailyAva int,
		@Remark varchar(250),
		@CreateDate datetime,
		@CreateBy char(8),
		@ChangeDate datetime,
		@ChangeBy char(8),
		@master_id int
	if(@OperationType ='A')
	
	begin
	   --一、宣告遊標
	   declare ResGpCap_cursor cursor for select * from @ResGpCap
	   --二、開啟遊標
	   open ResGpCap_cursor
	   --三、取第一條資料
	   fetch next from ResGpCap_cursor 
			   into @ResGp,
				@Plant,
				@Dept,
				@workDate,
				@WkHrPerDaily,
				@DailyAva,
				@Remark,
				@CreateDate,
				@CreateBy,
				@ChangeDate,
				@ChangeBy 
       --四、操作資料
	   while @@FETCH_STATUS = 0
	   begin
		SELECT @master_id=id FROM [CapacityManagement].[dbo].[ResGp_Master] 
					where resgp = @ResGp
					and	plant = @Plant
					and	dept = @Dept
		--update操作
		update [CapacityManagement].[dbo].[ResGp_Cap]
		set WorkHr = @WkHrPerDaily,
			AvaQty = @DailyAva,
			Remark = @Remark,
			Modified_by = @ChangeBy,
			Modified_on = @ChangeDate
		where master_id = @master_id
		and Valid_Form = @workDate
		and Valid_To = @workDate
		--insert操作
		if not exists(select master_id from [CapacityManagement].[dbo].[ResGp_Cap] where Master_id = @master_id	and Valid_Form = @workDate and Valid_To = @workDate)
		insert into [CapacityManagement].[dbo].[ResGp_Cap](
				Master_id, 
				AvaQty, 
				WorkHr, 
				WorkPer, 
				Valid_Form, 
				Valid_To, 
				Remark, 
				Created_by, 
				Created_on, 
				Modified_by, 
				Modified_on)
			values(
				@master_id,
				@DailyAva,
				@WkHrPerDaily,
				'D',
				@workDate,
				@workDate,
				@Remark,
				@CreateBy,
				@CreateDate,
				@ChangeBy,
				@ChangeDate)
		--五、取下一條資料
		fetch next from ResGpCap_cursor 
			   into @ResGp,
				@Plant,
				@Dept,
				@workDate,
				@WkHrPerDaily,
				@DailyAva,
				@Remark,
				@CreateDate,
				@CreateBy,
				@ChangeDate,
				@ChangeBy 
	   end	  
	   --六、關閉遊標
	   close ResGpCap_cursor
	   --七、釋放遊標
	   deallocate ResGpCap_cursor 
      end  
	  
	 commit transaction
	end try 
	begin catch
	select ERROR_MESSAGE() as errorMessage
	rollback transaction
	end catch

END
GO


註釋也是夠詳細了,操作資料那個過程,業務需求是對一堆資料進行插入,如果該資料已經存在,就進行更新,如果屬於新資料,那麼就進行插入(所以博主想到的是先遍歷全部根據主鍵進行update,再根據主鍵查詢是否存在該資料,若沒有,則插入新資料),其實讀者可以不細看,因為操作過程是根據業務需求,這裡主要講解遊標的使用。