问题描述
如何删除表#XMLItm中的冗余?
我的代码:
BEGIN TRY
DECLARE @xml XML= '<?xml version="1.0" encoding="iso-8859-1"?>
<lists>
<list list="LIST A" remark="xx">
<item id_list="1" code="Y" description="Yes" order="1" enabled="1" />
<item id_list="1" code="N" description="No" order="2" enabled="1" />
</list>
<list list="LIST B" remark="yy">
<item id_list="2" code="E" description="Enabled" order="1" enabled="1" />
<item id_list="2" code="D" description="disabled" order="2" active="1" />
</list>
</lists>';
CREATE TABLE #XMLLst
(
[ID_LIST] INT NOT NULL,[NAME_LIST] VARCHAR(250) NOT NULL,[REMARKS] VARCHAR(8000)
);
INSERT INTO #XMLLst
(
ID_LIST,NAME_LIST,REMARKS
)
SELECT disTINCT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ID_LIST,Ssn.value('(/list/@list)[1]','Varchar(250)') AS NAME_LIST,Ssn.value('(/list/@remark)[1]','varchar(8000)') AS REMARKS
FROM
(
SELECT S.s.query('.') AS Ssn
FROM @xml.nodes('/lists/list') AS S(s)
) AS SSnes;
WITH CTE_DATOS_ORIGEN
AS (SELECT disTINCT
ID_LIST,REMARKS
FROM #XMLLst)
MERGE INTO [sos].[LIST] LIST
USING CTE_DATA_ORIGIN
ON LIST.ID_LIST = CTE_DATA_ORIGIN.ID_LIST
WHEN MATCHED AND CTE_DATA_ORIGIN.NAME_LIST = LIST.NAME_LIST
THEN UPDATE SET
LIST.NAME_LIST = CTE_DATA_ORIGIN.NAME_LIST,LIST.REMARKS = CTE_DATA_ORIGIN.REMARKS
WHEN NOT MATCHED
THEN
INSERT(ID_LIST,REMARKS)
VALUES
(
CTE_DATA_ORIGIN.ID_LIST,CTE_DATA_ORIGIN.NAME_LIST,CTE_DATA_ORIGIN.REMARKS
);
CREATE TABLE #XMLItm
(
[ID_OPTION_LIST] INT NOT NULL,[ID_LIST] INT NOT NULL,[CODE] VARCHAR(50) NOT NULL,[DESCRIPTION] VARCHAR(1000) NOT NULL,[ORDER] INT NOT NULL,[ENABLED] BIT
);
INSERT INTO #XMLItm
(
ID_OPTION_LIST,ID_LIST,CODE,DESCRIPTION,ORDER,ENABLED
)
SELECT disTINCT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ID_OPTION_LIST,-- I want delete this option and load the ID_LIST from #XMLLst
Ssn.value('(/item/@id_list)[1]','int') AS ID_LIST,Ssn.value('(/item/@code)[1]','varchar(50)') AS CODE,Ssn.value('(/item/@description)[1]','varchar(1000)') AS DESCRIPTION,Ssn.value('(/item/@order)[1]','int') AS ORDER,Ssn.value('(/item/@enabled)[1]','int') AS ENABLED
FROM
(
SELECT S.s.query('.') AS Ssn
FROM @xml.nodes('/lists/list/item') AS S(s)
) AS SSnes;
WITH CTE_DATA_ORIGIN
AS (SELECT disTINCT
ID_OPCION_LIST,ENABLED
FROM #XMLItm)
MERGE INTO [sos].[ITEM_LIST] ITEM
USING CTE_DATA_ORIGIN
ON ITEM.ID_OPTION_LIST = CTE_DATA_ORIGIN.ID_OPTION_LIST
AND ITEM.ID_LIST = CTE_DATA_ORIGIN.ID_LIST
WHEN MATCHED AND CTE_DATA_ORIGIN.CODE = ITEM.CODE
THEN UPDATE SET
ITEM.DESCRIPTION = CTE_DATA_ORIGIN.DESCRIPTION,ITEM.ORDER = CTE_DATA_ORIGIN.ORDER,ITEM.ENABLED = CTE_DATA_ORIGIN.ENABLED
WHEN NOT MATCHED
THEN
INSERT(ID_OPTION_LIST,ENABLED)
VALUES
(
CTE_DATOS_ORIGEN.ID_OPTION_LIST,CTE_DATOS_ORIGEN.ID_LIST,CTE_DATOS_ORIGEN.CODE,CTE_DATOS_ORIGEN.DESCRIPTION,CTE_DATOS_ORIGEN.ORDER,CTE_DATOS_ORIGEN.ENABLED
);
DROP TABLE #XMLLst;
DROP TABLE #XMLItm;
在此代码中,我希望在两个表中加载公共字段ID_LIST的信息。如何从临时表#XMLItm中的#XMLLst加载ID_LIST?
我想从表#XMLItm中的XML中删除字段ID_LIST,并从临时表#XMLLst中获取一个ID_LIST;
:在#XMLLst表中,加载一个列表,其中包含您的ID(自动递增),名称和备注,并从XML导出到sql。
在表#XMLItm中加载与ID列表链接的项目。
预期输出
+-----------+---------------+---------+
|ID_LIST | NAME_LIST | REMARKS |
|1 |LIST A | xx |
|2 |LIST B | yy |
+-------------------------------------+
ID_OPTION_LIST ID_LIST CODE DESCRIPTION ORDER ENABLED
1 1 Y yes 1 1
2 1 N No 2 1
3 2 E Enabled 1 1
4 2 D disables 2 1
解决方法
请尝试以下解决方案。它将列表与XML中的子 item 片段结合在一起。此外,它还在两个级别上生成两个运行序列。
SQL
-- DDL and sample data population,start
DECLARE @xml XML =
'<?xml version="1.0" encoding="iso-8859-1"?>
<lists>
<list list="LIST A" remark="xx">
<item id_list="1" code="Y" description="Yes" order="1" enabled="1" />
<item id_list="1" code="N" description="No" order="2" enabled="1" />
</list>
<list list="LIST B" remark="yy">
<item id_list="2" code="E" description="Enabled" order="1" enabled="1" />
<item id_list="2" code="D" description="Disabled" order="2" active="1" />
</list>
</lists>';
-- DDL and sample data population,end
-- It seems exactly waht you need
SELECT ROW_NUMBER() OVER (ORDER BY i) AS ID_OPTION_LIST,DENSE_RANK() OVER (ORDER BY c) AS ID_LIST_Sequence,c.value('@list','VARCHAR(250)') AS NAME_LIST,c.value('@remark','VARCHAR(8000)') AS REMARKS,i.value('@id_list','int') AS ID_LIST,i.value('@code','varchar(50)') AS CODE,i.value('@description','varchar(1000)') AS DESCRIPTION,i.value('@order','int') AS [ORDER],i.value('@enabled','int') AS ENABLED
FROM @xml.nodes('/lists/list') AS t(c)
CROSS APPLY t.c.nodes('item') AS x(i);
输出
+----------------+------------------+-----------+---------+---------+------+-------------+-------+---------+
| ID_OPTION_LIST | ID_LIST_Sequence | NAME_LIST | REMARKS | ID_LIST | CODE | DESCRIPTION | ORDER | ENABLED |
+----------------+------------------+-----------+---------+---------+------+-------------+-------+---------+
| 1 | 1 | LIST A | xx | 1 | Y | Yes | 1 | 1 |
| 2 | 1 | LIST A | xx | 1 | N | No | 2 | 1 |
| 3 | 2 | LIST B | yy | 2 | E | Enabled | 1 | 1 |
| 4 | 2 | LIST B | yy | 2 | D | Disabled | 2 | NULL |
+----------------+------------------+-----------+---------+---------+------+-------------+-------+---------+