2011-09-27 42 views
3

我做這樣的事情:存儲過程讀取XML,任何方式更好地做到這一點? SQL SERVER 2008

CREATE PROCEDURE [dbo].[InsertStudents] 
(
    @students nvarchar(max) 
) 
AS 
DECLARE @studentstable TABLE 
(
    RowIndex int, 
    FirstName nvarchar(50), 
    LastName nvarchar(50), 
    Number nvarchar(20), 
    IdSchool int 
) 
DECLARE @xmldata xml 
SET @xmldata = @students 
INSERT INTO @studentstable 
SELECT S.Stud.query('./RowIndex').value('.','int') RowIndex, 
     S.Stud.query('./FirstName').value('.','nvarchar(50)') FirstName, 
     S.Stud.query('./LastName').value('.','nvarchar(50)') LastName, 
     S.Stud.query('./Number').value('.','nvarchar(50)') Number, 
     S.Stud.query('./IdSchool').value('.','int') IdSchool, 
FROM @xmldata.nodes('/Students/Student') AS S(Stud) 

DECLARE @totalrows int 
DECLARE @currentrow int 
DECLARE @totalinserts int 

DECLARE @currentfirstname nvarchar(50) 
DECLARE @currentlastname nvarchar(50) 
DECLARE @currentnumber nvarchar(20) 
DECLARE @currentidschool int 

DECLARE @insertresult int 

SET @totalinserts = 0 
SET @totalrows=(SELECT COUNT(*) FROM @studentstable) 
SET @currentrow=0 

WHILE(@currentrow<@totalrows) BEGIN 
    SELECT @currentfirstname = FirstName, @currentlastname = LastName, @currentnumber = Number, @currentidschool = IdSchool 
    FROM @studentstable 
    WHERE [email protected] 
    EXEC @insertresult = InsertStudent @currentfirstname, @currentlastname, @currentnumber, @currentidschool 
    IF @insertresult=0 BEGIN 
     SET @[email protected]+1 
    END 
    SET @currentrow = @currentrow + 1 
END 
SELECT @totalinserts 

InsertStudent返回0,如果插入工作或1如果已經存在與該號碼的學生。

難道沒有辦法做到這一點,而不與該變量表混淆?

+4

您正在使用哪個版本的SQL Server?如果您使用的是2008或更高版本,我建議您閱讀['MERGE'](http://msdn.microsoft.com/zh-cn/library/bb510625.aspx)語法(並重構以使' InsertStudent'調用'InsertStudents') –

回答

2

類似這樣的使用merge

merge Student 
using (select S.Stud.query('./RowIndex').value('.','int') RowIndex, 
       S.Stud.query('./FirstName').value('.','nvarchar(50)') FirstName, 
       S.Stud.query('./LastName').value('.','nvarchar(50)') LastName, 
       S.Stud.query('./Number').value('.','nvarchar(50)') Number, 
       S.Stud.query('./IdSchool').value('.','int') IdSchool 
     from @xmldata.nodes('/Students/Student') as S(Stud)) as SXML 
on Student.Number = SXML.Number 
when not matched then 
    insert (FirstName, LastName, Number, IdSchool) 
    values (SXML.FirstName, SXML.LastName, SXML.Number, SXML.IdSchool); 

select @@rowcount 
+0

插入一個學生的存儲過程也會在其他表中執行insters,所以可以做如下事情:當不匹配時,然後開始....執行某些邏輯(事務或某事) ...結束 ? – gigi

+0

@吉吉 - 不,它不是。但是,您可以使用output子句來捕獲更新到表變量中的行,然後可以使用該表變量來執行更新後的行的其他邏輯。 http://msdn.microsoft.com/en-us/library/ms177564.aspx –

相關問題