I'm only passingly familiar with XML. I need to parse a response from a SOAP request. From a lot of searching, I've developed the following query to try to extract the status. Ultimately, I'd like to get the status, cntr and cntr_status fields from the response. My query gives no error, but also no results. What noob error am I making?
SELECT *
FROM XMLTABLE (
XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
'http://service.xxx.com/' AS "xxx"),
'/soapenv:Envelope/soapenv:Body/xxx:sendDataResponse/xxx:sendDataReturn/xxx:result'
PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' <cntr_result>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>')
COLUMNS status VARCHAR2(20) PATH 'xxx:status') xmlstuff ;
A sample response from the service is hard-coded into the XMLTYPE function.
I've tried any number of query strings and column paths involving the xxx namespace, all yielding no results.
There could be hundreds of cntr and cntr_status pairs.
Thanks for looking!
Using the DEFAULT namespace (since you don't define a prefix for http://service.xxx.com) and removing the references to xxx: appears to work:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
sqlfiddle here
Then to get the first cntr and cntr_status:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr[1]',
cntr_status VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr_status[1]'
) xmlstuff;
sqlfiddle here
Update for revised XML format
Ideally, you should be able to use the XPATH '/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_status/cntr_result' in the XMLTABLE and then get the status with the path ./../../status; however, I keep getting null values when trying to traverse to a parent element and couldn't find a working solution.
SELECT x.*
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_statuses/cntr_result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH './../../status',
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) x;
sqlfiddle here
According to this comment, it will work in Oracle 11.2.0.4 but if you try it in Oracle 11.2.0.2 then status will be NULL (which is the result seen on SQLFiddle).
Instead, with multiple cntr_result elements you can use two XMLTABLE:
SELECT x.status,
c.cntr,
c.cntr_status
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr_statuses XMLTYPE PATH 'cntr_statuses'
) x
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/cntr_statuses/cntr_result'
PASSING x.cntr_statuses
COLUMNS
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) c;
Assuming your data is in the xml column of the table_name table.
Then the output is:
STATUS
CNTR
CNTR_STATUS
SUCCESS
1234567890A
SUCCESS
SUCCESS
1234567890B
SUCCESS
sqlfiddle here
Related
I have this function called pvt():
Create Or Replace Function pvt()
RETURNS void
LANGUAGE 'plpgsql'
AS '
declare
sqlColumn varchar;
qr varchar;
columnlist varchar;
Begin
sqlColumn= ''select distinct D.sys_cat from (select Row_Number() Over (Partition By Project,Date_ Order By System_) as sys_cat From your_table) D order by D.sys_cat;'';
qr=''prepare pvtstmt as Select D.Project,D.Date_,'';
For columnlist In EXECUTE sqlColumn
Loop
qr=qr || ''
Max(Case When sys_cat=''|| chr(39) || columnlist || chr(39) ||'' Then System_ ||'' ||chr(39)||''-''||chr(39)||''|| Result_ Else '' ||chr(39)||chr(39)||'' End) As System'' || columnlist || '' , '';
END LOOP;
qr=substr(qr, 0, length(qr) - 1);
qr=qr || ''From
(select *, Row_Number() Over (Partition By Project,Date_ Order By System_) as sys_cat From your_table) D Where D.Project='' || chr(39) || ''Proj1'' || chr(39) || ''Group By D.Project,D.Date_ Order By D.Project,D.Date_'';
Deallocate All;
EXECUTE qr;
End;
'
I need to execute these SQL statements:
Select pvt();
Execute pvtstmt;
Currently, I have a queries.js file where I have defined:
const getRunsByProjectTable = `
Select pvt();
Execute pvtstmt;
`
However, when I try to make the API call I do not receive any data back:
const getRunsByProjectTable = (req, res) => {
pool.query(queries.getRunsByProjectTable, (error, results) => {
if (error) throw error;
res.status(200).json(results.rows);
})
}
Does anyone know what the issue may be? Any help would be much appreciated!
I have a sample code from http://phil-sqltips.blogspot.com/2015/07/beware-of-empty-partitions.html and I'd like to understand this xmlgen sql.
WITH t AS (
SELECT table_owner
, table_name
, partition_name
, TO_NUMBER (EXTRACTVALUE (XMLTYPE (DBMS_XMLGEN.getxml ('SELECT COUNT(*) AS rows_exist FROM '
|| DBMS_ASSERT.enquote_name (str => table_owner)
|| '.'
|| DBMS_ASSERT.enquote_name (str => table_name)
|| ' PARTITION ('
|| DBMS_ASSERT.enquote_name (str => partition_name)
|| ') WHERE ROWNUM <= 1'
)
)
, '/ROWSET/ROW/ROWS_EXIST'
)
) AS rows_exist
FROM all_tab_partitions
WHERE table_owner = 'WH'
AND table_name IN ('POINT_OF_SALE_FACTS')
ORDER BY table_owner
, table_name
, partition_position
)
SELECT 'ALTER TABLE '
|| DBMS_ASSERT.enquote_name (str => table_owner)
|| '.'
|| DBMS_ASSERT.enquote_name (str => table_name)
|| ' DROP PARTITION '
|| DBMS_ASSERT.enquote_name (str => partition_name)
|| ';' AS stmt
, t.*
FROM t
WHERE rows_exist = 0
;
I've found most of them except this,
DBMS_ASSERT.enquote_name (str => table_owner).
What is the syntax of arrow in (str => table_owner) inside of enquote_name?
I found this https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_assert.htm#BABDEHBC but there is no such arrow syntax, and couldn't find web sites for this syntax.
That's the named parameter syntax. Here's the relevant documentation. So str => table_name says to set the str parameter to table_name.
In this case, it isn't necessary, since str is the first parameter for DBMS_ASSERT.ENQUOTE_NAME. So you could omit it and just call DBMS_ASSERT.enquote_name(table_owner).
But in some cases it can be very useful. For example, when there are multiple optional parameters (with defaults) and you only want to specify one of them. Or when you want to clarify the purpose of a parameter by displaying the parameter name next to the value.
I am having problems with parsing XML containing name-space.
This is my XML structure (snipped, with modified data):
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02 ./camt.053.001.02.xsd">
<BkToCstmrStmt>
<Stmt>
<Ntry>
<Amt Ccy="EUR">0.0</Amt>
<CdtDbtInd>CCCC</CdtDbtInd>
<Sts>BBBB</Sts>
<BookgDt>
<Dt>2011-01-01</Dt>
</BookgDt>
<ValDt>
<Dt>2011-01-01</Dt>
</ValDt>
<AcctSvcrRef>325569685ASDAS</AcctSvcrRef>
<BkTxCd>
<Prtry>
<Cd>NOTPROVIDED</Cd>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<EndToEndId>DD545454545-54545-54</EndToEndId>
<TxId>46545445G5GG54DD5S</TxId>
</Refs>
<RltdPties>
<Dbtr>
<Nm>TEST</Nm>
<PstlAdr>
<Ctry>JJ</Ctry>
<AdrLine>TEST ADD</AdrLine>
<AdrLine>TEST ADD2</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>000000000000000</IBAN>
</Id>
</DbtrAcct>
<Cdtr>
<Nm>TEST NAME</Nm>
<PstlAdr>
<Ctry>JJ</Ctry>
<AdrLine>TEST ADD3</AdrLine>
<AdrLine>TEST ADD4</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>22222222222222</IBAN>
</Id>
</CdtrAcct>
</RltdPties>
<Purp>
<Cd>IIII</Cd>
</Purp>
<RmtInf>
<Strd>
<CdtrRefInf>
<Ref>GG56565656565656</Ref>
</CdtrRefInf>
<AddtlRmtInf>TEST TEST 123</AddtlRmtInf>
</Strd>
</RmtInf>
<RltdDts>
<IntrBkSttlmDt>2011-01-01</IntrBkSttlmDt>
</RltdDts>
</TxDtls>
</NtryDtls>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>
This is the code i use that works if root element is without namespace ():
DECLARE
l_clob CLOB;
l_bfile BFILE := BFILENAME('XML_IMPORT', 'test_import.xml');
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
l_bfile_csid NUMBER := 0;
l_lang_context INTEGER := 0;
l_warning INTEGER := 0;
l_xml xmltype;
BEGIN
DBMS_LOB.createtemporary (l_clob, TRUE);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.loadclobfromfile (
dest_lob => l_clob,
src_bfile => l_bfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
bfile_csid => l_bfile_csid ,
lang_context => l_lang_context,
warning => l_warning);
DBMS_LOB.fileclose(l_bfile);
l_xml := xmltype(l_clob);
BEGIN
FOR r IN (
SELECT ExtractValue(Value(p),'/Ntry/Amt/text()') as TEMP_COL1
,ExtractValue(Value(p),'/Ntry/Amt/#Ccy/text()') as TEMP_COL2
,ExtractValue(Value(p),'/Ntry/ValDt/Dt/text()') as TEMP_COL3
,ExtractValue(Value(p),'/Ntry/BookgDt/Dt/text()') as TEMP_COL4
FROM TABLE(XMLSequence(Extract(l_xml,'/Document/BkToCstmrStmt/Stmt/Ntry'))) p
)
LOOP
dbms_output.put_line('Some value 1: ' || r.TEMP_COL1);
dbms_output.put_line('Some value 2: ' || r.TEMP_COL2);
dbms_output.put_line('Some value 3: ' || r.TEMP_COL3);
dbms_output.put_line('Some value 4: ' || r.TEMP_COL4);
END LOOP;
END;
END;
I would like to know how to modify my code to work with name space.
Google provided few examples but so far i had no luck implementing them into my solution.
I believe you need to pass the namespace to both the Extract() and ExtractValue() functions e.g.
FOR r IN (
SELECT ExtractValue(Value(p),'/Ntry/Amt/text()', 'xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"') as TEMP_COL1
,ExtractValue(Value(p),'/Ntry/Amt/#Ccy','xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"') as TEMP_COL2
,ExtractValue(Value(p),'/Ntry/ValDt/Dt/text()','xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"') as TEMP_COL3
,ExtractValue(Value(p),'/Ntry/BookgDt/Dt/text()','xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"') as TEMP_COL4
FROM TABLE(XMLSequence(Extract(l_xml,'/Document/BkToCstmrStmt/Stmt/Ntry', 'xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"'))) p
)
LOOP
dbms_output.put_line('Some value 1: ' || r.TEMP_COL1);
dbms_output.put_line('Some value 2: ' || r.TEMP_COL2);
dbms_output.put_line('Some value 3: ' || r.TEMP_COL3);
dbms_output.put_line('Some value 4: ' || r.TEMP_COL4);
END LOOP;
I don't think there is a way to specify a default namespace for the ExtractValue function, so my personal preference would be to do something like this instead which avoids repeatedly declaring the namespace:
FOR r IN (
SELECT p.temp_col1,
p.temp_col2,
p.temp_col3,
p.temp_col4
FROM xmltable(
--define a default namespace to be used for all values
xmlnamespaces(
DEFAULT 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02'
),
--define an xpath expression for the values you want to extract
'/Document/BkToCstmrStmt/Stmt/Ntry'
--pass the xml type in here
PASSING l_xml
--declare the columns you would like to extract and the formats they are expected to be in
COLUMNS
temp_col1 VARCHAR2(128) path '/Ntry/Amt/text()',
temp_col2 VARCHAR2(128) path '/Ntry/Amt/#Ccy',
temp_col3 VARCHAR2(128) path '/Ntry/ValDt/Dt/text()',
temp_col4 VARCHAR2(128) path '/Ntry/BookgDt/Dt/text()'
) p
)
LOOP
dbms_output.put_line('Some value 1: ' || r.temp_col1);
dbms_output.put_line('Some value 2: ' || r.temp_col2);
dbms_output.put_line('Some value 3: ' || r.temp_col3);
dbms_output.put_line('Some value 4: ' || r.temp_col4);
END LOOP;
Sample XML as below:
<Root>
...
<XMLNSC>
...
<SOAP-ENV:Envelope>
...
<SOAP-ENV:Body>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">
last tag typesNS0:getABCD want to select
select xmltype(a).extract('//typesNS0:getABCD','xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/"')
from (
select
'<Root xmlns:SOAP-ENV="http://a.b.org/">
<XMLNSC />
<SOAP-ENV:Envelope/>
<SOAP-ENV:Body/>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">123</typesNS0:getABCD>
</Root>' a from dual
)
You may run below script if you want get exact tag value;
DECLARE
vs_Xml VARCHAR2(32000):= '<Root xmlns:SOAP-ENV="http://a.b.org/">
<XMLNSC />
<SOAP-ENV:Envelope/>
<SOAP-ENV:Body/>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">123</typesNS0:getABCD>
</Root>';
vx_ParameterList XMLTYPE;
vx_Parameter XMLTYPE;
vn_ParameterIndex NUMBER;
vs_Key VARCHAR2(64);
vs_XPath VARCHAR2(255);
vs_Value VARCHAR2(10000);
BEGIN
vx_ParameterList := xmltype(vs_Xml);
vn_ParameterIndex := 1;
vs_XPath := '/Root';
WHILE vx_ParameterList.existsNode(vs_XPath || '[' || vn_ParameterIndex || ']') = 1 LOOP
vx_Parameter := vx_ParameterList.extract(vs_XPath || '[' || vn_ParameterIndex || ']');
vs_Value := vx_Parameter.extract('//typesNS0:getABCD/text()','xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/"').GetStringVal();
vn_ParameterIndex := vn_ParameterIndex + 1;
dbms_output.put_line(vs_Value);
END LOOP;
END;
'm having a problem with my one procedure that suppose to generate an Excel file, the procedure is this one:
CREATE OR REPLACE PROCEDURE GENERATE_REPORT_P(P_CONTRACT_NUM IN VARCHAR2 DEFAULT NULL,
P_CUSTOMER_NAME IN VARCHAR2 DEFAULT NULL,
P_CUSTOMER_NUM IN VARCHAR2 DEFAULT NULL,
P_UPDATE_DATE_START IN DATE DEFAULT NULL,
P_UPDATE_DATE_END IN DATE DEFAULT NULL,
P_ORDER_NUM IN VARCHAR2 DEFAULT NULL) IS
vRecords BOOLEAN := FALSE;
BEGIN
FOR i IN (SELECT
a.contract_num,
d.customer_abt_number,
d.customer_name,
c.doms_order_num order_num,
e.service_tag asset,
e.sku,
e.field,
e.previous_value,
e.new_value,
e.update_date, --to_char(i.update_date, 'DD-MON-RRRR HH12:MI:SS')
e.updated_by
FROM contracts a,
order_extension b,
orders c,
customers d,
abt_cisi_log e
WHERE a.id = b.contract_id
AND c.id = b.order_id
AND d.id = a.customer_id
AND c.id = e.order_id
--parameters
AND a.contract_num LIKE NVL(p_contract_num, a.contract_num)
AND d.customer_abt_number LIKE
NVL(p_customer_num, d.customer_abt_number)
AND d.customer_name LIKE
NVL(p_customer_name, d.customer_name)
AND e.update_date between
NVL(to_date(p_update_date_start, 'dd-mon-rrrr'), '01-JAN-1900') AND
NVL(to_date(p_update_date_end, 'dd-mon-rrrr'), '31-DEC-2199')
AND c.doms_order_num LIKE
NVL(p_order_num, c.doms_order_num)
ORDER BY a.contract_num,
c.doms_order_num,
e.service_tag,
e.sku) LOOP
IF NOT vRecords THEN
vRecords := TRUE;
owa_util.mime_header(ccontent_type => 'application/vnd.ms-excel');
htp.htmlopen;
htp.bodyopen;
htp.tableopen(cattributes => 'border=1');
htp.tablerowopen;
htp.p('<td><b>Contract</b></td>');
htp.p('<td><b>Customer Number</b></td>');
htp.p('<td><b>Customer</b></td>');
htp.p('<td><b>Order#</b></td>');
htp.p('<td><b>Asset</b></td>');
htp.p('<td><b>SKU</b></td>');
htp.p('<td><b>Field</b></td>');
htp.p('<td><b>Previous Value</b></td>');
htp.p('<td><b>New Value</b></td>');
htp.p('<td><b>Update Date</b></td>');
htp.p('<td><b>Updated By</b></td>');
htp.tablerowclose;
END IF;
htp.tablerowopen;
htp.p('<td>' || i.contract_num || '</td>');
htp.p('<td>' || i.customer_abt_number || '</td>');
htp.p('<td>' || i.customer_name || '</td>');
htp.p('<td>' || i.order_num || '</td>');
htp.p('<td>' || i.asset || '</td>');
htp.p('<td>' || i.sku || '</td>');
htp.p('<td>' || i.field || '</td>');
htp.p('<td>' || i.previous_value || '</td>');
htp.p('<td>' || i.new_value || '</td>');
htp.p('<td>' || to_char(i.update_date, 'DD-MON-RRRR HH12:MI:SS') ||
'</td>');
htp.p('<td>' || i.updated_by || '</td>');
htp.tablerowclose;
END LOOP;
IF vRecords THEN
htp.tableclose;
htp.bodyclose;
htp.htmlclose;
END IF;
END GENERATE_REPORT_P;
But when i execute this procedure by
Begin
GENERATE_REPORT_P();
END;
I ALWAYS get this error:
I was trying to figure it out, but not much luclk until now, I've tryed to comment all the code into the procedure and just call the owa_util.mime_header(ccontent_type => 'application/vnd.ms-excel'); To see what happens, and checked the data type from my table, well, pretty much all the basic stuff.
If anyone could give me some help, ou tip, i really appreciate that.
My Regards!
Note: I extract the procedure from a packge, and ajust one or two things just to place at StackOverflow, so, i u see the error message and figere it out, my bad!
To resolve this particular issue put this piece of code somewhere before the call to generate_report_p:
owa.num_cgi_vars := NVL(owa.num_cgi_vars, 0);