將Cursor地宣告調整為 declare
myCursor cursor local for
即可。
如下為原本的問題內容
//-----------------------------------------------------------
我有一張表,是傳入的Json字串到自行定義的FunctionParseJson
做解析後回傳。
--定義變數
declare @Type nvarchar(max)=N'Book'
declare
@json nvarchar(max)=N'{
"Book":{
"IssueDate":"02-15-2019"
, "Detail":{
"Type":"Any Type"
, "Author":{
"Name":"Annie"
, "Sex":"Female"
}
}
, "Chapter":[
{
"Section":"1.1"
, "Title":"Hello world."
}
,
{
"Section":"1.2"
, "Title":"Be happy."
}
]
, "Sponsor":["A","B","C"]
}
}'
select
*
from
ParseJson(@json, @Type, 0)
我的目的是要逐筆判斷每列isTerminal的值,
當isTerminal=0時,呼叫方法Function:ParseJson
,繼續做分解,再依據分解後回傳的table,繼續逐筆判斷;
當isTerminal=1,呼叫StoreProcedure:InsertToDB
,將值存入TableA
以及一些其他邏輯作業。
因此我嘗試使用Cursor,並在Cursor中加入遞迴呼叫自己
if object_id(N'CursorJson') is not null
drop procedure CursorJson
go
create procedure CursorJson
@json nvarchar(max)
, @Type nvarchar(max)
, @isArray bit = 0
as
begin
set nocount on
--定義存放的變數
declare
@TopKey nvarchar(4000)
, @Key nvarchar(4000)
, @IsType bit
, @IsList bit
, @isTerminal bit
, @Value nvarchar(4000)
--@tempTable放結果
declare @tempTable table(
@TopKey nvarchar(4000)
, @Key nvarchar(4000)
, @IsType bit
, @IsList bit
, @isTerminal bit
, @Value nvarchar(4000))
--定義Cursor並打開
declare myCursor cursor for
--資料集,其長相可參考第一張圖
select * from ParseJson(@json, @Type, @isArray)
--開啟游標
open myCursor
--print @@cursor_rows --查看總筆數
--迴圈跑Cursor
fetch next from myCursor into
@TopKey nvarchar(4000)
, @Key nvarchar(4000)
, @IsType bit
, @IsList bit
, @isTerminal bit
, @Value nvarchar(4000)
while(@@fetch_status = 0) --放入迴圈條件
begin
if @isTerminal = 0
begin
set @json = '{"' + @Key + '":' + @Value + '}'
--遞迴呼叫自己
exec CursorJson @json, @Key, @isList
end
else
begin
exec InsertToDB @TopKey, @Key, @Value
end
--抓下一筆
fetch next from myCursor into
@TopKey nvarchar(4000)
, @Key nvarchar(4000)
, @IsType bit
, @IsList bit
, @isTerminal bit
, @Value nvarchar(4000)
end
--關閉與釋放Cursor
close myCursor
deallocate myCursor
return
end
另外,目前可以成功執行create procedure,
但執行時會跑出如下錯誤訊息,請問能夠這樣做嗎?
declare @Type nvarchar(max)=N'Book'
declare
@json nvarchar(max)=N'{
"Book":{
"IssueDate":"02-15-2019"
, "Detail":{
"Type":"Any Type"
, "Author":{
"Name":"Annie"
, "Sex":"Female"
}
}
, "Chapter":[
{
"Section":"1.1"
, "Title":"Hello world."
}
,
{
"Section":"1.2"
, "Title":"Be happy."
}
]
, "Sponsor":["A","B","C"]
}
}'
exec CreateInstanceJson @json,'Application',0
程序 CreateInstanceJson,行 27 [批次開始行 0]名稱為 'myCursor' 的資料指標已經存在。
【補充】PraseJson
是Function,其作用是將傳入的Json字串使用sql的openJson分解成key、value(2016以上的版本才有),並透過sql的isJson去判斷是不是Terminal的值(0:Non-terminal; 1:Terminal),回傳結果table變數。
InsertToDB
是Stored Procedure,其作用是將key、value做insert到tableA中。
TableA
的長相
我發問的困難點在於,因為是專案的內容,而以上兩個方法的內容牽涉的table與額外呼叫的函數較多,因此無法附上完整的code,所以使用敘述的方式說明,請見諒!