我正在研究针对Oracle 10gR2的一些JDBC查询的参数化。
大多数查询的格式为:
String value = "somevalue";
String query = "select dbms_xmlgen.xmlget('select c1, c2 from t1 where c1 = ''"
+ somevalue + "'' ') xml from dual;";
我无法按原样参数化,因为实际的select位于xmlget中的带引号的字符串中,并且参数不会在字符串中展开。 JDBC会将该查询视为没有参数。
我在使用:{/ p>模仿dbms_xmlgen.xmlget
的行为方面相当成功
String query = "SELECT xmltype.getclobval(sys_xmlagg(xmlelement(\"ROW\","
+ "xmlforest(c1, c2)))) xml from t1 where c1 = ?";
我无法解决的唯一问题是查询不返回任何行。
使用dbms_xmlgen.xmlget
,没有行返回空CLOB。但是,对于sys_xmlagg
,没有行会导致CLOB包含:
<?xml version="1.0"?><ROWSET></ROWSET>
我正在寻找一个能给我一个空的CLOB而不是一个空文档的解决方案。
答案 0 :(得分:1)
我目前无法访问Oracle数据库,所以请原谅不准确之处。
DBMS_XMLGEN
调用的参数化似乎是目标。这是通过使用一点PL / SQL来完成的。 The Oracle Docs for the DBMS_XMLGEN package描述了一些应该有用的操作。首先,使用以下格式从SYS_REFCURSOR创建上下文:
DBMS_XMLGEN.NEWCONTEXT (
queryString IN SYS_REFCURSOR)
RETURN ctxHandle;
然后,以GetXML
:
DBMS_XMLGEN.GETXML (
ctx IN ctxHandle,
tmpclob IN OUT NCOPY CLOB,
dtdOrSchema IN number := NONE)
RETURN BOOLEAN;
使用此方法还可以获得可能重用CLOB(而不是创建新临时CLOB)的好处,这可能有助于提高性能。还有另一种形式,它更像你在你的例子中使用的形式,但失去了这个属性。
还有一件事......本例中GETXML
的返回应告诉您是否返回了行。这比操作完成时检查CLOB的内容更可靠。或者,您可以在上下文中使用NumRowsProcessed
函数来获取CLOB中包含的行数。
粗略地说,您的代码看起来像这样:
DECLARE
srcRefCursor SYS_REFCURSOR;
ctxHandle ctxHandle;
somevalue VARCHAR2(1000);
myClob CLOB;
hasRows boolean;
BEGIN
OPEN srcRefCursor FOR
SELECT c1, c2
FROM t1
WHERE c1 = somevalue; --Note parameterized value
ctxHandle := DBMS_XMLGEN.NEWCONTEXT(srcRefCursor);
hasRows := DBMS_XMLGEN.GETXML(
ctxHandle,
myClob -- XML stored in myCLOB
);
IF (hasRows) THEN
/* Do work on CLOB here */
END IF;
DBMS_XMLGEN.CLOSECONTEXT(ctxHandle);
END;