我希望将以下XML作为字符串传递给SQL,并根据UPDATE
和EventID
标识的现有表列将目标表行GROUP
传递给.....
<Item>
<GroupItem>
<Group1>A</Group1>
<Price>100</Price>
<Location>Here</Location>
</GroupItem>
<GroupItem>
<Group2>B</Group2>
<Price>200</Price>
<Location>There</Location>
</GroupItem>
<GroupItem>
<Group3>C</Group3>
<Price>300</Price>
<Location>Everywhere</Location>
</GroupItem>
<EVENTID>12345</EVENTID>
<MATCHED>100</MATCHED>
</Item>
因此,在此示例中,我想要更新EventID
为12345的表行,并为列提供值:GROUP1 = A
,GROUP2 = B
,GROUP3 = C
...
任何帮助解开我所处的混乱(再一次)都会感激......
TARGET TABLE结构如下:
CREATE TABLE [dbo].[GROUPTABLE](
[EventID] [int] NOT NULL,
[Group1A] [nvarchar](50) NULL,
[Group1B] [nvarchar](50) NULL,
[Group1C] [nvarchar](50) NULL,
[Group1D] [nvarchar](50) NULL,
[Group1_Location] [nvarchar](50) NULL,
[Group1_Matched] [float] NULL,
[Group2A] [nvarchar](50) NULL,
[Group2B] [nvarchar](50) NULL,
[Group2_Matched] [float] NULL,
[Group2_Location] [nvarchar](50) NULL,
[Group3A] [nvarchar](50) NULL,
[Group3B] [nvarchar](50) NULL,
[Group3_Matched] [float] NULL,
[Group3_Location] [nvarchar](50) NULL,
[Group4A] [nvarchar](50) NULL,
[Group4B] [nvarchar](50) NULL,
[Group4_Matched] [float] NULL,
[Group4_Location] [nvarchar](50) NULL,
CONSTRAINT [PK_GROUPTABLE] PRIMARY KEY CLUSTERED
(
[EventID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
虽然这在概念上可能没有意义 - 这不是我在我的应用程序中使用的确切表 - (我不想放弃太多),但这种结构模仿了我想要做的事情&# 39,真正的&#39;表....
答案 0 :(得分:0)
只需将整个代码块复制到一个空的查询窗口中并尝试一下......
/*
This is your mimic table
Btw: It is - in almost all cases! - a very bad idea to store related data in a table like data1, data2, data3...
If possible you should introduce a table GroupValues with a foreign key onto group table
*/
CREATE TABLE [dbo].[GROUPTABLE](
[EventID] [int] NOT NULL,
[Group1A] [nvarchar](50) NULL,
[Group1B] [nvarchar](50) NULL,
[Group1_Matched] [float] NULL,
[Group1_Location] [nvarchar](50) NULL,
[Group2A] [nvarchar](50) NULL,
[Group2B] [nvarchar](50) NULL,
[Group2_Matched] [float] NULL,
[Group2_Location] [nvarchar](50) NULL,
[Group3A] [nvarchar](50) NULL,
[Group3B] [nvarchar](50) NULL,
[Group3_Matched] [float] NULL,
[Group3_Location] [nvarchar](50) NULL,
[Group4A] [nvarchar](50) NULL,
[Group4B] [nvarchar](50) NULL,
[Group4_Matched] [float] NULL,
[Group4_Location] [nvarchar](50) NULL,
CONSTRAINT [PK_GROUPTABLE] PRIMARY KEY CLUSTERED
(
[EventID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
--here I insert two dummy rows
INSERT INTO GROUPTABLE VALUES
(1, 'Gr1A','Gr1B',111,'Gr1Location'
,'Gr2A','Gr2B',222,'Gr2Location'
,'Gr3A','Gr3B',333,'Gr3Location'
,'Gr4A','Gr4B',444,'Gr4Location'
)
,(12345,'Gr1A','Gr1B',111,'Gr1Location'
,'Gr2A','Gr2B',222,'Gr2Location'
,'Gr3A','Gr3B',333,'Gr3Location'
,'Gr4A','Gr4B',444,'Gr4Location'
);
--one test to show the data
SELECT * FROM dbo.GROUPTABLE;
--Here's your XML
DECLARE @XML XML=
'<Item>
<GroupItem>
<Group1>A</Group1>
<Price>100</Price>
<Location>Here</Location>
</GroupItem>
<GroupItem>
<Group2>B</Group2>
<Price>200</Price>
<Location>There</Location>
</GroupItem>
<GroupItem>
<Group3>C</Group3>
<Price>300</Price>
<Location>Everywhere</Location>
</GroupItem>
<EVENTID>12345</EVENTID>
<MATCHED>100</MATCHED>
</Item>';
/*
And this is the UPDATE
If necessary you might use .query() to get the nodes and save repeated XPath-navigation
Anyway: Much better was a
<Item>
<GroupItem group="A">
<Group>A</Group>
<Price>100</Price>
...
<GroupItem group="B">
<Group>A</Group>
<Price>100</Price>
...
to avoid differint element names
*/
UPDATE dbo.GROUPTABLE
SET Group1A = @XML.value('(/Item/GroupItem/*[local-name(.)="Group1"])[1]','varchar(max)')
,Group2A = @XML.value('(/Item/GroupItem/*[local-name(.)="Group2"])[1]','varchar(max)')
,Group3A = @XML.value('(/Item/GroupItem/*[local-name(.)="Group3"])[1]','varchar(max)')
,Group4A = @XML.value('(/Item/GroupItem/*[local-name(.)="Group4"])[1]','varchar(max)')
,Group1B = @XML.value('(/Item/GroupItem/*[local-name(.)="Group1"]/../Price)[1]','varchar(max)')
,Group2B = @XML.value('(/Item/GroupItem/*[local-name(.)="Group2"]/../Price)[1]','varchar(max)')
,Group3B = @XML.value('(/Item/GroupItem/*[local-name(.)="Group3"]/../Price)[1]','varchar(max)')
,Group4B = @XML.value('(/Item/GroupItem/*[local-name(.)="Group4"]/../Price)[1]','varchar(max)')
,Group1_Matched = @XML.value('(/Item/MATCHED)[1]','float')
,Group2_Matched = @XML.value('(/Item/MATCHED)[1]','float')
,Group3_Matched = @XML.value('(/Item/MATCHED)[1]','float')
,Group4_Matched = @XML.value('(/Item/MATCHED)[1]','float')
,Group1_Location = @XML.value('(/Item/GroupItem/*[local-name(.)="Group1"]/../Location)[1]','varchar(max)')
,Group2_Location = @XML.value('(/Item/GroupItem/*[local-name(.)="Group2"]/../Location)[1]','varchar(max)')
,Group3_Location = @XML.value('(/Item/GroupItem/*[local-name(.)="Group3"]/../Location)[1]','varchar(max)')
,Group4_Location = @XML.value('(/Item/GroupItem/*[local-name(.)="Group4"]/../Location)[1]','varchar(max)')
WHERE EventID=@XML.value('(/Item/EVENTID)[1]','int');
--Here you see, that the item' value changed for EventID=12345
SELECT * FROM dbo.GROUPTABLE;
--Clean Up
--DROP TABLE dbo.GROUPTABLE
使用此查询,您可以一次性获取所有数据
SELECT @XML.value('(/Item/EVENTID)[1]','int') AS EventId
,@XML.value('(/Item/MATCHED)[1]','int') AS Matched
,A.B.value('local-name(*[position()=1][1])','varchar(max)') AS GroupName
,A.B.value('*[position()=1][1]','varchar(max)') AS FirstNode
,A.B.value('Price[1]','decimal(12,4)') AS Price
,A.B.value('Location[1]','varchar(max)') AS Location
FROM @XML.nodes('/Item/GroupItem') AS A(B)
结果
12345 100 Group1 A 100.0000 Here
12345 100 Group2 B 200.0000 There
12345 100 Group3 C 300.0000 Everywhere
其实我怀疑你给出的描述真的是你想要的:-),但这是实现我理解的方法:
DECLARE @XML XML=
'<Item>
<GroupItem>
<Group1>A</Group1>
<Price>100</Price>
<Location>Here</Location>
</GroupItem>
<GroupItem>
<Group2>B</Group2>
<Price>200</Price>
<Location>There</Location>
</GroupItem>
<GroupItem>
<Group3>C</Group3>
<Price>300</Price>
<Location>Everywhere</Location>
</GroupItem>
<EVENTID>12345</EVENTID>
<MATCHED>100</MATCHED>
</Item>';
声明一个表变量,用测试数据填充它
DECLARE @tbl TABLE(ID INT,Group1 VARCHAR(10),Group2 VARCHAR(10),Group3 VARCHAR(10));
INSERT INTO @tbl VALUES
(3456,'Test1','Test2','Test3')
,(12345,'Test1','Test2','Test3');
SELECT * FROM @tbl;
结果
3456 Test1 Test2 Test3
12345 Test1 Test2 Test3
更改ID = 12345的行
UPDATE @tbl SET Group1 = @XML.value('(/Item/GroupItem/*[local-name(.)="Group1"])[1]','varchar(max)')
,Group2 = @XML.value('(/Item/GroupItem/*[local-name(.)="Group2"])[1]','varchar(max)')
,Group3 = @XML.value('(/Item/GroupItem/*[local-name(.)="Group3"])[1]','varchar(max)')
WHERE ID=@XML.value('(/Item/EVENTID)[1]','int');
结果
SELECT * FROM @tbl;
3456 Test1 Test2 Test3
12345 A B C