2009-11-16 3 views
1

나는 다음과 같은 형식의 XML 문서가 있습니다. 이 데이터를 SQL Server 테이블에 삽입해야합니다. 내 테이블이 스키마가 : 그래서 나는 XML 열이있는 임시 테이블에 내 xml 파일을 가져온삽입 XML 데이터

CREATE TABLE [dbo].[Questions](
    [ImportQuestionID] [int] IDENTITY(1,1) NOT NULL, 
    [TopicName] [varchar](100) NULL, 
    [DepartmentName] [varchar](100) NULL, 
    [ParentDepartmentName] [varchar](100) NULL, 
    [QuestionID] [int] NOT NULL, 
    [SurveyID] [int] NOT NULL, 
    [ResponseID] [int] NOT NULL, 
    [PageNumber] [int] NOT NULL, 
    [OrderNumber] [int] NOT NULL, 
    [Result] [varchar](10) NULL, 
    [GroupName] [varchar](100) NULL, 
    [QuestionText] [varchar](500) NOT NULL, 
    [AnswerText] [varchar](500) NOT NULL, 
    [Comment] [varchar](500) NULL, 
    [Reference] [varchar](500) NULL) 

을 지금은 파일을 구문 분석하고 관계형 테이블에 넣어 노력하고있어. 여기

내가 노력하고있어입니다 :

INSERT INTO [SRCL_XmlTest].[dbo].[Questions] 
      field list... 
SELECT tab.col.value('./topic/@name', 'varchar(100)') as TopicName, 
     tab.col.value('./topic/department/@name', 'varchar(100)') as DepartmentName, 
     tab.col.value('./topic/department/@parent', 'varchar(100)') as ParentDepartmentName, 
     tab.col.value('./topic/department/questionH/@questionID', 'int') as QuestionID, 
     tab.col.value('./topic/department/questionH/@surveyID', 'int') as SurveyID, 
     tab.col.value('./topic/department/questionH/@responseID', 'int') as ResponseID, 
     tab.col.value('./topic/department/questionH/@pageNumber', 'int') as PageNumber, 
     tab.col.value('./topic/department/questionH/@orderNumber', 'int') as OrderNumber, 
     tab.col.value('./topic/department/questionH/@result', 'varchar(10)') as ResultColourCode, 
     tab.col.value('./topic/department/questionH/@group', 'varchar(100)') as GroupName, 
     tab.col.value('./topic/department/questionH/question', 'varchar(500)') as QuestionText, 
     tab.col.value('./topic/department/questionH/answer', 'varchar(500)') as AnswerText, 
     tab.col.value('./topic/department/questionH/comment', 'varchar(500)') as Comment, 
     tab.col.value('./topic/department/questionH/reference', 'varchar(500)') as Reference 
FROM FileImport 
CROSS APPLY 
XmlData.nodes('//response/topics') AS tab(col) 

을하지만, 나는 오류가 계속 : XQuery는 [FileImport.XmlData.value는()는] '값은()'싱글 톤 (또는 빈 시퀀스)가 필요합니다 , 'xdt : untypedAtomic *'유형의 피연산자를 찾았습니다

XML에 여러 주제 노드가 있기 때문입니까? XmlData.nodes ('응답/주제/주제/부서/questionHead/질문') AS 탭 (열)

이제 질문에 액세스 할 수 있지만 ' 답을 찾을 수있는 곳이면 어디든 갈 수 있습니다. 어떤 아이디어가 있니?

+0

중복 : http://stackoverflow.com/questions/1302064/sql-server-2005-xml-query-works-value-requires-singleton-found-xdtuntype –

답변

4

넣어 모든 xml.value에서 싱글 :

tab.col.value('(./topic)[1]/@name', 'varchar(100)') 
tab.col.value('(./topic/department)[1]/@name', 'varchar(100)') 
... 

Whitouth을 XML 스키마 선언은 SQL이 주제/주제가 무엇인지 추측 할 수있는 방법이 없다. 싱글 톤이므로 명시 적으로 강제로 (...)[1]을 사용해야합니다. 당신의 XML 여러 < 주제에게 < 주제 > 부모 > 요소가있는 경우

업데이트

는 쿼리가 잘못되었습니다. 당신은 nodestopic를 이동해야합니다

SELECT 
tab.col.value('@name',...) 
tab.col.value('(./department)[1]',...) 
... 
FROM ... 
CROSS APPLY ... nodes('//response/topics/topic') as tab(col); 

당신이 모든 주제 노드에서 각 주제에 대한 행을 투사 이쪽으로. 원래 검색어는 각 주제 상위에서 하나의 주제 만 선택할 수 있습니다.

+0

아마 'CROSS APPLY ... 노드 ('/ 응답/주제/주제 ')를 탭 (열)으로 사용해야합니다.', 아니요? 나는'/ topics/topic' XPath 표현식이 유용한 것을 선택하는 것을 의심합니다 ..... –

+0

@marc : 제 편집에서 원래 쿼리가 없었기 때문에 그냥 메모리에서 입력했습니다. 나는 혼란을 피하기 위해 편집 할 것입니다. –

+0

정확한 해결책이 아니었지만 나를 올바른 길로 인도했습니다. 내 xpath는 다음과 같아야합니다. XmlData.nodes('//response/topics/topic/department/questionHead') AS tab(col).내가 가장 자식 노드로 이동하고 다시 내 방식으로 작동하는 데 필요한 그래서 본질적으로 SELECT tab.col.value('../../@name', 'varchar(100)') as TopicName, tab.col.value('../@name', 'varchar(100)') as DepartmentName, tab.col.value('@questionID', 'int') as QuestionID, tab.col.value('./question[1]', 'varchar(500)') as QuestionText : 또한 다음 내 선택 목록과 유사 할 필요가 (나머지는 간결 왼쪽) –

1

것은 예를 들어 당신의 .value()의 XPath는 내부 [1]를 사용해보십시오 :

tab.col.value('./topic[1]/@name', 'varchar(100)') 

대신 단지

tab.col.value('./topic/@name', 'varchar(100)') 
+0

내 대답을 다시 편집하는 중이었습니다. . – Nestor