如何根据 Sql 服务器中的 xml 在各个表中动态插入数据
How dynamically insert data in respective tables based upon xml in Sql server
我在存储过程中有这种类型的输入 XML
参数传递,它是从我的 .net
应用程序传递的。
现在,我需要在每个 table:
中插入记录
<root>
<table1>
<patid>123</patid>
<name>gresh</name>
<fname>kumar</name>
</table1>
<table2>
<patid>123</patid>
<Schoolname>12345</Schoolname>
</table2>
<tablen>
<patid>123</patid>
<nfield>12345</nfield>
</tablen>
<root>
假设table1
将在table1
中插入数据,table2
中的数据在table2
中,tablen
意味着其他table的数量可能XML
.
那么如何在每个 table 中插入?
您首先需要从XML
获取数据。您的情况非常简单(我假设您只在一个 table 中插入数据一次,但是您可以轻松解决在一个 table 中多次插入的问题)。所以,下面的语句给了我:
SELECT T.c.value('local-name(.)','nvarchar(128)') AS tableName
,T1.c1.value('local-name(.)','nvarchar(128)') AS columName
,T1.c1.value('(./node())[1]','nvarchar(max)') AS value
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
然后,您需要对每个 table 的 insertion
的值进行分组(我正在使用 CLR
连接函数(您可以找到它 here,但是您也可以搜索 T-SQL
替代方案):
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT tableName
,[dbo].[Concatenate] (columName)
,[dbo].[Concatenate] (value)
FROM DataSource
GROUP BY tableName
您可以像这样进一步准备上述代码以进行动态执行:.
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT 'INSERT INTO ' + tableName + '(' + [dbo].[Concatenate] (columName) + ') VALUES(' + [dbo].[Concatenate] ('''' + value + '''') + ');'
FROM DataSource
GROUP BY tableName
现在,您只需构建一个 dynamic T-SQL string
并使用 sp_executesql
过程执行它:
DECLARE @XML XML = N'<root>
<table1>
<patid>123</patid>
<name>gresh</name>
<fname>kumar</fname>
</table1>
<table2>
<patid>123</patid>
<Schoolname>12345</Schoolname>
</table2>
<tablen>
<patid>123</patid>
<nfield>12345</nfield>
</tablen>
</root>';
DECLARE @DynamicSQLStatement NVARCHAR(MAX)
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT @DynamicSQLStatement =
(
SELECT CHAR(10) + 'INSERT INTO ' + tableName + '(' + [dbo].[Concatenate] (columName) + ') VALUES(' + [dbo].[Concatenate] ('''' + value + '''') + ');'
FROM DataSource
GROUP BY tableName
FOR XML PATH, TYPE
).value('.', 'NVARCHAR(MAX)')
PRINT @DynamicSQLStatement
EXEC sp_executesql @DynamicSQLStatement
请注意,我假设您的 XML
结构在数据库上下文中有效 - table 存在,列存在,并且列中插入的值是正确的。
如果需要,您可以添加更多检查。
我在存储过程中有这种类型的输入 XML
参数传递,它是从我的 .net
应用程序传递的。
现在,我需要在每个 table:
中插入记录<root>
<table1>
<patid>123</patid>
<name>gresh</name>
<fname>kumar</name>
</table1>
<table2>
<patid>123</patid>
<Schoolname>12345</Schoolname>
</table2>
<tablen>
<patid>123</patid>
<nfield>12345</nfield>
</tablen>
<root>
假设table1
将在table1
中插入数据,table2
中的数据在table2
中,tablen
意味着其他table的数量可能XML
.
那么如何在每个 table 中插入?
您首先需要从XML
获取数据。您的情况非常简单(我假设您只在一个 table 中插入数据一次,但是您可以轻松解决在一个 table 中多次插入的问题)。所以,下面的语句给了我:
SELECT T.c.value('local-name(.)','nvarchar(128)') AS tableName
,T1.c1.value('local-name(.)','nvarchar(128)') AS columName
,T1.c1.value('(./node())[1]','nvarchar(max)') AS value
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
然后,您需要对每个 table 的 insertion
的值进行分组(我正在使用 CLR
连接函数(您可以找到它 here,但是您也可以搜索 T-SQL
替代方案):
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT tableName
,[dbo].[Concatenate] (columName)
,[dbo].[Concatenate] (value)
FROM DataSource
GROUP BY tableName
您可以像这样进一步准备上述代码以进行动态执行:.
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT 'INSERT INTO ' + tableName + '(' + [dbo].[Concatenate] (columName) + ') VALUES(' + [dbo].[Concatenate] ('''' + value + '''') + ');'
FROM DataSource
GROUP BY tableName
现在,您只需构建一个 dynamic T-SQL string
并使用 sp_executesql
过程执行它:
DECLARE @XML XML = N'<root>
<table1>
<patid>123</patid>
<name>gresh</name>
<fname>kumar</fname>
</table1>
<table2>
<patid>123</patid>
<Schoolname>12345</Schoolname>
</table2>
<tablen>
<patid>123</patid>
<nfield>12345</nfield>
</tablen>
</root>';
DECLARE @DynamicSQLStatement NVARCHAR(MAX)
;WITH DataSource(tableName, columName, value)AS
(
SELECT T.c.value('local-name(.)','nvarchar(128)')
,T1.c1.value('local-name(.)','nvarchar(128)')
,T1.c1.value('(./node())[1]','nvarchar(max)')
FROM @XML.nodes('/root/*') T(c)
CROSS APPLY T.c.nodes('*') T1(c1)
)
SELECT @DynamicSQLStatement =
(
SELECT CHAR(10) + 'INSERT INTO ' + tableName + '(' + [dbo].[Concatenate] (columName) + ') VALUES(' + [dbo].[Concatenate] ('''' + value + '''') + ');'
FROM DataSource
GROUP BY tableName
FOR XML PATH, TYPE
).value('.', 'NVARCHAR(MAX)')
PRINT @DynamicSQLStatement
EXEC sp_executesql @DynamicSQLStatement
请注意,我假设您的 XML
结构在数据库上下文中有效 - table 存在,列存在,并且列中插入的值是正确的。
如果需要,您可以添加更多检查。