循环在尝试通过 Oracle EBS 中的并发程序使用 PL/SQL 创建 XML 时提前结束
Posted
技术标签:
【中文标题】循环在尝试通过 Oracle EBS 中的并发程序使用 PL/SQL 创建 XML 时提前结束【英文标题】:Loop ending early in trying to create XML using PL/SQL via concurrent programs in Oracle EBS 【发布时间】:2020-10-30 16:37:25 【问题描述】:这是我过去一直在工作的基本代码。
我一直在尝试使用 PLSQL 和 EBS 并发程序创建 XML 文件。我过去使用第一组代码已经成功完成。但目前我的第二个代码停在线路送货地址,只设置了 1 行。
LOOP
FND_FILE.put_line(FND_FILE.OUTPUT,'<ROW>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ACCOUNT_NUMBER>'||rec.ACCOUNT_NUMBER||'</ACCOUNT_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ACCOUNT_NAME>'||replace(rec.ACCOUNT_NAME,'&','and')||'</ACCOUNT_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ADDRESS1>'||rec.ADDRESS1||'</ADDRESS1>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<CITY>'||rec.CITY||'</CITY>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<STATE>'||rec.STATE||'</STATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<GEOGRAPHY_NAME>'||rec.GEOGRAPHY_NAME||'</GEOGRAPHY_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<POSTAL_CODE>'||rec.POSTAL_CODE||'</POSTAL_CODE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<TRX_DATE>'||rec.TRX_DATE||'</TRX_DATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<TRX_NUMBER>'||rec.TRX_NUMBER||'</TRX_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<DESCRIPTION>'||rec.DESCRIPTION||'</DESCRIPTION>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<receipt_date>'||rec.receipt_date||'</receipt_date>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<receipt_number>'||rec.receipt_number||'</receipt_number>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<CIMA_REV>'||rec.CIMA_REV||'</CIMA_REV>');
FND_FILE.put_line(FND_FILE.OUTPUT,'</ROW>');
END LOOP;
FND_FILE.put_line(FND_FILE.OUTPUT,'</ROWSET>');
这是我目前正在制作的代码,它停在
FOR REC IN C_DATA
LOOP
FND_FILE.put_line(FND_FILE.OUTPUT,'<ROW>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_NUMBER>'||rec.Invoice_Number||'</INVOICE_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_DATE>'||rec.Invoice_Date||'</INVOICE_DATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_AMOUNT>'||rec.Invoice_Amount||'</INVOICE_AMOUNT>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_TYPE>'||rec.Invoice_Type||'</INVOICE_TYPE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_BALANCE>'||rec.Invoice_Balance||'</INVOICE_BALANCE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIP_TO>'||rec.Ship_to||'</SHIP_TO>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIP_TO2>'||rec.Ship_to2||'</SHIP_TO2>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIP_ADDRESS1>'||rec.Ship_address1||'</SHIP_ADDRESS1');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIP_2ADDRESS2>'||rec.Ship_address2||'</SHIP_2ADDRESS2>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<BILL_TO>'||rec.Bill_to||'</BILL_TO>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<BILL_TO2>'||rec.Bill_to2||'</BILL_TO2>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<BILL_ADDRESS1'||rec.Bill_address1||'</BILL_ADDRESS1>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<BILL_ADDRESS2>'||rec.Bill_address2||'</BILL_ADDRESS2>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<DUE_DATE>'||rec.Due_Date||'</DUE_DATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ORIGINAL_TOTAL_AMOUNT>'||rec.Original_Total_Amount||'</ORIGINAL_TOTAL_AMOUNT>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<AMOUNT_DUE>'||rec.Amount_Due||'</AMOUNT_DUE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<DAYS_LATE>'||rec.Days_Late||'</DAYS_LATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_TAX>'||rec.Invoice_Tax||'</INVOICE_TAX>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIP_AND_HANDLING>'||rec.Ship_and_Handling||'</SHIP_AND_HANDLING>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<CUSTOMER_NUMBER>'||rec.Customer_number||'</CUSTOMER_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<CUSTOMER_NAME>'||rec.Customer_name||'</CUSTOMER_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<LINE_NUMBER>'||rec.Line_Number||'</LINE_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<PRODUCT_CODE>'||rec.Product_Code||'</PRODUCT_CODE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<DESCRIPTION>'||rec.Description||'</DESCRIPTION>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<QUANTITY>'||rec.Quantity||'</QUANTITY>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<UNIT_PRICE>'||rec.Unit_Price||'</UNIT_PRICE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ORDER_NUMBER>'||rec.Order_Number||'</ORDER_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<PO_NUMBER>'||rec.PO_Number||'</PO_NUMBER>');
enter code hereFND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SHIPPING_INSTRUCTIONS>'||rec.Shipping_Instructions||'</SHIPPING_INSTRUCTIONS>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<AMOUNT>'||rec.Amount||'</AMOUNT>');
我能做些什么来阻止这种情况发生?
【问题讨论】:
您的</SHIP_ADDRESS1>
标记中似乎缺少结束>
【参考方案1】:
您似乎在'</SHIP_ADDRESS1'
的结束标记和'<BILL_ADDRESS1'
的开始标记中缺少>
。
我建议不要使用字符串连接构建 XML 文件(这可能会导致 XML 格式错误,就像您目前所拥有的那样),我建议您在 select 语句中使用 XMLTYPE
构建 XML。这样,您可以一次构建所有 XML,然后一次性将全部内容写入文件。将您的代码更改为这样的功能将大大减少您需要编写的代码量,并且无需遍历每一行,从而可能提高性能。
在下面的示例中,我使用示例查询来生成一些“发票”数据,但您可以将其更改为您用于光标的任何内容。
DECLARE
l_xml XMLTYPE;
BEGIN
WITH
invoice_data (invoice_number, invoice_date, invoice_amount)
AS
( SELECT LEVEL, SYSDATE - LEVEL, ROUND (DBMS_RANDOM.VALUE (0, 10000), 2)
FROM DUAL
CONNECT BY LEVEL <= 100)
SELECT XMLELEMENT (
"ROWSET",
XMLAGG (
XMLELEMENT (
"ROW",
XMLCONCAT (XMLELEMENT ("INVOICE_NUMBER", invoice_number),
XMLELEMENT ("INVOICE_DATE", invoice_date),
XMLELEMENT ("INVOICE_AMOUNT", invoice_amount)))))
INTO l_xml
FROM invoice_data;
DBMS_XSLPROCESSOR.clob2file (l_xml.getClobVal, 'TMP', 'testfile.txt');
END;
/
如果由于某种原因需要回读文件,可以这样读取文件:
DECLARE
l_clob CLOB;
BEGIN
l_clob := DBMS_XSLPROCESSOR.read2clob ('TMP', 'testfile.txt');
DBMS_OUTPUT.put_line (DBMS_LOB.SUBSTR (l_clob, 32767, 1));
END;
/
【讨论】:
以上是关于循环在尝试通过 Oracle EBS 中的并发程序使用 PL/SQL 创建 XML 时提前结束的主要内容,如果未能解决你的问题,请参考以下文章