应用程序接口概述-db2info.md_message()
DB2 Cube View应用程序接口是一个用于访问维度元数据的接口。它作为一个DB2存储过程被实现,名为db2info.md_message(),传送XML文档进出它所有的参数。
一个存储过程的优点就在于应用程序接口成为中性语言。任何能够与DB2会话的程序设计语言都可以调用这个存储过程。你可以通过ODBC或者JDBC等等使用嵌入式SQL、动态SQL。
在DB2 Cube View Setup and User ' s Guide一书的附录里有这个API的详尽的描述。在本文中,我们将介绍几个例子。
输入参数
存储过程有下面的语法:
DBINFO.MD_MESSAGE(operation IN, metadata IN/OUT, response OUT)
所有的参数是CLOB类型。
存储过程有两个输入参数。第一个是必需的,指定调用程序想执行什么操作。这个操作是:
DESCRIBE
CREATE
ALTER
RENAME
DROP
IMPORT
VALIDATE
某些操作(像CREATE和IMPORT)要求元数据通过第二个参数被传入存储过程。一个操作DESCRIBE通过第二个参数返回元数据。
输出参数
存储过程的第三个参数是一个输出参数。对于每个到这个存储过程的调用,都会通过第三个参数返回一个响应文档。然而,如果出现某些严重错误,那么没有输出响应文档被创建。
分析XML
为了使用应用程序接口,你的程序必须构造传入存储过程的XML文档。你还将需要分析存储过程返回的XML。
DB2 Cube View应用程序接口使用的XML的语法由XSD模式文件指定,XSD模式文件在sqllib/cfg目录。你将使用的XSD模式文件如表1所示。
表⒈与输入和输出参数相联系的XSD文件
应用程序接口参数 |
模式文件 |
Operations and responses(first and third arguments) |
db2md_parameter.xsd |
Metadata (second argument) |
db2md_metadata.xsd anddb2md_types.xsd |
使用应用程序接口
用于调用md_message()存储过程的例程C++代码在sqllib/samples/olap/client/db2mdapiclient.cpp的DB2
Cube View产品中。
如果你是使用Java编写程序,那么这里给出使用JDBC调用存储过程的样例代码段:
/* Calls the DB2 stored procedure passing in the request string * as the first parameter and the metadata string as the second * parameter. If xmlRequestString contains a script or no output * metadata is required the xmlMetadata parameter may be null. * The outputMetadata boolean controls what is returned by the * method. If it is true any output metadata is returned. If * false the response output is returned. */ private String callDB2StoredProc(String xmlRequestString, String xmlMetadataString, boolean outputMetadata) throws OCException, OCApiException { /* Create an SQL command to call the Stored procedure in DB2 * to get the XML */ String sql = "CALL db2info.MD_MESSAGE (?, ?, ?)"; String response = null; String xmlMetadataResponse = null; CallableStatement callStmt = null; try { callStmt = auroraCatalogConnection.prepareCall(sql);
/* Set input parameter to request and metadata strings. */ callStmt.setString (1, xmlRequestString); callStmt.setString (2, xmlMetadataString);
/* Register the output parameters. */ callStmt.registerOutParameter (2, Types.VARCHAR); callStmt.registerOutParameter (3, Types.VARCHAR);
/* Call the stored procedure */ callStmt.execute();
/* Retrieve output parameters. If the procedure was called with * a request that returns metadata in the middle parameter then * xmlMetadataResponse will store the output XML. */ if (outputMetadata == true) xmlMetadataResponse = callStmt.getString(2); response = callStmt.getString(3);
/* See if there are any warnings. */ SQLWarning warning = callStmt.getWarnings();
/* If execute returns a warning with a non-zero SQL state * then the API has had an error and returned some response * info in the output XML document. */ if (warning != null) { OCLog.trace("Stored procedure execute returned a warning."); OCLog.trace("SQL state: " + warning.getSQLState()); OCLog.trace("SQL state: " + warning.getErrorCode());
/* readResponseFromXML will throw an OCApiException containing * the error info (which will then be thrown to our caller) or * it will throw an OCException if a parsing error occurred. If * for some strange reason the file does not contain error * info it will just return and then we'll throw an OCException * to notify the user. */ try { readResponseFromXML(response); }
/* If an API exception was thrown add the SQL state etc to * it and then throw it again. */ catch (OCApiException apie) { apie.setSqlException(warning);
throw apie; } /* If we have had a warning we always want to rollback any changes. * If we have a problem rolling back the exception will be caught * below. */ finally { auroraCatalogConnection.rollback(); }
/* If we got here there must have been a warning with nothing * in the output XML so throw an exception explaining this. */ throw new OCException("OC_ERR_API_DB2_STORED_PROC_FAIL_NO_INFO"); } } /* If we had an error executing the SQL, log the information and * throw an exception. We also rollback any changes and catch * the exception if the rollback has a problem. */ catch (SQLException e) { OCApiException newe = new OCApiException(e); OCLog.trace( newe.getMessage() ); logExceptionInfo(e);
try { auroraCatalogConnection.rollback(); } catch (SQLException e2) { OCLog.trace("An exception also occurred rolling back."); logExceptionInfo(e2); }
throw newe; }
读取元数据
在你有一些成功地调用API的代码之后,你需要把注意力集中在传送正确的XML到应用程序接口中,并且能够分析输出的XML。
大部分的程序将需要使用DESCRIBE操作从DB2 Cube View中读取元数据。这里是一些例子:
例子⒈读取所有的元数据
这里是操作你将使用的XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<describe objectType="all" recurse="no">; </describe>; </olap:request>;
注意:
· 调用程序和服务器上的DB2存储过程的版本号(比如8.1.2.1.0)必须一致。
· 注意请求标记应该是<olap:request>;。
第二个参数将返回包含元数据的一个CLOB。通常,许多对象被返回。如果DB2只有一个Attribute对象,那么输出元数据XML看起来象如下所示:
<olap:metadata xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<attribute name="FAMILY" schema="MDSAMPLE" businessName="FAMILY" createTime="2003-04-11T21:28:22" creator="db2admin">; <datatype schema="SYSIBM" name="VARCHAR" length="15" scale="0"/>; <sqlExpression template="{$$1}">; <column name="FAMILY" tableSchema="MDSAMPLE" tableName="FAMILY"/>; </sqlExpression>; </attribute>; </olap:metadata>;
如果成功的话,响应文档就会看起来象这样:
<olap:response xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<describe>; <status id="0" text="Operation completed successfully. No errors were encountered." type="informational"/>; </describe>; </olap:response>;
例子⒉取得一个指定的Cube模型和关联对象。
下面是你想用来为db2admin.MyCubeModel取得cube模型和它的相关对象的操作XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<describe objectType="cubeModel" recurse="yes">; <restriction>; <predicate property="name" operator="=" value="MyCubeModel"/>; <predicate property="schema" operator="=" value="db2admin"/>; </restriction>; </describe>; </olap:request>;
注意:
· Recurse="yes"让应用程序接口返回Cube模型和所有Cube模型递归调用的对象。
· 注意使用一个指定我们感兴趣的Cube模型的谓词。
创建元数据
有两个操作用于新建元数据:CREATE和IMPORT。当你新建元数据的时候使用CREATE。如果你想创建对象有可能和已有的对象冲突(因为名称相同),那么使用IMPORT。
例子:创建DB2 Cube View中的一些元数据对象
这里是你将使用的操作XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<create/>; </olap:request>;
你将通过第二个参数把XML中的一个或多个元数据对象传到储存过程中。
修改元数据
有两个操作,ALTER和RENAME,用于修改元数据对象。
例子⒈修改一个连接对象
ALTER操作与CREATE相似,除了要传入的元数据对象必须已经存在之外。那些对象将要被新的定义替代。这里是你将使用的操作XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<alter/>; </olap:request>;
对于元数据XML,当我们想要它变化的时候,传入Join对象:
<join name="ProductFamily" schema="db2admin" businessName="ProductFamily" type="inner" cardinality="n:1">; <attributeJoin operator="=">; <leftAttributeRef name="FAMILYID" schema="db2admin"/>; <rightAttributeRef name="FAMILYID (FAMILY)" schema="db2admin"/>; </attributeJoin>; </join>;
例子⒉为一个Cube模型对象改名
假设我们想把一个Cube模型对象从db2admin.SalesModel改名为db2admin.SalesModel(2003)。这里是实现这个操作的XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<rename objectType="cubeModel">; <currentRef name="SalesModel" schema="db2admin"/>; <newRef name="SalesModel (2003)" schema="db2admin"/>; </rename>; </olap:request>;
对于改名,你不需要元数据XML.
删除元数据
使用DROP操作来删除元数据对象。
例子1:删除所有的元数据对象
要小心这个操作!下面是我们要使用的操作XML:
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<drop objectType="all"/>; </olap:request>;
例子⒉删除一个cube对象和它的关联对象
这里是删除db2admin.MyCube和它的关联对象的操作XML。
<olap:request xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<script>; <drop objectType="cube">; <restriction>; <predicate property="name" operator="=" value="My Cube"/>; <predicate property="schema" operator="=" value="db2admin"/>; </restriction>; </drop>; <drop objectType="cubeFacts">; <restriction>; <predicate property="name" operator="=" value="Cube Facts (My Cube)"/>; <predicate property="schema" operator="=" value="db2admin"/>; </restriction>; </drop>; <drop objectType="cubeDimension">;<restriction>; <predicate property="name" operator="=" value="Market (My Cube)"/>; <predicate property="schema" operator="=" value="db2admin"/>; </restriction>;</drop>; <drop objectType="cubeHierarchy">; <restriction>;<predicate property="name" operator="=" value="Region (My Cube)"/>; <predicate property="schema" operator="=" value="db2admin"/>; </restriction>; </drop>; </script>; </olap:request>;
没有元数据XML需要被传入。
排除错误
存储过程中的大部分错误是非常不需加以说明的,虽然你必须习惯用于消息中引用的对象的命名约定。因此,你常常必须非常认真的读这个信息。
下面是一个报告错误的API响应。是当我们试图删除一个不存在的Cube对象(db2admin.My Cube)时返回的信息。(请注意:由于页面的限制,状态消息被分成两行显示。)
<olap:response xmlns:olap="http://www.ibm.com/olap"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="8.1.2.1.0">;
<drop>;
<status id="6006" text="No objects were
found matching search criteria:
"objectType=CUBE & name=My Cube &
schema=db2admin"." type="warning">;
<tokens>;
<text value="objectType=CUBE & name=My
Cube & schema=db2admin"/>;
</tokens>;
</status>;
</drop>;
</olap:response>;
|