Sunday, October 16, 2016

Working with UTL_FILE

UTL
UTL_FILE is available for both client-side and server-side PL/SQL. Both the client (text I/O) and server implementations are subject to server-side file system permission checking.
In the past, accessible directories for the UTL_FILE functions were specified in the initialization file using the UTL_FILE_DIR parameter. However,UTL_FILE_DIR access is not recommended. It is recommended that you use the CREATE DIRECTORY feature, which replaces UTL_FILE_DIR. Directory objects offer more flexibility and granular control to the UTL_FILE application administrator, can be maintained dynamically (that is, without shutting down the database), and are consistent with other Oracle tools. CREATE DIRECTORY privilege is granted only to SYS and SYSTEM by default
 
 
CREATE DIRECTORY test_dir AS 'c:\';
-- CREATE DIRECTORY test_dir AS '/tmp';


DECLARE
  fileHandler UTL_FILE.FILE_TYPE;
BEGIN
  fileHandler := UTL_FILE.FOPEN('test_dir', 'test_file.txt', 'W');
  UTL_FILE.PUTF(fileHandler, 'Writing TO a file\n');
  UTL_FILE.FCLOSE(fileHandler);
EXCEPTION
  WHEN utl_file.invalid_path THEN
     raise_application_error(-20000, 'ERROR: Invalid PATH FOR file.');
END;
/

DECLARE 
  V1 VARCHAR2(32767); 
  F1 UTL_FILE.FILE_TYPE; 
BEGIN 
  -- In this example MAX_LINESIZE is less than GET_LINE's length request 
  -- so the number of bytes returned will be 256 or less if a line terminator is seen. 
  F1 := UTL_FILE.FOPEN('MYDIR','MYFILE','R',256); 
  UTL_FILE.GET_LINE(F1,V1,32767); 
  UTL_FILE.FCLOSE(F1); 
 
  -- In this example, FOPEN's MAX_LINESIZE is NULL and defaults to 1024, 
  -- so the number of bytes returned will be 1024 or less if a line terminator is seen. 
  F1 := UTL_FILE.FOPEN('MYDIR','MYFILE','R'); 
  UTL_FILE.GET_LINE(F1,V1,32767); 
  UTL_FILE.FCLOSE(F1); 
 
  -- In this example, GET_LINE doesn't specify a number of bytes, so it defaults to 
  -- the same value as FOPEN's MAX_LINESIZE which is NULL in this case and defaults to 1024. 
  -- So the number of bytes returned will be 1024 or less if a line terminator is seen. 
  F1 := UTL_FILE.FOPEN('MYDIR','MYFILE','R'); 
  UTL_FILE.GET_LINE(F1,V1); 
  UTL_FILE.FCLOSE(F1); 
END;


INVALID_PATH
File location is invalid.
INVALID_MODE
The open_mode parameter in FOPEN is invalid.
INVALID_FILEHANDLE
File handle is invalid.
INVALID_OPERATION
File could not be opened or operated on as requested.
READ_ERROR
Operating system error occurred during the read operation.
WRITE_ERROR
Operating system error occurred during the write operation.
FILE_OPEN
The requested operation failed because the file is open.
INVALID_MAXLINESIZE
The MAX_LINESIZE value for FOPEN() is invalid; it should be within the range 1 to 32767.
INVALID_FILENAME
The filename parameter is invalid.

Sql Tricky Queries

select parent_id who have at least one boy and one girl

Table: parent_id, parent_name, child_id, child_gender
select parent_id
from your_table
group by parent_id
having count(distinct child_gender) = 2




What is the simplest SQL Query to find the second largest value?


1)
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);
2)
SELECT MAX( col )
  FROM table
 WHERE col < ( SELECT MAX( col )
                 FROM table )

This will delete duplicate rows, except first row
DELETE FROM Mytable 
WHERE RowID NOT IN (SELECT MIN(RowID) 
                    FROM Mytable 
                    GROUP BY Col1,Col2,Col3)



DELETE LU 
FROM   (SELECT *, 
               Row_number() 
                 OVER ( 
                   partition BY col1, col1, col3 
                   ORDER BY rowid DESC) [Row] 
        FROM   mytable) LU 
WHERE  [row] > 1 




SELECT (SYSDATE) +level-1 each_day FROM DUAL CONNECT BY LEVEL <= 10

0/p:
18-DEC-13
19-DEC-13
20-DEC-13
21-DEC-13
22-DEC-13
23-DEC-13
24-DEC-13
25-DEC-13
26-DEC-13

27-DEC-13

Dynamically calling a logo in XML Publisher

Dynamically calling a logo in XML Publisher

In the previous lesson we learnt how to insert a logo statically but in this lesson we are going learn how to insert a logo dynamically.
OA Media Directory Reference
Note: This method only applies to Oracle E-Business Suite Installations.
1.             Insert a dummy image in our template
2.             In the Format Picture dialog box select web tab. Enter the following syntax in the Alternative Text region to reference the OA_MEDIA directory:
                                                                   url:{‘${OA_MEDIA}/< image_name>’}
For example, enter
                                                                   url:{‘${OA_MEDIA}/ORACLE_LOGO.gif’}
We can see step by step process.

Our previous lesson RTF is shown below with static logo. Here the logo which acts as dummy

XML Publisher Report with PLSQL Code

XML Publisher Report with PLSQL Code





1. Create the PLSQL EXECUTABLE of PLSQL Pakage type
2. write the plsql proc, which generate the output in xml.
3. Set the Concurrent Program output as XML.
4. Configure the conc program.
5. Get the program output by running it, save it as xml file
6. Create the rtf template using the xml file.
7. Create the XML Data definition using the XML Publisher responsibility.
8. Create the XML Template using XML Publisher responsibility.
9. Attach the rtf template in XML Template Definition.
10 Run the program, you get the output in excel.




CREATE OR REPLACE PROCEDURE apps.xx_PLSQL_XML_report
(
   errbuf           OUT      VARCHAR2,
   retcode          OUT      VARCHAR2,
   p_geography     IN       NUMBER,
   p_report_type   IN       VARCHAR2
)
AS
   CURSOR c1
   IS
      SELECT REPLACE
             (SELECT papf.full_name FROM apps.per_all_people_f papf WHERE papf.person_id = a.employee_id AND ROWNUM = 1) full_name,
             a.invoice_num, a.description, a.total,
             TRUNC (a.creation_date) creation_date, a.report_submitted_date,
             a.expense_status_code,
             (SELECT s.end_date
                FROM apps.wf_item_activity_statuses s,
                     apps.wf_process_activities p
               WHERE s.item_type = 'APEXP'
                 AND p.activity_name = 'MANAGER_APPROVES'
                 AND p.process_name = 'AP_MANAGER_APPROVAL_PROCESS'
                 AND p.activity_item_type = 'APEXP'
                 AND s.item_key = TO_CHAR (a.report_header_id)
                 AND p.instance_id = s.process_activity)
                                                       manager_approval_date
        FROM apps.ap_expense_report_headers_all a
       WHERE NOT EXISTS (
                SELECT '1'
                  FROM apps.ap_expense_report_lines_all b
                 WHERE a.report_header_id = b.report_header_id
                   AND b.credit_card_trx_id IS NOT NULL)
         AND a.org_id = p_geography
         AND a.vouchno = 0
         AND a.expense_status_code = 'MGRAPPR'
         AND a.report_submitted_date >= '01-JAN-2008';

 
BEGIN
   fnd_file.put_line (fnd_file.LOG, '-------------------------');
   fnd_file.put_line (fnd_file.LOG, 'Program Execution Starts');
   fnd_file.put_line (fnd_file.LOG, '-------------------------');
   fnd_file.put_line (fnd_file.LOG, 'p_geography: ' || p_geography);
   fnd_file.put_line (fnd_file.LOG, 'p_report_type : ' || p_report_type);


FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<?xml version="1.0" encoding="UTF-8"?>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ROOT>');

    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<HEADER>');
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REP_NAME>'          || 'XX Amex Ready to Pay Expense Reports' || '</REP_NAME>'    );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ORG_ID>'          || p_geography            || '</ORG_ID>'    );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<TRANSACTION_TYPE>'      || p_report_type          || '</TRANSACTION_TYPE>'   );
    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</HEADER>');


FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<AMEX_TRX_INFO>');

   IF (p_report_type = 'ONLY_CASH')
   THEN
      fnd_file.put_line (fnd_file.LOG, '-------------------------');
      fnd_file.put_line (fnd_file.LOG, 'Only Cash Trx Report');
      fnd_file.put_line (fnd_file.LOG, '-------------------------');
      FOR c1_rec IN c1
      LOOP
    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<AMEX_CASH_ONLY>');
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<FULL_NAME>'          || c1_rec.FULL_NAME             || '</FULL_NAME>'      );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<INVOICE_NUM>'         || c1_rec.INVOICE_NUM           || '</INVOICE_NUM>'      );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<DESCRIPTION>'         || c1_rec.DESCRIPTION           || '</DESCRIPTION>'      );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<TOTAL>'           || c1_rec.TOTAL                 || '</TOTAL>'       );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<CREATION_DATE>'         || c1_rec.CREATION_DATE         || '</CREATION_DATE>'     );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPORT_SUBMITTED_DATE>' || c1_rec.REPORT_SUBMITTED_DATE || '</REPORT_SUBMITTED_DATE>'   );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<EXPENSE_STATUS_CODE>'   || c1_rec.EXPENSE_STATUS_CODE   || '</EXPENSE_STATUS_CODE>'    );
            FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<MANAGER_APPROVAL_DATE>' || c1_rec.MANAGER_APPROVAL_DATE || '</MANAGER_APPROVAL_DATE>'   );
    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</AMEX_CASH_ONLY>');
      END LOOP;
   END IF;

    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</AMEX_TRX_INFO>'); 
    FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</ROOT>');
    fnd_file.put_line (fnd_file.LOG, '-------------------------');
    fnd_file.put_line (fnd_file.LOG, 'Program Execution Completed');
    fnd_file.put_line (fnd_file.LOG, '-------------------------');
  
  
END xx_PLSQL_XML_report ;


XML Publisher Report from XML Data Template

How to develop XML Publisher reports without using rdf or sql or pl/sql concurrent program. The traditional way is metioned below
1.        Create a RDF or SQL or PL/SQL procedure
2.        Register the RDF or SQL or PL/SQL report as a concurrent program and set the output to XML
3.        Run the above report and get the output and save it as a XML file

4.        Use the XML data in building the Template using Microsoft Word

Alternate method is described below using .xml

The XML data template is an XML document that consists of four basic sections:
1.        Parameters
2.        Triggers
3.        Data Query
4.        Data Structure


The data templates are useful when you need to create a XML Publisher report without using the RDF. The XML Publisher data engine enables you to rapidly generate any kind of XML data structure against any database in a scalable, efficient manner which you can easily use in your templates.

The data template is the method by which you communicate your request for data to the data engine. It is an XML document whose elements collectively define how the data engine will process the template to generate the XML.
This structure is shown in the following graphic:






1] Parameters Section:

A parameter is a variable whose value you can set at runtime. Parameters are especially useful for modifying SELECT statements and setting PL/SQL variables at runtime. However, the Parameters section of the data template is optional.

How to Define Parameters:


1
2
3
4
<parameters>
<parameter name="P_PERIOD_FROM" dataType="character" />
<parameter name="P_PERIOD_TO" dataType="character" />
</parameters>

How to Pass Parameters:

To pass parameters, (for example, to restrict the query), use bind variables in your query. For example:
SELECT *
FROM apps.gl_balances glb
WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO;

2] Data Query Section:

The <dataQuery> section of the data template is required.

How to Define SQL Queries

The <sqlStatement> element is placed between the open and close dataQuery tags. The <sqlStatement> element has a related attribute, name. It is expressed within the <sqlStatment> tag. The query is entered in the CDATA section.
1
2
3
4
5
6
7
<dataQuery>
<sqlStatement name="Q1">
<![CDATA[SELECT *
FROM apps.gl_balances glb
WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO]]>
</sqlStatement>
</dataQuery>

Lexical References:

You can use lexical references to replace the clauses appearing after SELECT, FROM, WHERE, GROUP BY, ORDER BY, or HAVING. Use a lexical reference when you want the parameter to replace multiple values at runtime.
Create a lexical reference using the following syntax:
&parametername
Define the lexical parameters as follows:
• Before creating your query, define a parameter in the PL/SQL default package for each lexical reference in the query. The data engine uses these values to replace the lexical parameters.
• Create your query containing lexical references.
1
2
3
4
5
6
7
<dataQuery>
<sqlStatement name="Q_Lexical">
<![CDATA[ &p_query ]]>
</sqlStatement>
</dataQuery>

<dataTrigger name="beforeReport" source="xxfin_test_pkg.beforeReport" />
In the function xxfin_test_pkg.beforeReport, you can design your query at runtime as below:
p_query VARCHAR2(2000) :=
‘SELECT * apps.gl_balances glb
WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO’;

How to Define a Data Link between Queries:

If you have multiple queries, you must link them to create the appropriate data output. In the data template, there are two methods for linking queries: using bind variables or using the <link> element to define the link between queries.
The following example shows a query link using a bind variable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dataQuery>
<sqlStatement name="Q1">
<![CDATA[SELECT PARENT_COL FROM XXTEST_LINK_TABLE1]]>
</sqlStatement>
</dataQuery>

<dataQuery>
<sqlStatement name="Q2">
<![CDATA[SELECT CHILD_COL FROM XXTEST_LINK_TABLE2]]>
</sqlStatement>
</dataQuery>

<link name="TEST_LINK" parentQuery="Q1" parentColumn="PARENT_COL"
childQuery="Q2" childColumn="CHILD_COL"/>
The <link> element has a set of attributes. Use these attributes to specify the required link information. You can specify any number of links.

3] Using Data Triggers:

Data triggers execute PL/SQL functions at specific times during the execution and generation of XML output. Using the conditional processing capabilities of PL/SQL for these triggers, you can do things such as perform initialization tasks and access the database.
Data triggers are optional, and you can have as many <dataTrigger> elements as necessary. The <dataTrigger> element has a set of related attributes. These are expressed within the <dataTrigger> tag.
For example:
1
2
<dataTrigger name="beforeReport1" source=" xxfin_test_pkg.beforeReport()"/>
<dataTrigger name="beforeReport2" source=" xxfin_test_pkg.beforeReport(:Parameter)"/>
§  Name: The event name to fire this trigger.
§  Source: The PL/SQL <package name>.<function name> where the executable code resides.

4] Data Structure Section:

In the data structure section you define what the XML output will be and how it will be structured. The complete group hierarchy is available for output. You can specify all the columns within each group and break the order of those columns; you can use summaries, and placeholders to further customize within the groups.
Sample Data Structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<dataStructure>
<group name="GROUP_1" source="Q1">
  <element name="LEDGER_ID" value="LEDGER_ID" />
  <element name="LEDGER_SHORT_NAME" value="LEDGER_SHORT_NAME" />
  <element name="LEDGER_DESCRIPTION" value="LEDGER_DESCRIPTION" />
  <element name="LEDGER_NAME" value="LEDGER_NAME" />
  <element name="LEDGER_SUM_BAL_DR" value="ACCT_SUM_BAL_DR" function="SUM()" />
  <element name="LEDGER_SUM_BAL_CR" value="ACCT_SUM_BAL_CR" function="SUM()" />
<group name=" GROUP_2" source="Q1">
  <element name="CODE_COMBINATION_ID" value="CODE_COMBINATION_ID" />
  <element name="ACCOUNTING_CODE_COMBINATION" value="ACCOUNTING_CODE_COMBINATION" />
  <element name="CODE_COMBINATION_DESCRIPTION" value="CODE_COMBINATION_DESCRIPTION" />
  <element name="ACCT_SUM_PR_DR" value="PERIOD_NET_DR" function="SUM()" />
  <element name="ACCT_SUM_PR_CR" value="PERIOD_NET_CR" function="SUM()" />
  <element name="ACCT_SUM_BAL_DR" value="BEGIN_BALANCE_DR" function="SUM()" />
  <element name="ACCT_SUM_BAL_CR" value="BEGIN_BALANCE_CR" function="SUM()" />
<group name=" GROUP_3" source="Q1">
  <element name="PERIOD_YEAR" value="PERIOD_YEAR" />
  <element name="PERIOD_NUMBER" value="PERIOD_NUMBER" />
  <element name="PERIOD_NAME" value="PERIOD_NAME" />
  </group>
  </group>
  </group>
</dataStructure>


How to Call a Data Template:

There are two methods for calling the data engine to process your data template:
• Concurrent Manager
• Data Engine Java APIs
Before you can use either of these methods, you must first register your data template in the Template Manager as a Data Definition. After that you attached the RTF template to that data definition.



Calling a Data Template from the Concurrent Manager:


To use the concurrent manager to execute your data template, you must register a Concurrent Program, using the define Concurrent Programs form:
Executable Name Enter the XML Publisher data engine executable: XDODTEXE
Output Format Select “XML” as the output format.
Note: We do not need to create a concurrent executable as we use a seeded executable XDODTEXE
Concurrent Program – Parameters:
For each parameter in the Data Template, define a parameter in the concurrent program.  The Data Template parameter name should match the concurrent program parameter token

Few tips for best practices:

Performing operations in SQL is faster than performing them in the data template or PL/SQL. It is recommended that you use SQL for the following operations:
§  Use a WHERE clause instead of a group filter to exclude records.
§  Perform calculations directly in your query rather than in the template.
 To maximize performance when building data queries in the data template: XML Publisher tests have shown that using bind variables is more efficient than using the link tag.
The dataStructure section is required for multiple queries and optional for single queries. If omitted for a single query, the data engine will generate flat XML.