我正在使用以下存储过程,它从XML数据中获取日期值并将它们解析为临时表中的MonthDate字段。然后我尝试循环遍历不同的序列化xml数据集,并基本上更新相应的列以创建一个按MonthDate分组的大型数据集。我的SPROC是;
--declare outputTable as original temp table to store date and simulation values
Declare @outputTable TABLE (ID int identity, MonthDate datetime, Col2 float, Col3 float, Col4 float, Col5 float, Col6 float, Col7 float, Col8 float, Col9 float, Col10 float, Col11 float)
Declare @rowCount int
--Retrieve month list from XML Data for simulations, and receive count of month results
Declare @medianResult nvarchar(max)
Declare @ngTestMonth Table(XmlContent XML)
declare @MonthCount varchar(max)
Declare @MonthDate datetime
Insert into @ngTestMonth(XMLContent)(SELECT Cast(Cast(Data as ntext) as XML) FROM [Accounts].[dbo].[GoalChartData] where goalID = 3661 and typeID = 2)
Insert into @outputTable(MonthDate)(SELECT
x.value('MonthDate[1]','DateTime')
From @ngTestMonth
CROSS APPLY XmlContent.nodes('//MonthlyAmount') n(x))
--SELECT * from @outputTable
--get actual data for Goal by GoalID, and parse out serialized data values from Median results and simulations
Declare @MonteCarloData varchar(max)
Declare @ngTest2 Table(XmlContent XML)
DECLARE @numRows int
DECLARE @numDataSets int = 1
Declare @StringValue varchar(max)
Declare @dataString varchar(max)
Declare @tempVar varchar(max)
Insert into @ngTest2(XMLContent)(SELECT Cast(Cast(Data as ntext) as XML) FROM [Accounts].[dbo].[GoalChartData] where goalID = 3661 and typeID = 2)
set @MonteCarloData = (SELECT
x.value('SerializedData[1]','nvarchar(max)') as MonteCarloData
From @ngTest2
CROSS APPLY XmlContent.nodes('//GoalMonteCarloChartResult') n(x))
--get number of result rows to know how long to loop through and insert into temporary table
set @numRows = (SELECT count(*) from [dbo].split(@MonteCarloData,'['))
Declare @col varchar(5)
Declare @sql nvarchar(1000)
WHILE @numDataSets <= @numRows
BEGIN
set @dataString = (SELECT Data from [dbo].Split(@MonteCarloData,'[') where Id = @numDataSets)
while Len(@dataString) > 0
set @rowCount = 1
BEGIN
--select @dataString
set @StringValue = Left(@dataString,ISNULL(NULLIF(CHARINDEX(',', @dataString) - 1, -1),
LEN(@dataString)))
set @dataString = SUBSTRING(@dataString,ISNULL(NULLIF(CHARINDEX(',',@dataString),0),
LEN(@dataString)) + 1, LEN(@dataString))
--select @StringValue
Set @StringValue = Replace(@StringValue,'[','')
Set @StringValue = Replace(@StringValue,']','')
Set @col = 'Col' + Convert(varchar(max),@numDataSets)
set @sql = N'Update @outputTable set ' + @col + ' = ' + @StringValue + ' Where ID = ' + Convert(nvarchar(10),@rowCount)
--select @sql
exec sp_executesql @sql;
set @sql = ''
set @rowCount = @rowCount + 1
--select @numDataSets
END
set @numDataSets = @numDataSets + 1
set @rowCount = 0
END
SELECT * from @outputTable
我想要的是一旦这段代码被循环并按ID更新表。我知道日期总会有113条记录,因为这就是模拟的工作原理,总会有11个数据集出来,所以它就像是这样;
Declare @col varchar(5)
Declare @sql nvarchar(1000)
WHILE @numDataSets <= @numRows
BEGIN
set @dataString = (SELECT Data from [dbo].Split(@MonteCarloData,'[') where Id = @numDataSets)
while Len(@dataString) > 0
**set @rowCount = 1****Start at first record, i believe i would loop here**
BEGIN
***While @rowCount <= 113***
--select @dataString
set @StringValue = Left(@dataString,ISNULL(NULLIF(CHARINDEX(',', @dataString) - 1, -1),
LEN(@dataString)))
set @dataString = SUBSTRING(@dataString,ISNULL(NULLIF(CHARINDEX(',',@dataString),0),
LEN(@dataString)) + 1, LEN(@dataString))
--select @StringValue
Set @StringValue = Replace(@StringValue,'[','')
Set @StringValue = Replace(@StringValue,']','')
Set @col = 'Col' + Convert(varchar(max),@numDataSets)
set @sql = N'Update @outputTable set ' + @col + ' = ' + @StringValue + ' Where ID = ' + Convert(nvarchar(10),@rowCount)
--select @sql
exec sp_executesql @sql;
set @sql = ''
set @rowCount = @rowCount + 1
***END***
--select @numDataSets
END
set @numDataSets = @numDataSets + 1
set @rowCount = 0
--reset @rowCount to 0--
END
SELECT * from @outputTable
但是这个循环结构对我来说似乎不正常,更新语句不回头但效率似乎很慢