iT邦幫忙

0

[已解決]詢問關閉cursor後為何會印出多筆

因為在程式中有遞迴呼叫自己,因此會跑完整個SP才會再進入SP,故會印出多筆。

如下為原本的問題內容

//-------------------------------------------------

如下舉例只是想表達在cursor中呼叫自己,不具實質意義。
我先傳入0到這個方法中,讓他可以進入if @variable = 0,並將傳入值重新設定為1後呼叫自己,因此下一次會進入if @variable = 1
我想詢問的問題是,在關閉與釋放Cursor後,為什麼還會印出兩次"Print something..."呢?有沒有方式可以讓他只會印出一次呢?

建立有cursor的方法:

if object_id(N'TestFunc') is not null 
	drop procedure TestFunc
go

create procedure TestFunc
	@variable int
as
begin
	set nocount on

	declare 
		@Id int
		, @Name nvarchar(4000)
		, @No nvarchar(4000)
		, @Type nvarchar(4000)

	declare
		 @CursorCount int = 0
		, @CursorSum int = 0

	--@tempTable放結果
	declare @tempTable table (
		[id] int
		, [Name] nvarchar(4000)
		, [No] nvarchar(4000)
		, [Type] nvarchar(4000)
		)

	--定義Cursor並打開
	declare myCursor cursor local for

	--資料集
	select * from TableA

	--開啟游標
	open myCursor

	set @CursorSum = @@cursor_rows

	--迴圈跑Cursor
	fetch next from myCursor into 
		@Id
		, @Name
		, @No
		, @Type

	while(@@fetch_status = 0)					
	begin
		set @CursorCount = @CursorCount + 1

		if @variable = 0
		begin
			insert @tempTable
			select
				@Id
				, @Name
				, @No
				, @Type

			set @variable = 1
			--呼叫自己
			exec TestFunc @variable
		end
		else
		begin
			print '@variable = 1'
		end

		--抓下一筆
		fetch next from myCursor into 
		@Id 
		, @Name
		, @No
		, @Type
	end	

	--關閉與釋放Cursor
	close myCursor
	deallocate myCursor

	select * from @tempTable 
	print 'Print something...'

    return 
end

呼叫方法:

declare @testTable table (
	[id] int
	, [Name] nvarchar(4000)
	, [No] nvarchar(4000)
	, [Type] nvarchar(4000)
	)

insert @testTable
exec TestFunc 0

select * from @testTable

結果:
https://ithelp.ithome.com.tw/upload/images/20190418/20115336FphRTDjtJd.pnghttps://ithelp.ithome.com.tw/upload/images/20190418/201153367mBBO81EcY.png

1 個回答

0
舜~
iT邦新手 2 級 ‧ 2019-04-18 14:49:30

TestFunc裡面的呼叫自已....能不能拿掉或改寫??

不然跑兩次...

看更多先前的回應...收起先前的回應...
anniecat iT邦新手 5 級 ‧ 2019-04-18 14:59:55 檢舉

嘗試過另外建一個Func去跑cursor,在用一個SP去呼叫Func,但會各做一次insert到@tempTable,所以出現如下訊息...

INSERT EXEC 陳述式不可以是巢狀的。

舜~ iT邦新手 2 級 ‧ 2019-04-18 15:15:07 檢舉

如果把 --呼叫自己 exec TestFunc 1 放到迴圈外呢?

while(@@fetch_status = 0)
begin ... end
--關閉與釋放Cursor
close myCursor
deallocate myCursor
    
if @variable = 0
begin 
    exec TestFunc 1 
end
anniecat iT邦新手 5 級 ‧ 2019-04-18 15:37:46 檢舉

我原本的需求內容會是每一列去判斷的,因此這樣可能就不符合我要的邏輯了...
另外,我上述遇到的問題,看到網路上說明建立linkserver可以解決,但我尚未成功,這部份提供你參考~

anniecat iT邦新手 5 級 ‧ 2019-04-18 16:25:49 檢舉

我原本以為Cursor執行完後才會繼續往下執行,但看起來因為在裡面有呼叫自己,所以會跑完整個SP的內容,才會再次進入SP...

舜~ iT邦新手 2 級 ‧ 2019-04-19 09:02:36 檢舉

會先進入呼叫自己的sp執行完畢離開後,才會回到剛剛執行到一半的sp執行完畢,你當成一般函數呼叫就可以了,只不過該函數是自己~~

我要發表回答

立即登入回答