XML - add a namespace not in root - sql-server

I need to build XML in SQL Server that has this format. You can see there are two XMLNAMESPACES on the first line but there is a third one further down next to Location.
<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypes">
<stuff>
<Description>blue</Description>
<Location xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues">
<d3p1:Code>64</d3p1:Code>
<d3p1:Description>Balloons</d3p1:Description>
</Location>
</stuff>
</arrayofstuff>
Here is what I have so far, with some sample data. It looks like there is a nested for XML query within the first query, but I can't seem to use the WITH statement a second time since it has to be the first command in a batch, so I'm not sure what to do.
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('myTable'))
BEGIN;
DROP TABLE [myTable];
END;
GO
CREATE TABLE [myTable] (
[myTableID] INTEGER NOT NULL IDENTITY(1, 1),
[Description] VARCHAR(MAX) NULL,
[sourceID] INTEGER NOT NULL ,
[Location] VARCHAR(255) NULL,
[Code] VARCHAR(255) NULL,
[Location_Desc] VARCHAR(255) NULL,
PRIMARY KEY ([myTableID])
);
GO
INSERT INTO myTable([SourceID],[Description],[Location],[Code],[Location_Desc])
VALUES(3,'yellow','Oxford County','64','list'),
(3,'blue','Fraser Lake','64','list'),
(2,'red','San Marcello Pistoiese','64','list'),
(2,'green','Gembloux','64','list'),
(2,'green','Yeongcheon','64','list')
GO
WITH XMLNAMESPACES (default 'http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess', 'http://www.w3.org/2001/XMLSchema-instance' as i )
SELECT
[sourceID]
,cast(stuff((
SELECT
[Description] as [Description]
,[Code] AS [Location/Code]
,[Location_Desc] AS [Location/Description]
FROM [myTable] mnbm
where mnbm.[sourceID] = p.[sourceID]
for xml path('stuff'), root ('arrayofstuff')
),1,0,'') as xml) as Ids
from [myTable] p
group by
p.[sourceID]
Here is the result of my output currently:
<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess">
<stuff>
<Description>commodo</Description>
<Location>San Marcello Pistoiese</Location>
</stuff>
<stuff>
<Description>ipsum</Description>
<Location>Gembloux</Location>
</stuff>
<stuff>
<Description>ipsum</Description>
<Location>Yeongcheon</Location>
</stuff>
</arrayofstuff>

Is there some specific reason why xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues" has to appear on the Location element? Namespaces can be defined anywhere in an XML document, so long as they're defined before they're referenced, so you can define it on the root element as part of WITH XMLNAMESPACES, e.g.:
drop table if exists dbo.myTable;
create table dbo.myTable (
myTableID integer not null identity(1, 1),
[Description] varchar(max) null,
sourceID integer not null,
[Location] varchar(255) null,
Code varchar(255) null,
Location_Desc varchar(255) null,
primary key (myTableID)
);
insert into dbo.myTable (sourceID,[Description],[Location],Code,Location_Desc)
values (1, 'blue', 'Somewhere', '64', 'Balloons');
with xmlnamespaces (
default 'http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess',
'http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues' as d3p1,
'http://www.w3.org/2001/XMLSchema-instance' as i )
select
[sourceID],
cast((
select
[Description],
Code as [Location/d3p1:Code],
Location_Desc as [Location/d3p1:Description]
from dbo.myTable mnbm
where mnbm.sourceID = p.sourceID
for xml path('stuff'), root('arrayofstuff')
) as xml) as Ids
from dbo.myTable p
group by p.sourceID;
Which yields:
<arrayofstuff
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues"
xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess">
<stuff>
<Description>blue</Description>
<Location>
<d3p1:Code>64</d3p1:Code>
<d3p1:Description>Balloons</d3p1:Description>
</Location>
</stuff>
</arrayofstuff>

You can try the following solution based on XQuery and FLWOR expression.
It is producing XML that is shaped exactly as the desired output.
It is a two step process:
Compose raw XML.
Shape raw XML with namespaces based on the desired output.
SQL
-- DDL and sample data population, start
DECLARE #myTable TABLE
(
[myTableID] INTEGER NOT NULL IDENTITY(1, 1),
[Description] VARCHAR(MAX) NULL,
[sourceID] INTEGER NOT NULL,
[Location] VARCHAR(255) NULL,
[Code] VARCHAR(255) NULL,
[Location_Desc] VARCHAR(255) NULL,
PRIMARY KEY ([myTableID])
);
INSERT INTO #myTable
(
[sourceID],
[Description],
[Location],
[Code],
[Location_Desc]
)
VALUES
(3, 'yellow', 'Oxford County', '64', 'list'),
(3, 'blue', 'Fraser Lake', '64', 'list'),
(2, 'red', 'San Marcello Pistoiese', '64', 'list'),
(2, 'green', 'Gembloux', '64', 'list'),
(2, 'green', 'Yeongcheon', '64', 'list');
-- DDL and sample data population, end
;WITH rs AS
(
SELECT [sourceID]
, (SELECT [Description] AS [Description]
, [Code] AS [Code]
, [Location_Desc] AS [Location_Desc]
FROM #myTable AS mnbm
WHERE mnbm.[sourceID] = p.[sourceID]
FOR XML PATH('stuff'), TYPE, ROOT('arrayofstuff')
) AS Ids
FROM #myTable AS p
GROUP BY p.[sourceID]
)
SELECT rs.sourceID, rs.Ids AS [Before]
, rs.Ids.query('<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypes">
{
for $x in /*:arrayofstuff/*:stuff
return <stuff>
<Description>{data($x/*:Description)}</Description>
<Location xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues">
<d3p1:Code>{data($x/*:Code)}</d3p1:Code>
<d3p1:Description>{data($x/*:Location_Desc)}</d3p1:Description>
</Location>
</stuff>
}
</arrayofstuff>') AS [After]
FROM rs;

Related

After adding Feature Name and Feature Value query takes more than 5 minutes

I work on SQL Server 2014 and my issue occurred after displaying Feature Name and Feature Value separated by $.
When executing the query below after adding Feature Name and Feature Value with stuff it became very slow.
How to enhance it?
Before adding the two stuff statements it took 28 seconds to display 750 thousand records. Now as below script and after adding two stuff statements take 5 minutes.
Script below give me expected result but issue is performance is very slow.
So can I do separate Feature Name and Feature Value to make it faster? Separated by $ if possible.
My script:
IF OBJECT_ID('[dbo].[gen]') IS NOT NULL
DROP TABLE [dbo].[gen]
IF OBJECT_ID('[dbo].[PartAttributes]') IS NOT NULL
DROP TABLE [dbo].[PartAttributes]
IF OBJECT_ID('dbo.core_datadefinition_Detailes') IS NOT NULL
DROP TABLE core_datadefinition_Detailes
CREATE TABLE core_datadefinition_Detailes
(
[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[ColumnName] [nvarchar](500) NOT NULL,
[ColumnNumber] [int] NOT NULL,
CONSTRAINT [PK_Core_DataDefinition_Details]
PRIMARY KEY CLUSTERED ([ID] ASC)
)
INSERT INTO core_datadefinition_Detailes([ColumnNumber],[ColumnName])
VALUES (202503, 'Product Shape Type'),
(1501170111, 'Type'),
(202504, 'Package Family')
CREATE TABLE [dbo].[gen]
(
[TradeCodeControlID] [int] IDENTITY(1,1) NOT NULL,
[CodeTypeID] [int] NULL,
[RevisionID] [bigint] NULL,
[Code] [varchar](20) NULL,
[ZPLID] [int] NULL,
[ZfeatureKey] [bigint] NULL,
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[gen] ON
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7565, 849774, 307683692, N'8541100050', 4239, 202503)
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7566, 849774, 307683692, N'8541100050', 4239, 202504)
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7567, 849774, 307683692, N'8541100050', 4239, 1501170111)
SET IDENTITY_INSERT [dbo].[gen] OFF
CREATE TABLE [dbo].[PartAttributes]
(
[PartID] [int] NOT NULL,
[ZfeatureKey] [bigint] NULL,
[AcceptedValuesOption_Value] [float] NULL,
[FeatureValue] [nvarchar](500) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 202503, N'Discrete')
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 1501170111, N'Zener')
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 202504, N'SOT')
SELECT
PartID, Code, Co.CodeTypeID, Co.RevisionID, Co.ZPLID,
COUNT(1) AS ConCount,
STUFF((SELECT '$' + CAST(CP.ColumnName AS VARCHAR(300)) AS [text()]
FROM
(SELECT DISTINCT
d.ColumnName, C.codeTypeId, C.Code, C.ZfeatureKey
FROM gen C
INNER JOIN core_datadefinitiondetails d WITH (NOLOCK) ON C.ZfeatureKey = d.columnnumber
INNER JOIN PartAttributes P ON P.partid = PM.partid) CP
WHERE CP.codeTypeId = Co.codeTypeId AND CP.Code = Co.Code
ORDER BY CP.ZfeatureKey
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS FeatureName,
STUFF((SELECT '$' + CAST(CP2.FeatureValue AS VARCHAR(300)) AS [text()]
FROM
(SELECT DISTINCT
P.FeatureValue, C2.codeTypeId, C2.Code, C2.ZfeatureKey
FROM gen C2
INNER JOIN PartAttributes P ON C2.ZfeatureKey = P.ZfeatureKey) CP2
WHERE CP2.codeTypeId = Co.codeTypeId AND CP2.Code = Co.Code
ORDER BY CP2.ZfeatureKey
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS FeatureValue
FROM
PartAttributes PM
INNER JOIN
gen Co ON Co.ZfeatureKey = PM.ZfeatureKey
GROUP BY
PartID, Code, Co.CodeTypeID, Co.RevisionID, Co.ZPLID
Final result:
final result after add two stuff

How to insert data in table using Insert Query from values provided in parameters

I have this table structure and I want to write Insert Query that'll insert data into the table from the values provided in parameters
CREATE TABLE [dbo].[EMPLOYEE](
[ID] [int] NULL,
[EMPLOYEE_NAME] [varchar](50) NULL,
[DEPARTMENT_ID] [int] NULL,
) ON [PRIMARY]
DECLARE #ID VARCHAR(20) = '1, 2';
DECLARE #Name VARCHAR(50) = 'Asim Asghar, Ahmad'
DECLARE #DeptID VARCHAR(20) = '5, 12';
INSERT INTO EMPLOYEE VALUES (#ID, #Name, #DeptID)
Based on the data provided above it should add 4 rows with following data
1 Asim Asghar 5
2 Ahmad 5
1 Asim Asghar 12
2 Ahmad 12
Hope someone can help
You can not pass multiple values together through a variable at a time. The script should be as below considering one person at a time-
CREATE TABLE [dbo].[EMPLOYEE](
[ID] [int] NULL,
[EMPLOYEE_NAME] [varchar](50) NULL,
[DEPARTMENT_ID] [int] NULL,
) ON [PRIMARY]
DECLARE #ID INT = 1;
DECLARE #Name VARCHAR(50) = 'Asim Asghar';
DECLARE #DeptID INT = 5;
INSERT INTO EMPLOYEE(ID,EMPLOYEE_NAME,DEPARTMENT_ID) VALUES (#ID, #Name, #DeptID)
Then you can change the values for next person and execute the INSERT script again. And from the second execution, you have to skip the Table creation script other wise it will through error.
The question's query is trying to insert a single row, using strings values for the ID and DeptID fields. This will fail with a runtime error.
One can use the table value constructor syntax to insert multiple rows in a single INSERT statement :
INSERT INTO EMPLOYEE
VALUES
(1, 'Asim Asghar', 5),
(2, 'Ahmad', 5),
(1, 'Asim Asghar', 12),
(2, 'Ahmad', 12)
The values can come from parameters or variables.
Using duplicate IDs and names in an Employee table hints at a problem. Looks like the intent is to store employees and their department assignments. Otherwise why insert 4 rows instead of 8 with all possible combinations?
Employee should be changed to this :
CREATE TABLE [dbo].[EMPLOYEE]
(
[ID] [int] primary key not null,
[EMPLOYEE_NAME] [varchar](50)
)
And another table, EmployeeAssignment should be added
CREATE TABLE [dbo].[EMPLOYEE_ASSIGNMENT]
(
Employee_ID int not null FOREIGN KEY REFERENCES EMPLOYEE(ID),
[DEPARTMENT_ID] [int] not NULL,
PRIMARY KEY (Employee_ID,Department_ID)
)
The data can be inserted with two INSERT statements :
INSERT INTO EMPLOYEE
VALUES
(1, 'Asim Asghar'),
(2, 'Ahmad'),
INSERT INTO EMPLOYEE_ASSIGNMENT
VALUES
(1, 5),
(2, 5),
(1, 12),
(2, 12)
Try this, You need this function for splitting by char using dynamic delimiter.
CREATE FUNCTION UDF_SPLIT_BY_CHAR(#STRING VARCHAR(8000), #DELIMITER CHAR(1))
RETURNS #TEMPTABLE TABLE (S_DATA VARCHAR(8000))
AS
BEGIN
DECLARE #IDX INT=1,#SLICE VARCHAR(8000)
IF LEN(#STRING)<1 OR #STRING IS NULL RETURN
WHILE #IDX<> 0
BEGIN
SET #IDX = CHARINDEX(#DELIMITER,#STRING)
IF #IDX!=0
SET #SLICE = LEFT(#STRING,#IDX - 1)
ELSE
SET #SLICE = #STRING
IF(LEN(#SLICE)>0)
INSERT INTO #TEMPTABLE(S_DATA) VALUES(#SLICE)
SET #STRING = RIGHT(#STRING,LEN(#STRING) - #IDX)
IF LEN(#STRING) = 0 BREAK
END
RETURN
END
Declare #EMPLOYEE TABLE
(
[ID] [int] NULL,
[EMPLOYEE_NAME] [varchar](50) NULL,
[DEPARTMENT_ID] [int] NULL
)
DECLARE #ID VARCHAR(20) = '1, 2'
,#Name VARCHAR(50) = 'Asim Asghar, Ahmad'
,#DeptID VARCHAR(20) = '5, 12';
insert into #EMPLOYEE
(
[ID],[EMPLOYEE_NAME],[DEPARTMENT_ID]
)
Select a.S_DATA,b.S_DATA,c.S_DATA
from dbo.UDF_SPLIT_BY_CHAR(#id,',') a
left join dbo.UDF_SPLIT_BY_CHAR(#Name,',') b on 1=1
left join dbo.UDF_SPLIT_BY_CHAR(#DeptID,',') c on 1=1

How to loop though XML type and insert record every iteration in SQL Server?

I want to create a stored procedure which has a varchar(max) parameter which serves as a container for the XML string I constructed in my application. I have managed to come up with this xml string which will be passed as a varchar(max) parameter to the stored procedure and will be cast to XML:
<SurveyQuestion>
<Name>What is your pets name?</Name>
<Type>1</Type>
<IsRequired>True</IsRequired>
<Answer></Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>What is your gender?</Name>
<Type>3</Type>
<IsRequired>True</IsRequired>
<Answer>Male</Answer>
<Answer>Female</Answer>
<Answer>Trans</Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>Which colors do you like?</Name>
<Type>4</Type>
<IsRequired>False</IsRequired>
<Answer>Yellow</Answer>
<Answer>Green</Answer>
<Answer>Red</Answer>
<Answer>Blue</Answer>
<Answer>Orange</Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>Rate the service that you have receive from 1 to 5. I being the lowest and 5 being the highest</Name>
<Type>2</Type>
<IsRequired>True</IsRequired>
<Answer>1</Answer>
<Answer>2</Answer>
<Answer>3</Answer>
<Answer>4</Answer>
<Answer>5</Answer>
</SurveyQuestion>
I have Questions and an Answers table:
CREATE TABLE [dbo].[Questions]
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Question] [varchar](max) NULL, --Name
[IsRequired] bit NULL,
[SurveyFieldObjectId] [bigint] NULL --Type
)
CREATE TABLE [dbo].[Answers]
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[QuestionId] [bigint] NULL, --Foreign key Questions
[Options] [varchar](50) NULL, --Answer
[SurveyFieldObjectId] [bigint] NULL
)
And this is my stored procedure:
CREATE PROCEDURE
#otherIrrelevantProperty nvarchar(120),
#varcharXML varchar(max)
AS
BEGIN
BEGIN TRY
DECLARE #questionsXML = CAST(#varcharXML AS XML)
BEGIN TRANSACTION INSERTSURVEY
LOOP(#questionsXML.question)
BEGIN
INSERT INTO Questions VALUES (..)
LOOP(#questionsXML.answers)
BEGIN
INSERT INTO Answers VALUES (..)
END
END
COMMIT TRANSACTION INSERTSURVEY
SELECT 1
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION INSERTSURVEY
END
SELECT -1
END CATCH
END
If Name is unique in your XML, you can do this using two INSERT and temp table:
CREATE TABLE #Questions
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Question] [varchar](max) NULL --Name
)
CREATE TABLE #Answers
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[QuestionId] [bigint] NULL, --Foreign key Questions
[Options] [varchar](50) NULL --Answer
)
declare #xml xml = '<root>
<SurveyQuestion>
<Name>What is your pets name?</Name>
<Type>1</Type>
<IsRequired>True</IsRequired>
<Answer></Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>What is your gender?</Name>
<Type>3</Type>
<IsRequired>True</IsRequired>
<Answer>Male</Answer>
<Answer>Female</Answer>
<Answer>Trans</Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>Which colors do you like?</Name>
<Type>4</Type>
<IsRequired>False</IsRequired>
<Answer>Yellow</Answer>
<Answer>Green</Answer>
<Answer>Red</Answer>
<Answer>Blue</Answer>
<Answer>Orange</Answer>
</SurveyQuestion>
<SurveyQuestion>
<Name>Rate the service that you have receive from 1 to 5. I being the lowest and 5 being the highest</Name>
<Type>2</Type>
<IsRequired>True</IsRequired>
<Answer>1</Answer>
<Answer>2</Answer>
<Answer>3</Answer>
<Answer>4</Answer>
<Answer>5</Answer>
</SurveyQuestion>
</root>';
CREATE TABLE #temp
(
[Id] [bigint] NOT NULL,
[Question] [varchar](8000) NOT NULL, --Name, UNIQUE!!!
CONSTRAINT UC_Question UNIQUE(Question)
);
insert into #Questions (Question)
output INSERTED.Id, INSERTED.Question
into #temp (id, question)
select n.value('.', 'varchar(max)') Name
from #xml.nodes('/root/SurveyQuestion/Name') xml(n);
insert into #Answers (QuestionId, Options)
select t.Id, n.value('.', 'varchar(50)') answer
from #temp t
cross apply #xml.nodes('/root/SurveyQuestion[Name = sql:column("t.question")]/Answer') answers(n);
select * from #Questions;
select * from #Answers;
drop table #Questions;
drop table #Answers;
drop table #temp;

Error occurred in executing Table type parameter

I am trying to insert data into table using BizTalk with below code. But I am facing error as "Procedure or function Emp_Details has too many arguments specified."
Could someone help me out to solve the same?
ALTER PROCEDURE [dbo].[Emp_Details]
(#InsertDetails InsertDetailsType readonly)
AS
Begin
Truncate table [dbo].[Emp_Details]
INSERT INTO [dbo].[Emp_Details]
(
[NAME],
[DESCRIPTION],
[EMPID]
)
select
[NAME],
[DESCRIPTION],
[EMPID]
from #InsertDetails;
Begin
if exists(select 1 from [dbo].[Emp_Details]where NAME='Raul')
Delete from [Emp_Details]where NAME='Raul'
End
end
Reposting the same sample code used previously for reference.
USE <Database>
GO
/* This is a template table */
CREATE TYPE Emp_Details AS TABLE
( [Name] VARCHAR(100)
, [Description] VARCHAR(100)
, [Address] VARCHAR(100));
GO
/* The following is your Table Emp_Details which you must be having already*/
CREATE TABLE Emp_Details
( [Name] VARCHAR(100)
, [Description] VARCHAR(100)
, [Address] VARCHAR(100));
GO
/* Consider this as your Input Data i.e CSV file or Excel (Note: I have created a table for sample)*/
CREATE TABLE Emp_Details1
( [Name] VARCHAR(100)
, [Description] VARCHAR(100)
, [Address] VARCHAR(100));
GO
INSERT INTO Emp_Details1 VALUES ('John','Test','123')
INSERT INTO Emp_Details1 VALUES ('John1','Test1','1234')
INSERT INTO Emp_Details1 VALUES ('John2','Test2','1235')
GO
SELECT * FROM Emp_Details
/* Declare a variable that references the type. So when you reference a `TYPE` it takes the table template which we created previously*/
DECLARE #Emp AS Emp_Details;
/* Add data to the table variable. In your case push the data that you get into the #Emp */
INSERT INTO #Emp ([Name], [Description], [Address])
SELECT [Name], [Description], [Address]
FROM Emp_Details1;
/* Pass the table variable data to a stored procedure. */
EXEC [dbo].[Insert_Deatils] #Emp;
GO
SELECT * FROM Emp_Details

Insert xml element contents(which is also xml tags) into column in SQL Server 2005

For a table schema like below
CREATE TABLE [dbo].[Employee](
[EmployeeId] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Location] [nvarchar](50) NOT NULL,
[Skills] [xml] NOT NULL,
[Projects] [nvarchar](400) NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
When inserting data into table, i want to insert only child tags of <SkillSet> but seems <SkillSet> along with it's child elements inserts into Skill xml columns.
declare #doc NVARCHAR(MAX)
declare #idoc INT
select #doc = '<Request Type="InsertEmployee" CRUD="C">
<Employee>
<EmployeeId>1</EmployeeId>
<Name>Deeptechtons</Name>
<Location>USA</Location>
<SkillSet>
<Skill>C#</Skill>
<Skill>SQL Server 2005</Skill>
<Skill>ASP.net</Skill>
</SkillSet>
<Projects>
<Project>LowBin</Project>
<Project>Maskin</Project>
</Projects>
</Employee>
</Request>'
exec sp_xml_preparedocument #idoc output,#doc
insert into Employee (
EmployeeId
,[Name]
,Location
,Skills,
Projects
)
SELECT NEWID()
,[Name]
,Location
,Skills
,Projects
FROM OPENXML(#idoc,'Request/Employee',2)
WITH
(
[Name] NVARCHAR(50)
,Location NVARCHAR(50)
,Skills XML 'SkillSet'
,Projects NVARCHAR(400)
)
exec sp_xml_removedocument #idoc
Questions
How to insert only child elements of <Skillset> rather than whole tag and its children.
I expected Projects also to be inserted same as did but only Lowbin content of first Project tag is inserted. Can you correct my code.
Since you are on SQL Server 2005 you can make use of the XML data type and do like this instead.
declare #doc xml
select #doc = '<Request Type="InsertEmployee" CRUD="C">
<Employee>
<EmployeeId>1</EmployeeId>
<Name>Deeptechtons</Name>
<Location>USA</Location>
<SkillSet>
<Skill>C#</Skill>
<Skill>SQL Server 2005</Skill>
<Skill>ASP.net</Skill>
</SkillSet>
<Projects>
<Project>LowBin</Project>
<Project>Maskin</Project>
</Projects>
</Employee>
</Request>'
insert into Employee (
EmployeeId
,[Name]
,Location
,Skills,
Projects
)
select newid(),
T.N.value('Name[1]', 'nvarchar(50)'),
T.N.value('Location[1]', 'nvarchar(50)'),
T.N.query('SkillSet/*'),
cast(T.N.query('Projects/*') as nvarchar(400))
from #doc.nodes('/Request/Employee') as T(N)
Result:
BC76E37C-0C0D-4B7B-92FD-0F7807F9204B
Deeptechtons
USA
<Skill>C#</Skill><Skill>SQL Server005</Skill>Skill>ASP.net</Skill>
<Project>LowBin</Project><Project>Maskin</Project>
Update:
If you really want to use OPENXML for some reason you can use this.
insert into Employee (
EmployeeId
,[Name]
,Location
,Skills,
Projects
)
SELECT NEWID()
,[Name]
,Location
,Skills.query('SkillSet/*')
,cast(Projects.query('Projects/*') as nvarchar(max))
FROM OPENXML(#idoc,'Request/Employee',2)
WITH
(
[Name] NVARCHAR(50)
,Location NVARCHAR(50)
,Skills XML 'SkillSet'
,Projects XML
)

Resources