使用While循环SQL Server更新临时表

时间:2014-04-23 12:54:40

标签: sql sql-server-2008 stored-procedures xml-parsing while-loop

我正在使用以下存储过程,它从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 

但是这个循环结构对我来说似乎不正常,更新语句不回头但效率似乎很慢

0 个答案:

没有答案