使用pureXML和XMLTable在DB2中分解XML

本文介绍了如何在DB2 pureXML中利用XMLTable功能分解XML文档,以便进行数据分析。通过示例展示了如何处理ASDI消息中的arrivalInformation,特别是computerId和qualifiedAircraftId,强调了分解策略、性能考量以及使用视图、存储过程和触发器等方法。

DB2 pureXML允许将格式正确的XML文档以本机格式存储在关系数据库中。 通过使用SQL和XQUERY语言,可以在数据库中操作这些文档。 如果没有此功能,应用程序将必须接收完整的文档,进行更改,然后将完整的文档返回数据库。 对于大文件或大量文件,这可能会使网络连接快速饱和。

pureXML功能包括对SQL函数XMLQUERY,XMLTABLE和XMLEXISTS的支持。 这些分别在SELECT,FROM和WHERE子句中使用。 XMLTABLE函数允许多个XPath或XQuery表达式指定文档中的元素,然后像在关系表中一样对其进行访问。 XMLTABLE函数中的一个XQuery表达式用作生成行的表达式,这意味着XMLTABLE函数针对此XQuery表达式返回的每一项返回一行。 使用多个XMLTABLE函数调用可以模拟基于SQL的工具可用的外键关系。 有关XMLTABLE函数的更多详细信息,您可以阅读developerWorks文章XMLTABLE示例

有时将XML转换为关系数据称为“切碎”。 使用DB2 pureXML可以切碎文档而无需从数据库中检索它,并将结果存储在关系表中。

留言内容

ASDI消息

为了探索XML文档的分解或“分解”,将使用“向工业界展示飞机状况(ASDI)”作为其架构。 ASDI是一个定义明确的标准,它使用XML通过数据馈送向航空业成员传播有关空中交通数据的信息。 该信息以包含多个消息的流的形式到达, 如图1所示。 共有11条常见消息,它们由81个核心元素组成。

arrivalInformation消息

ASDI提要中的一种消息是到达消息。 它具有一种到达信息( 图2 )。 此复杂类型定义为qualifiedAircraftIdType类型( 图3 )和timeOfArrivalType类型的两个元素。 QualifiedAircraftIdType由computerIdType( 图4 ),出发位置信息和到达位置信息组成。

图1.典型消息流的框图
框图显示asdiMessage数据包中的多个到达信息消息
图2. ArrivalInformationType模式
ArrivalInformationType的图表,显示它由合格的AircraftIdType和timeOfArrivalType组成
图3.qualifiedAircraftIdType模式
合格的AircraftId类型的图表,显示它由flightClass,aircraftIdType,flightComputerIdType,departmentPointType和arrivalPointType组成
图4. computerIdType模式
computerId Type的图表,显示它由facilityIdentifiedType,comptuerSystemIdType和idNumberType组成

分解文件

场景:分析人员希望运行一些查询以汇总到达信息。 仅需要一部分可用数据。 该数据将汇总为报告。 这是一个一次性的过程,将仅偶尔运行且优先级较低。

定义重要的数据元素

应用程序不需要了解文档架构中的所有元素。 第一步应该是编译重要元素和XPATH表达式的列表,以在XML文档中找到它们。 下一步考虑聚合或过滤可能需要的其他元素。

一旦定义了重要元素,就可以从XML模式,样本文档和提供的转换中确定它们的关系数据类型。 然后可以将紧密相关的元素分组为表和相关表,类似于用于传统关系数据库建模的方法。 拥有一个如表1所示的清单很有用,该清单使用源元素的XPATH表达式跟踪关系表,列和数据类型。 如果需要进行转换以更改返回数据的方式,则也可以在清单中注明。

在ASDI模式中,computerId具有三个元素,它们是字符串,可以在关系数据库中表示为单个表。

表1.该表显示了从关系列到XPATH表达式的computerId映射
数据类型 XPATH
计算机ID facilityId VARCHAR(4) / adiMessage / arrivalInformation / nxcm:qualifiedAircraftId / nxce:computerId / nxce:facilityIdentifier
计算机ID computerSystemId VARCHAR(5) / asdiMessage / arrivalInformation / nxcm:qualifiedAircraftId / nxce:computerId / nxce:computerSystemId
计算机ID 身份证号码 VARCHAR(3) / asdiMessage / arrivalInformation / nxcm:qualifiedAircraftId / nxce:computerId / nxce:idNumber
清单1. ComputerId表
CREATE TABLE computerid (
	facilityID       VARCHAR(4),
	computersystemID VARCHAR(5),
	idnumber	 VARCHAR(3)
)
清单2.填充ComputerId表的XMLTable查询
INSERT INTO computerid (facilityID, computersystemID, idnumber)
SELECT X.facilityID, X.computersystemID, x.idnumber
FROM XMLTABLE (
    XMLNAMESPACES( 'http://tfm.faa.gov/tfms/NasXCoreElements'	AS "nxce",
                   'http://tfm.faa.gov/tfms/MessageMetaData'	AS "mmd",
                   'http://tfm.faa.gov/tfms/NasXCommonMessages'	AS "nxcm",
                   'http://www.w3.org/2001/XMLSchema-instance'	AS "xsi" ),
  '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation/
  	nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING CAST(? as XML) as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber'
) as X

注意:为了简洁起见,所有其他代码清单将省略XMLNAMESPACES声明。

链接层次结构中的元素

场景:分析人员现在希望对computerId数据和合格的AircraftId数据执行更复杂的分析。 因为合格的AircraftId条目可能存在多个computerId条目,所以实体需要它们自己的表。

检查有趣元素列表时,层次结构应该很明显。 现在应该将逻辑组或相同XML数据类型中的元素组合在一起。

例如,computerId内的所有元素都可以在qualifiedAircraftId下分组, qualifiedAircraftId到达信息分组 。 DeparturePoint在qualifiedAircraftId下,但与computerId不相关,因此应与computerId元素分开分组。 类似地,应将ArrivalPoint分组在一起,但应与离开Point和computerId分开。 由于到达点和离开点共享所有相同的元素,因此可以将它们一起存储在表中,并使用其他列来声明它们是什么。

当这些元素分成不同的表时,它们需要一个代理键来链接父级和子级。 函数GENERATE_UNIQUE()创建一个通用唯一标识符(UUID),可以用作代理键。 存储的层次结构中的每个级别都需要引用其上的级别,以维护文档中的引用完整性。

可以使用清单3中SQL创建图5所示的数据模型。

图5.通过UUID模式链接的QualifiedAircraft和ComputerId
qualifiedAircraft和ComputerId表的架构图,显示了生成的UUID上的外键关系
CREATE TABLE computerid (
	parentUUID	 CHAR(13) FOR BIT DATA,
	facilityID	 VARCHAR(4),
	computersystemID VARCHAR(5),
	idnumber	 VARCHAR(3)
);

CREATE TABLE qualifiedAircraft (
	QA_UUID 	CHAR(13) FOR BIT DATA NOT NULL PRIMARY KEY,
	aircraftID	VARCHAR(6),
	flightClass	VARCHAR(16)
);
alter table computerid add  foreign key (parentUUID) 
	references qualifiedAircraft(QA_UUID);

清单4中的代码用于填充两个表并根据生成的UUID维护外键关系。

清单4.用于填充链接的computerId和qualifiedAircraftId的复杂XMLTable查询
-- The statement terminator character is @
begin atomic
declare QA_UUID CHAR(16) FOR BIT DATA;

SET (QA_UUID) = (
SELECT QA_UUID FROM NEW TABLE (
  INSERT INTO qualifiedaircraft (QA_UUID, aircraftID, flightClass)
  SELECT GENERATE_UNIQUE(), X.aircraftID, X.flightClass
  FROM XMLTABLE (
    '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation/nxcm:qualifiedAircraftId'
	PASSING CAST(? as XML) as "DOC"
    COLUMNS
	  aircraftID	VARCHAR(6)	PATH 'nxce:aircraftId',
	  flightClass	VARCHAR(16)	PATH '@flightClass'
  ) as X
)
);

INSERT INTO computerid (parentUUID, facilityID, computersystemID, idnumber)
SELECT QA_UUID, X.facilityID, X.computersystemID, x.idnumber
FROM XMLTABLE (
  '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation/
  	nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING XMLDOCUMENT(?) as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber'
) as X
;

end@

清单4将正确维护外键关系,只要该文档中有一个合格的AircraftId实体即可。 如果有多个computerid条目,则每个条目都将指向该合格的AircraftId条目。 如果存在多个合格的AircraftId实体,则必须定义一个循环以执行computerId插入。 清单13演示了这一点。

规划未来的分解

场景:应用程序所有者赞赏分析人员正在生成的报告。 他们现在要求更多的XML数据是关系数据。 他们尚未决定哪些部分很重要,但知道一个子集。 他们渴望入门,并找出下一阶段用户的缺失。

文档中每个感兴趣的元素都可以XML形式保存,以备将来分解( 图6 )。 这可以通过在关系表中定义一个附加的XML列来完成( 清单5 )。 以这种方式存储元素可能是填充将来可能添加到架构的任何列的有效方法。

图6.具有文档片段的QualifiedAircraft和ComputerId
qualifiedAircraft和ComputerId表的架构图,显示了XML列的附加项
清单5.带有UUID和XML列的ComputerId和qualifiedAircraft表
CREATE TABLE computerid (
	parentUUID	 CHAR(16) FOR BIT DATA,
	facilityID	 VARCHAR(4),
	computersystemID VARCHAR(5),
	idnumber	 VARCHAR(3),
	doc		 XML
);

CREATE TABLE qualifiedAircraft (
	QA_UUID 	CHAR(16) FOR BIT DATA,
	aircraftID	VARCHAR(6),
	flightClass	VARCHAR(16),
	doc		XML
);

通过将新表达式添加到XMLTABLE函数的COLUMNS子句中,可以修改先前的查询以填充两个表中的XML列。 结果是清单6。

清单6. 使用XML数据填充computerId和qualifiedAircraftId表的复杂XMLTable查询
-- The statement terminator character is @
begin atomic
declare V_UUID CHAR(16) FOR BIT DATA;

SET (V_UUID) = (
SELECT QA_UUID FROM NEW TABLE (
  INSERT INTO qualifiedaircraft (QA_UUID, aircraftID, flightClass, doc)
  SELECT GENERATE_UNIQUE(), X.aircraftID, X.flightClass, XMLDOCUMENT(X.doc)
  FROM XMLTABLE (
    '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation/nxcm:qualifiedAircraftId'
	PASSING CAST(? as XML) as "DOC"
    COLUMNS
	  aircraftID	VARCHAR(6)	PATH 'nxce:aircraftId',
	  flightClass	VARCHAR(16)	PATH '@flightClass',
	  DOC		XML		PATH '.'
  ) as X
 )
);

INSERT INTO computerid (parentUUID, facilityID, computersystemID, idnumber, doc)
SELECT QA.QA_UUID, X.facilityID, X.computersystemID, x.idnumber, XMLDOCUMENT(x.doc)
FROM qualifiedaircraft qa, XMLTABLE (
  '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING QA.DOC as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber',
	DOC		 XML		PATH '.'
 ) as X
WHERE QA.QA_UUID = V_UUID
;

end@

本示例仍然使用为qualifiedAircraft生成的UUID,并且不适用于同一文档中的多个qualifiedAircraft实体。 应用程序可以使用所有生成的UUID填充临时表或数组,并以相同的方式填充computerid表,用适当的逻辑替换V_UUID变量。

可以将其他支持表和列添加到架构中,以允许应用程序排队并分配其分解活动。 例如,可以添加一个时间戳列以跟踪DOC列的最后分解时间。

性能考量

XMLTABLE的性能取决于其输入的内容。 这可能意味着要解析的文档的大小和复杂性,要​​返回的列数以及用于在文档中定义这些列的XPATH表达式。 一些使性能最大化的建议:

引用层次结构中的较高元素时,请使用XMLQUERY

当XMLTABLE的COLUMNS子句中的元素在层次结构中高于文档的根引用元素(PATH表达式以“ ..”开头)时,改用XMLQUERY可能更有效。 当XMLTABLE函数产生多行时,这一点尤其明显。

清单7.查询其中computerID表也应具有合格的Aircraft XML文档的情况。
INSERT INTO computerid (parentUUID, facilityID, computersystemID, idnumber, 
	computerdoc, qualifiedaircraftdoc)
SELECT QA.QA_UUID, X.facilityID, X.computersystemID, x.idnumber, 
	XMLDOCUMENT(x.computerdoc), XMLDOCUMENT(x.qualifiedAircraftDoc)
FROM qualifiedaircraft qa, XMLTABLE (
  '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING QA.DOC as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber',
	computerDOC	 XML		PATH '.',
	qualifiedAircraftDoc	XML	PATH '..'
) as X
WHERE QA.QA_UUID =  V_UUID

qualifiedAircraftDoc元素是指层次结构中较高的值。 如果将此元素移到SELECT子句,则该查询的性能会更好。

清单8.为了在生成多个computerId条目时获得更好的性能,请使用以下语句。
INSERT INTO computerid (parentUUID, facilityID, computersystemID, idnumber, 
	computerdoc, qualifiedaircraftdoc)
SELECT QA.QA_UUID, X.facilityID, X.computersystemID, x.idnumber, 
	XMLDOCUMENT(x.computerdoc) as cdoc , 
XMLQUERY('declare namespace nxcm="http://tfm.faa.gov/tfms/NasXCommonMessages";
	$MDOC/nxcm:qualifiedAircraftId' PASSING QA.DOC as "MDOC") as qdoc
FROM qualifiedaircraft qa, XMLTABLE (
  '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING QA.DOC as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber',
	computerDOC	 XML		PATH '.'
) as X
WHERE QA.QA_UUID =  V_UUID

生成多个XML值时

如果COLUMNS子句将多个元素定义为XML类型,则可能会对性能产生明显影响。 最好组合这些元素,更充分地分解它们,或者以不同于主流处理方式的其他方式处理它们,例如对它们进行排队以供以后处理。

其他分解策略

使用视图

场景:该应用程序继续受到欢迎,并且越来越多的数据被合并到其中。 不幸的是,磁盘没有被添加到系统中,因此,除了XML文档之外,不再可能存储新数据。 您决定对XML文档实施视图。

清单9中, computerId已实现为基于清单5中 qualifiedAircraft表的视图。

清单9.作为视图的ComputerId
create view v_computerid as (
SELECT QA.QA_UUID as parentuuid, X.facilityID, X.computersystemID, x.idnumber, 
	XMLDOCUMENT(x.doc) as doc
FROM qualifiedaircraft qa, XMLTABLE (
  '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING QA.DOC as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber',
	DOC		 XML		PATH '.'
) as X
)

视图可以嵌套。 通过使用承载XML片段方法,可以在合格的Aircraft视图上构建computerId视图。

图7. QualifiedAircraft和ComputerId是基于ArrivalInformation构建的视图
显示视图嵌套的ArrivalInformation,QalifiedAircraft和ComputerId的架构图
清单10. ComputerId和qualifiedAircraft Id作为viewinInformation表上的视图
CREATE TABLE arrivalInformation (
	AI_UUID		CHAR(16) FOR BIT DATA,
	timeOfArrival	TIMESTAMP,
	timeEstimated	CHAR(1),
	DOC		XML
	);

INSERT INTO arrivalInformation (AI_UUID, timeOfArrival, timeEstimated, DOC)
SELECT generate_unique(), UDFS.ZULU_TO_TIMESTAMP(X.timeofarrival), 
      CASE UPPER(X.timeEstimated) WHEN 'TRUE' then 'T' else 'F' END, XMLDOCUMENT(X.DOC)
  FROM XMLTABLE (
    '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation'
	PASSING CAST(? as XML) as "DOC"
    COLUMNS
	  timeofarrival	VARCHAR(20)	PATH 'nxcm:timeOfArrival',
	  timeEstimated	VARCHAR(6)	PATH 'nxcm:timeOfArrival/@estimated',
	  DOC		XML		PATH '.'
  ) as X
;

create or replace view v_qualifiedaircraft as (
SELECT AI_UUID as parentUUID, GENERATE_UNIQUE() as QA_UUID, X.aircraftID, 
	X.flightClass, X.DOC
FROM arrivalInformation AI, XMLTABLE (
    '$DOC/*:arrivalInformation/nxcm:qualifiedAircraftId'
	PASSING AI.DOC as "DOC"
    COLUMNS
	  aircraftID	VARCHAR(6)	PATH 'nxce:aircraftId',
	  flightClass	VARCHAR(16)	PATH '@flightClass',
	  DOC		XML		PATH '.'
  ) as X
);

create or replace view v_computerid as (
 SELECT VQA.QA_UUID as parentuuid, X.facilityID, X.computersystemID, x.idnumber, 
	XMLDOCUMENT(x.doc) as computer
 FROM v_qualifiedaircraft vqa, XMLTABLE (
  '$DOC/ nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING VQA.DOC as "DOC"
  COLUMNS
	facilityID	 VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	idNumber	 VARCHAR(3)	PATH 'nxce:idNumber',
	DOC		 XML		PATH '.'
 ) as X
)
;

computerId视图建立在合格的Aircraft视图上,该视图建立在arrivalInformation表的DOC列上。

清单11.在生成的UUID上将元素重新结合在一起。
select AI.timeOfArrival, AI.timeEstimated, VQA.aircraftID, VCI.facilityId
from arrivalInformation AI, v_qualifiedaircraft VQA, v_computerid VCI
WHERE VQA.parentuuid = AI.AI_UUID
  AND VCI.parentuuid = VQA.QA_UUID
清单12.上面使用的ZULU_TO_TIMESTAMP函数将时间戳从ASDI消息转换为DB2时间戳。
CREATE OR REPLACE FUNCTION UDFS.ZULU_TO_TIMESTAMP ( inStr VARCHAR(22) )
  RETURNS TIMESTAMP LANGUAGE SQL SPECIFIC ZULU_TO_TIMESTAMP
  DETERMINISTIC CALLED ON NULL INPUT
  
   return values (timestamp(substr(inStr,1,10) || '-' || 
   	replace(substr(inStr,12,instr(inStr,'Z')-12),':','.')))

使用存储过程

存储过程是一种使业务逻辑接近数据库中数据的方法。 他们可以执行SQL中困难或不可能的复杂操作。 在这种情况下,存储过程可以将单个XML文档作为参数并将其部分插入到多个表中。

清单13.用于从一个XML文档填充多个表的表模式和存储过程
CREATE TABLE arrivalInformation (
	AI_UUID		CHAR(13) FOR BIT DATA,
	timeOfArrival	TIMESTAMP,
	timeEstimated	CHAR(1),
	DOC		XML
	)@

CREATE TABLE qualifiedAircraft (
	parentuuid 	CHAR(13) FOR BIT DATA,
	QA_UUID 	CHAR(13) FOR BIT DATA,
	aircraftID	VARCHAR(6),
	flightClass	VARCHAR(16),
	DOC		XML
)
@
CREATE TABLE computerid (
	parentUUID	 CHAR(13) FOR BIT DATA,
	facilityID	 VARCHAR(4),
	computersystemID VARCHAR(5),
	idnumber	 VARCHAR(3),
	DOC		 XML
)
@


CREATE OR REPLACE PROCEDURE shred_flightPlanInfo (IN cFlightPlanInfo XML)
	SPECIFIC SHRED_FLIGHTPLANINFO
	LANGUAGE SQL
main: BEGIN

	DECLARE v_AI_uuid, v_QA_uuid	CHAR(13) for bit data;

	-- Loop over the ArrivalInformation

    FOR v_AI AS select UDFS.ZULU_TO_TIMESTAMP(X.timeofarrival) timeofarrival, 
	CASE UPPER(X.timeEstimated) WHEN 'TRUE' then 'T' else 'F' END timeestimated, 
	XMLDOCUMENT(X.DOC) DOC
	  FROM XMLTABLE (
	    '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation'
		PASSING cFlightPlanInfo as "DOC"
	    COLUMNS
		timeofarrival	VARCHAR(20)	PATH 'nxcm:timeOfArrival',
		timeEstimated	VARCHAR(6)	PATH 'nxcm:timeOfArrival/@estimated',
		DOC		XML		PATH '.'
		  ) as X
	DO
		SET v_AI_uuid = GENERATE_UNIQUE();
		INSERT INTO arrivalInformation (AI_UUID, timeOfArrival, 
			timeEstimated, doc) 
		  values (v_AI_uuid,
		  	  v_AI.timeOfArrival,
		  	  v_AI.timeEstimated,
		  	  v_AI.DOC );
		
		FOR v_QA AS SELECT GENERATE_UNIQUE() as QA_UUID, X.aircraftID, 
				X.flightClass, XMLDOCUMENT(X.DOC) DOC
			FROM XMLTABLE (
		'$DOC/*:arrivalInformation/nxcm:qualifiedAircraftId'
		PASSING v_AI.DOC as "DOC"
		COLUMNS
		  aircraftID	VARCHAR(6)	PATH 'nxce:aircraftId',
		  flightClass	VARCHAR(16)	PATH '@flightClass',
		  DOC		XML		PATH '.'
			  ) as X
		DO
			SET v_QA_uuid = GENERATE_UNIQUE();
			INSERT INTO qualifiedAircraft (parentUUID, QA_UUID, 
					aircraftID, flightClass, doc) 
				values (v_AI_uuid,
					v_QA_uuid,
					v_QA.aircraftID,
					v_QA.flightClass,
					v_QA.DOC );
			
		  INSERT INTO computerid (parentUUID, facilityID, computersystemid, 
		    idnumber, doc) 
		  SELECT v_QA_uuid, X.facilityID, X.computersystemID, x.idnumber, 
			XMLDOCUMENT(x.doc) as computer
		  FROM v_qualifiedaircraft vqa, XMLTABLE (
		    '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
			PASSING v_QA.DOC as "DOC"
			COLUMNS
			  facilityID	   VARCHAR(4)	PATH 'nxce:facilityIdentifier',
			  computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
			  idNumber	   VARCHAR(3)	PATH 'nxce:idNumber',
			  DOC		   XML		PATH '.'
			) as X;
		END FOR;
	END FOR;
	COMMIT;
END main 
@

使用触发器

如果在关系数据库中完全创建了ASDI模式,则很明显,多个消息将写入同一对象。 由于对象分解相同,而不管其来源如何,因此可以将过程视为一组触发器来处理。

可以在关系表上定义触发器,以在插入新行时引起级联效果。 当前在触发器中的转换变量中使用XML数据类型存在限制,但是可以通过与使用AFTER触发器中使用生成的ID插入的行联接来解决。

清单14.使用存储过程中的模式触发DDL
CREATE OR REPLACE TRIGGER trig_ins_qa AFTER INSERT ON qualifiedAircraft
REFERENCING NEW as NEWROW FOR EACH ROW
  INSERT INTO computerid (parentUUID, facilityID, computersystemID, idnumber, DOC)
    SELECT NEWROW.QA_UUID, X.facilityID, X.computersystemID, x.idnumber, 
    	XMLDOCUMENT(X.DOC)
    FROM qualifiedAircraft QA, XMLTABLE (
         '$DOC/nxcm:qualifiedAircraftId/nxce:computerId'
	PASSING QA.DOC as "DOC"
	COLUMNS
	 facilityID	  VARCHAR(4)	PATH 'nxce:facilityIdentifier',
	 computerSystemId VARCHAR(5)	PATH 'nxce:computerSystemId',
	 idNumber	  VARCHAR(3)	PATH 'nxce:idNumber',
	 DOC		  XML		PATH '.'
    ) as X
    WHERE QA.QA_UUID = NEWROW.QA_UUID
;

CREATE OR REPLACE TRIGGER trig_ins_ai AFTER INSERT ON arrivalInformation
REFERENCING NEW as NEWROW FOR EACH ROW
  INSERT INTO qualifiedAircraft (parentUUID, QA_UUID, aircraftId, flightClass, DOC)
   SELECT NEWROW.AI_UUID, GENERATE_UNIQUE(), X.aircraftId, X.flightClass, 
  	XMLDOCUMENT(X.DOC)
   FROM arrivalinformation AI, XMLTABLE (
	  '$DOC/*:arrivalInformation/nxcm:qualifiedAircraftId'
	PASSING AI.DOC as "DOC"
	COLUMNS
	 aircraftID	VARCHAR(6)	PATH 'nxce:aircraftId',
	 flightClass	VARCHAR(16)	PATH '@flightClass',
	 DOC		XML		PATH '.'
    ) as X
    WHERE AI.AI_UUID = NEWROW.AI_UUID
;

insert into arrivalInformation (AI_UUID, timeOfArrival, timeEstimated, DOC)
SELECT generate_unique(), UDFS.ZULU_TO_TIMESTAMP(X.timeOfArrival), 
    CASE UPPER(X.timeEstimated) WHEN 'TRUE' then 'T' else 'F' END, 
    XMLDOCUMENT(X.DOC)
FROM XMLTABLE (
	 '$DOC/*:asdiOutput/*:asdiMessage/*:arrivalInformation'
	PASSING CAST(? as XML) as "DOC"
	COLUMNS
	  timeofarrival	VARCHAR(20)	PATH 'nxcm:timeOfArrival',
	  timeEstimated	VARCHAR(6)	PATH 'nxcm:timeOfArrival/@estimated',
	  DOC		XML		PATH '.'
) as X

摘要

本文提供了一些将XML数据转换为关系数据的方法。 为了说明多个层次结构和重复元素的处理,使用了复杂但定义明确的文档架构。 本文重点介绍了一些需要注意的项目,例如重复元素,关系层次结构和将来的注意事项。

附录A –使用的XML文档

清单15.用于测试的示例到达信息文档片段。
<?xml version="1.0" encoding="UTF-8"?><asdiOutput 
	xmlns="http://tfm.faa.gov/tfms/TFMS_XIS" 
	xmlns:nxce="http://tfm.faa.gov/tfms/NasXCoreElements"
	xmlns:mmd="http://tfm.faa.gov/tfms/MessageMetaData"
	xmlns:nxcm="http://tfm.faa.gov/tfms/NasXCommonMessages"
	xmlns:idr="http://tfm.faa.gov/tfms/TFMS_IDRS" 
	xmlns:xis="http://tfm.faa.gov/tfms/TFMS_XIS" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://tfm.faa.gov/tfms/TFMS_XIS 
	http://localhost:58489/tfms/schema/TFMS_XIS.xsd" 
	timestamp="2009-09-21T12:57:19Z">
  <asdiMessage sourceFacility="KZSE" sourceTimeStamp="2009-09-21T12:57:07Z" trigger="AZ">
    <arrivalInformation>
      <nxcm:qualifiedAircraftId>
        <nxce:aircraftId>QXE483</nxce:aircraftId>
        <nxce:computerId>
          <nxce:facilityIdentifier>KZSE</nxce:facilityIdentifier>
        </nxce:computerId>
        <nxce:departurePoint>
          <nxce:fix>
            <nxce:namedFix>KBLI</nxce:namedFix>
          </nxce:fix>
        </nxce:departurePoint>
        <nxce:arrivalPoint>
          <nxce:fix>
            <nxce:namedFix>KSEA</nxce:namedFix>
          </nxce:fix>
        </nxce:arrivalPoint>
      </nxcm:qualifiedAircraftId>
      <nxcm:timeOfArrival estimated="true">2009-09-21T12:54:00Z</nxcm:timeOfArrival>
    </arrivalInformation>
  </asdiMessage>
</asdiOutput>

附录B –修改后的XML文档

清单16.一个带有多个computerId条目的测试文档,以测试循环逻辑。
<?xml version="1.0" encoding="UTF-8"?><asdiOutput 
	xmlns="http://tfm.faa.gov/tfms/TFMS_XIS" 
	xmlns:nxce="http://tfm.faa.gov/tfms/NasXCoreElements" 
	xmlns:mmd="http://tfm.faa.gov/tfms/MessageMetaData" 
	xmlns:nxcm="http://tfm.faa.gov/tfms/NasXCommonMessages" 
	xmlns:idr="http://tfm.faa.gov/tfms/TFMS_IDRS" 
	xmlns:xis="http://tfm.faa.gov/tfms/TFMS_XIS" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://tfm.faa.gov/tfms/TFMS_XIS 
	http://localhost:58489/tfms/schema/TFMS_XIS.xsd" 
	timestamp="2009-09-21T12:57:19Z">
  <asdiMessage sourceFacility="KZSE" 
  	sourceTimeStamp="2009-09-21T12:57:07Z" trigger="AZ">
    <arrivalInformation>
      <nxcm:qualifiedAircraftId>
        <nxce:aircraftId>QXE483</nxce:aircraftId>
        <nxce:computerId>
          <nxce:facilityIdentifier>KZSE</nxce:facilityIdentifier>
        </nxce:computerId>
        <nxce:computerId>
          <nxce:facilityIdentifier>RGW1</nxce:facilityIdentifier>
        </nxce:computerId>
        <nxce:computerId>
          <nxce:facilityIdentifier>JAW1</nxce:facilityIdentifier>
        </nxce:computerId>
        <nxce:departurePoint>
          <nxce:fix>
            <nxce:namedFix>KBLI</nxce:namedFix>
          </nxce:fix>
        </nxce:departurePoint>
        <nxce:arrivalPoint>
          <nxce:fix>
            <nxce:namedFix>KSEA</nxce:namedFix>
          </nxce:fix>
        </nxce:arrivalPoint>
      </nxcm:qualifiedAircraftId>
      <nxcm:timeOfArrival 
      	estimated="true">2009-09-21T12:54:00Z</nxcm:timeOfArrival>
    </arrivalInformation>
  </asdiMessage>
</asdiOutput>

翻译自: https://www.ibm.com/developerworks/data/library/techarticle/dm-1211purexml/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值