Sql server 基于节点名称的T-Sql XML节点条件
我需要解析一些XML以插入到表中,但我的中级节点名称可以是两个值之一Sql server 基于节点名称的T-Sql XML节点条件,sql-server,xml,tsql,Sql Server,Xml,Tsql,我需要解析一些XML以插入到表中,但我的中级节点名称可以是两个值之一或。我有一个“插入后”触发器来执行此操作,这是我的尝试,但它不起作用。感兴趣的区域是朝向底部的案例陈述 USE [cims] GO /****** Object: Trigger [dbo].[tr_XML_Insert] Script Date: 07/08/2014 16:52:01 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRI
或
。我有一个“插入后”触发器来执行此操作,这是我的尝试,但它不起作用。感兴趣的区域是朝向底部的案例陈述
USE [cims]
GO
/****** Object: Trigger [dbo].[tr_XML_Insert] Script Date: 07/08/2014 16:52:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_XML_Insert]
ON [dbo].[ContainerXML]
AFTER INSERT
AS
BEGIN
IF @@ROWCOUNT = 0
RETURN
SET NOCOUNT ON
IF EXISTS(SELECT [XMLData] FROM INSERTED)
BEGIN
DECLARE @XML XML
SELECT @XML = XMLData FROM [inserted]
INSERT INTO [dbo].[ContainerImage]
(
CaptureDeviceCDIFID, CaptureDeviceName, Lat, Lon, DodAAC, OCR_Equipment, MOD_Equipment,
TypeCode, SideImageComments, BackImageComments, SideImageCaptureDate, SideImage,
BackImageCaptureDate, BackImage,
RecordCreateDate
)
SELECT
col.value('PCMU[1]/@cdifid[1]', 'NVARCHAR(15)'),
col.value('PCMU[1]/@Name[1]', 'NVARCHAR(100)'),
col.value('Location[1]/@lat[1]', '[DECIMAL](18,9)'),
col.value('Location[1]/@lon[1]', '[DECIMAL](18,9)'),
col.value('Location[1]/@DoDAAC[1]', 'NVARCHAR(10)'),
REPLACE(col.value('BIC[1]/@ISOCode[1]', 'NVARCHAR(12)'), ' ', ''),
REPLACE(col.value('BIC[1]/@ISOCode[1]', 'NVARCHAR(12)'), ' ', ''),
col.value('BIC[1]/@TypeCode[1]', 'NVARCHAR(10)'),
col.value('BIC[1]/@UserText1[1]', 'NVARCHAR(255)'),
col.value('BIC[1]/@UserText2[1]', 'NVARCHAR(255)'),
CASE xmldata.col.value('local-name(/*[1])','varchar(20)')
WHEN 'Image' THEN col.value('Image[1]/@imagetime[1]', 'DATETIME')
WHEN 'Video' THEN col.value('Video[1]/@time[1]', 'DATETIME')
END,
CASE xmldata.col.value('local-name(/*[1])','varchar(20)')
WHEN 'Image' THEN col.value('Image[1]/@imageData[1]', 'VARBINARY(MAX)')
WHEN 'Video' THEN col.value('Video[1]/@videoData[1]', 'VARBINARY(MAX)')
END,
CASE xmldata.col.value('local-name(/*[1])','varchar(20)')
WHEN 'Image' THEN col.value('Image[2]/@imagetime[1]', 'DATETIME')
WHEN 'Video' THEN col.value('Video[2]/@time[1]', 'DATETIME')
END,
CASE xmldata.col.value('local-name(/*[1])','varchar(20)')
WHEN 'Image' THEN col.value('Image[2]/@imageData[1]', 'VARBINARY(MAX)')
WHEN 'Video' THEN col.value('Video[2]/@videoData[1]', 'VARBINARY(MAX)')
END,
GETDATE()
FROM @XML.nodes('//Containers/Container') as xmldata(col)
END
END
这里是XML文件的两种格式——我可以很容易地做一种或另一种,我正在寻找一种方法在相同的代码中完成它。我基本上想要XML中的所有内容,我只是不知道如何说“如果node name==Image,获取这些字段,否则如果node name==Video,获取这些字段
<Containers>
<Container>
<PCMU cdifid="81.135.189.71" Name="Test PCMU1" />
<Location lat="38.35688" lon="-77.45752"
DoDAAC="TODO??" />
<BIC time="2014-06-20T15:11:07"
idStatus="OK"
ISOCode="(null)"
TypeCode="0x0"
UserText1="??"
UserText2="??" />
<Video view="Container Side"
time="2014-06-20T15:11:07"
videoData="big chunk of base64 data"/>
<Video view="Container Rear"
time="2014-06-20T15:11:07"
videoData="big chunk of base64 data" />
</Container>
</Containers>
<Containers>
<Container>
<PCMU cdifid="81.135.189.71" Name="Test PCMU1" />
<Location lat="38.35688" lon="-77.45752"
DoDAAC="TODO??" />
<BIC time="2014-06-20T15:11:07"
idStatus="OK"
ISOCode="(null)"
TypeCode="0x0"
UserText1="??"
UserText2="??" />
<Image view="Container Side"
imageTime="2014-06-20T15:11:07"
imageData="big chunk of base64 data"/>
<Image view="Container Rear"
imageTime="2014-06-20T15:11:07"
imageData="big chunk of base64 data" />
</Container>
</Containers>
您需要使用insert表,因为一次可以插入多行,您的case语句可以重写为在一个value子句中使用两个xPath表达式
CREATE TRIGGER[dbo]。[tr\u XML\u Insert]
在[dbo].[ContainerXML]上
插入后
作为
开始
插入[dbo]。[ContainerImage]
(
CaptureDeviceModifid、CaptureDeviceName、Lat、Lon、DodAAC、OCR_设备、MOD_设备、,
类型代码、SideImageComments、BackImageComments、SideImageCaptureDate、SideImage、,
BackImageCaptureDate,BackImageCaptureDate,
RecordCreateDate
)
挑选
列值('(PCMU/@cdifid)[1],'NVARCHAR(15)',
col.value('(PCMU/@Name)[1],'NVARCHAR(100)'),
列值('(位置/@lat)[1],'[十进制](18,9)'),
列值(‘(Location/@lon)[1]’,‘[十进制](18,9)’),
列值(‘(Location/@DoDAAC)[1]’,‘NVARCHAR(10)’),
替换(列值('(BIC/@ISOCode)[1],'NVARCHAR(12)',''),
替换(列值('(BIC/@ISOCode)[1],'NVARCHAR(12)',''),
列值('(BIC/@TypeCode)[1],'NVARCHAR(10)',
col.value('(BIC/@UserText1)[1],'NVARCHAR(255)',
col.value('(BIC/@UserText2)[1],'NVARCHAR(255)',
xmldata.col.value('(Image/@imageTime,Video/@time)[1],'DATETIME'),
xmldata.col.value('(Image/@imageData,Video/@videoData)[1],'VARBINARY(MAX)'),
xmldata.col.value('(Image/@imageTime,Video/@time)[2],'DATETIME'),
xmldata.col.value('(Image/@imageData,Video/@videoData)[2],'VARBINARY(MAX)'),
GETDATE()
从我插入的
交叉应用I.XMLData.nodes('/Containers/Container')作为XMLData(col)
结束
您应该发布一个要解析的XML示例,以及使用该XML的select语句的预期输出。另一件事是,您假设为每个插入的行调用一次触发器。事实并非如此。如果一次插入多行,则只会调用一次触发器和伪表inserted
将有多行。您不应该将XML分配给变量,而应该在查询中使用inserted
,在XMLData.nodes(…)上使用cross-apply
…
谢谢你,Mikael。我不常在TSQL中工作,所以我会通过谷歌交叉申请,并在这方面做得很聪明。谢谢你,Mikael,这工作做得很好,正是我想要的