Forms Advanced Techniques
Forms Advanced Techniques
Release 4.5
Forms Advanced Techniques, Release 4.5 Part No. A325062 Copyright Oracle Corporation 1994 All rights reserved. Printed in the U.S.A. Contributing Authors: Ken Chu, Gina Lim Contributors: Mark Clark, David Navas, Eric Newman, David Walker This software was not developed for use in any nuclear, aviation, mass transit, medical, or other inherently dangerous applications. It is the customers responsibility to take all appropriate measures to ensure the safe use of such applications if the programs are used for such purposes. This software/documentation contains proprietary information of Oracle Corporation; it is provided under a license agreement containing restrictions on use and disclosure and is also protected by copyright law. Reverse engineering of the software is prohibited. If this software/documentation is delivered to a U.S. Government Agency of the Department of Defense, then it is delivered with Restricted Rights and the following legend is applicable: Restricted Rights Legend Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of DFARS 252.2277013, Rights in Technical Data and Computer Software (October 1988). Oracle Corporation, 500 Oracle Parkway, Redwood City, CA 94065. If this software/documentation is delivered to a U.S. Government Agency not within the Department of Defense, then it is delivered with Restricted Rights, as defined in FAR 52.22714, Rights in Data General, including Alternate III (June 1987). The information in this document is subject to change without notice. If you find any problems in the documentation, please report them to us in writing. Oracle Corporation does not warrant that this document is errorfree. ORACLE, SQL*Net, and SQL*Plus are registered trademarks of Oracle Corporation. Oracle Forms, Oracle Reports, Oracle Graphics, Oracle Book, Oracle*Terminal, PL/SQL, and ORACLE7 are trademarks of Oracle Corporation. Microsoft, MSDOS, MS, Excel, Word, Visual Basic, and Windows are trademarks of Microsoft Corporation. All other products or company names are used for identification purposes only, and may be trademarks of their respective owners.
Preface
Preface
he Forms Advanced Techniques Manual provides information necessary to help you use Forms 4.5. This preface includes the following topics:
Forms Documentation Set Audience Related Publications Your Comments Are Welcome
Preface
Audience
All the manuals in the Forms Version 4.5 documentation set are written for the application developer.
Related Publications
As an application designer using Version 4.5 of Forms, you should also be familiar with the following documents:
Document Procedure Builder Developers Guide Oracle Terminal Users Guide, Version 2.0 Oracle7 Server Messages and Codes Manual Oracle7 Server SQL Language Reference Manual, Version 7.0 PL/SQL Users Guide and Reference, Version 2.0 Forms documentation for your operating system Part Number A32485 A11700 A12379 778701292 800201292
ii
Preface
iii
iv
Contents
Chapter 1
Handling Runtime Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling Runtime Errors in Triggers . . . . . . . . . . . . . . . . . . . . . . . Using PL/SQL Exception Handling in Triggers . . . . . . . . . . . Results of Trigger Failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling Exceptions Raised in Triggers . . . . . . . . . . . . . . . . . Responding to Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Evaluating the Success or Failure of Builtins . . . . . . . . . . . . . . . . Handling Errors in Builtin Subprograms . . . . . . . . . . . . . . . Raising the FORM_TRIGGER_FAILURE Exception . . . . . . . Handling Errors in UserNamed Triggers . . . . . . . . . . . . . . . Error Handling for Stored Procedures . . . . . . . . . . . . . . . . . . . . . . Checking DBMS_ERROR_TEXT, DBMS_ERROR_CODE . . . UserDefined Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Trapping SQLCODE and SQLERRM . . . . . . . . . . . . . . . . . . . . Stored Procedures and Database Triggers . . . . . . . . . . . . . . . . . . About Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Restrictions When Using Stored Procedures . . . . . . . . . . . . . . Standard Packages with Oracle7 Server . . . . . . . . . . . . . . . . . Creating and Modifying Stored Procedures . . . . . . . . . . . . . . . . . . Stored Program Unit Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . Calling Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Database Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating and Editing Database Triggers . . . . . . . . . . . . . . . . . . . . . Database Trigger Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarative Database Constraints . . . . . . . . . . . . . . . . . . . . . . . . . .
11 12 12 13 14 15 15 16 16 17 18 18 18 1 10 21 22 23 23 25 26 29 2 14 2 17 2 18 2 20
Chapter 2
Contents
Entity Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Referential Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Strategies for Constraint Checking . . . . . . . . . . . . . . . . . . . . . . Master/Detail Blocks and Referential Integrity . . . . . . . . . . . Chapter 3 User Exit Interface to Foreign Functions . . . . . . . . . . . . . . . . . . . . About the User Exit Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Foreign Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Types of Foreign Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . Oracle Precompiler Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . EXEC SQL Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EXEC TOOLS GET Statement . . . . . . . . . . . . . . . . . . . . . . . . . . EXEC TOOLS SET Statement . . . . . . . . . . . . . . . . . . . . . . . . . . EXEC TOOLS MESSAGE Statement . . . . . . . . . . . . . . . . . . . . EXEC TOOLS GET CONTEXT Statement . . . . . . . . . . . . . . . . EXEC TOOLS SET CONTEXT Statement . . . . . . . . . . . . . . . . EXEC ORACLE Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a User Exit Interface to Foreign Functions . . . . . . . . . . . Creating an IAPXTB Control Structure . . . . . . . . . . . . . . . . . . Integrating a User Exit Interface with Oracle Forms . . . . . . . Invoking a Foreign Function from a User Exit Interface . . . . . . . Passing Parameter Values to a Foreign Function . . . . . . . . . . Returning a Value from a Foreign Function . . . . . . . . . . . . . . A User Exit Interface to Foreign Functions on MS Windows . . . Microsoft Windows User Exit Interface Files . . . . . . . . . . . . . Compiling Microsoft Windows Foreign Functions . . . . . . . . Creating the IAPXTB Control Structure for MS Windows . . Building a Microsoft Windows Dynamic Link Library . . . . . Defining Foreign Functions in Multiple DLLs . . . . . . . . . . . . An Example of a User Exit Interface in Microsoft Windows Accessing the MS Windows SDK From a User Exit Interface . . . Connecting to NonORACLE Data Sources . . . . . . . . . . . . . . . . About Connecting to NonORACLE Data Sources . . . . . . . . . . . Connecting with Open Gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . Key Mode Block Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Locking Mode Block Property . . . . . . . . . . . . . . . . . . . . . . . . . . Cursor Mode Form Property . . . . . . . . . . . . . . . . . . . . . . . . . . . Savepoint Mode Form Property . . . . . . . . . . . . . . . . . . . . . . . . Using Transactional Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Transactional Trigger Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 20 2 20 2 20 2 22 31 32 33 33 35 36 37 38 39 3 10 3 11 3 11 3 12 3 12 3 13 3 14 3 15 3 16 3 16 3 17 3 19 3 19 3 20 3 21 3 23 3 25 41 42 42 43 45 46 47 48 48
Chapter 4
vi
Replacing Default Processing . . . . . . . . . . . . . . . . . . . . . . . . . . Calling User Exits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Augmenting and Suppressing Default Processing . . . . . . . . Transactional Triggers Block Property . . . . . . . . . . . . . . . . . . . Which Transactional Triggers are Required . . . . . . . . . . . . . . About Transaction Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logon and Logout Processing . . . . . . . . . . . . . . . . . . . . . . . . . . Count Query Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Query and Fetch Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . Commit Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Savepoint and Rollback Processing . . . . . . . . . . . . . . . . . . . . . Check Column Security Processing . . . . . . . . . . . . . . . . . . . . . Generate Sequence Number Processing . . . . . . . . . . . . . . . . . Lock Record Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing System Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 5 MultipleForm Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About MultipleForm Applications . . . . . . . . . . . . . . . . . . . . . . . . Invoking Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MultipleForm Applications and the Root Window . . . . . . . Invoking Independent Forms with OPEN_FORM . . . . . . . . . . . . Navigation Between Independent Forms . . . . . . . . . . . . . . . . Opening Forms in Different Database Sessions . . . . . . . . . . . Opening Multiple Instances of the Same Form . . . . . . . . . . . Replacing the Current Form with NEW_FORM . . . . . . . . . . . . . . Calling Modal Forms with CALL_FORM . . . . . . . . . . . . . . . . . . . Exiting from a Called Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . Allowing Operators to Quit from a Called Form . . . . . . . . . . Calling a Form in QueryOnly Mode . . . . . . . . . . . . . . . . . . . Using CALL_FORM with OPEN_FORM . . . . . . . . . . . . . . . . Managing Commit Processing When Using CALL_FORM . . . . . Post vs. Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What is PostOnly Mode? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Savepoints and Rollbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rolling Back Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rollback Mode Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . Default Rollback Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modifying the CLEAR ALL and EXIT Commands . . . . . . . . Using Posting and Rollback Mode to Manage Transactions . Checking for Changed Records . . . . . . . . . . . . . . . . . . . . . . . . . Getting Information About the Call Form Stack . . . . . . . . . . Suppressing Post and Commit Transaction Messages . . . . . .
4 10 4 11 4 11 4 15 4 16 4 16 4 18 4 20 4 22 4 29 4 33 4 34 4 35 4 36 4 36 51 52 52 53 54 54 56 57 59 5 10 5 11 5 11 5 12 5 13 5 15 5 15 5 15 5 16 5 17 5 17 5 18 5 19 5 19 5 20 5 22 5 22
Contents
vii
Passing Parameters to Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passing a Parameter List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Default Parameter List . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initial Values of Parameters in a Called Form . . . . . . . . . . . . . Integrating Form and Menu Modules . . . . . . . . . . . . . . . . . . . . . . . OPEN_FORM Menu Functionality . . . . . . . . . . . . . . . . . . . . . . NEW_FORM Menu Functionality . . . . . . . . . . . . . . . . . . . . . . CALL_FORM Menu Functionality . . . . . . . . . . . . . . . . . . . . . . Creating a Master Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the REPLACE_MENU Builtin Procedure . . . . . . . . . .
5 23 5 24 5 24 5 25 5 26 5 26 5 26 5 27 5 27 5 27 5 28
Chapter 6
Responding to Mouse Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Mouse Events, Triggers, and System Variables . . . . . . . . . Mouse Event Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mouse Event System Variables . . . . . . . . . . . . . . . . . . . . . . . . . Performing Actions Based on the Mouse Button Pressed . . . . . . Performing Actions Based on Mouse Location . . . . . . . . . . . . . . .
61 62 62 63 64 65
Chapter 7
Using Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Timer Usage Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Responding to Multiple Timers . . . . . . . . . . . . . . . . . . . . . . . . Modifying Timers Programmatically . . . . . . . . . . . . . . . . . . . . . . . Deleting a Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71 72 73 74 75 76
Chapter 8
Integrating with Other Oracle Tools . . . . . . . . . . . . . . . . . . . . . . . About Integration with Other Oracle Tools . . . . . . . . . . . . . . . . . . Calling Other Products from Oracle Forms . . . . . . . . . . . . . . . . . . Suppressing the Logon in Oracle Graphics . . . . . . . . . . . . . . . Invoking Oracle Book from Oracle Forms . . . . . . . . . . . . . . . . Passing Parameters to Called Products . . . . . . . . . . . . . . . . . . . . . . Creating Parameter Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Chart Items to Embed Oracle Graphics Displays . . . . . . . . Creating a Chart Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passing Parameters and Data to Oracle Graphics . . . . . . . . . Creating a Chart Item that Responds to Mouse Events . . . . . The OG Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.CLOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.GETCHARPARAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81 82 83 84 85 85 86 88 89 8 10 8 13 8 15 8 15 8 15
viii
OG.GETNUMPARAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.INTERPRET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.MOUSEDOWN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.MOUSEUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.OPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OG.REFRESH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Calling Oracle Forms from 3GL Programs . . . . . . . . . . . . . . . . . . . Chapter 9 Designing for Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Porting Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Template Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Choosing a Form Coordinate System . . . . . . . . . . . . . . . . . . . . . . . Using Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Choosing Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Font Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Icons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting Window Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Form Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CharacterMode Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . Running in Character Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . Text Issues in Character Mode . . . . . . . . . . . . . . . . . . . . . . . . . Aligning Boilerplate Text in Character Mode . . . . . . . . . . . . . Properties Restricted to Character Mode Applications . . . . . Object Linking and Embedding (OLE) . . . . . . . . . . . . . . . . . . . . . About OLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About OLE Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Embedded Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linked Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About OLE Servers and OLE Containers . . . . . . . . . . . . . . . . . . . . About the Registration Database . . . . . . . . . . . . . . . . . . . . . . . . . . . About OLE Object Activation Styles . . . . . . . . . . . . . . . . . . . . . . . . Inplace Activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . External Activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About OLE Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . When to Embed or Link OLE Objects . . . . . . . . . . . . . . . . . . . . . . . OLE in Oracle Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 16 8 16 8 17 8 18 8 20 8 21 8 22 91 92 93 94 95 95 96 97 98 99 9 10 9 10 9 11 9 11 9 12 9 12 9 12 9 13 9 14 10 1 10 2 10 3 10 3 10 3 10 4 10 4 10 5 10 5 10 6 10 7 10 7 10 8
Chapter 10
Contents
ix
Using OLE in the Oracle Forms Designer . . . . . . . . . . . . . . . . . . . . Using OLE in Oracle Forms at Runtime . . . . . . . . . . . . . . . . . . . . . Creating an OLE Container in Oracle Forms . . . . . . . . . . . . . . . . . Linking and Embedding OLE Objects . . . . . . . . . . . . . . . . . . . . . . . Embedding Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linking Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying OLE Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Editing OLE Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Editing Embedded Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . Editing Linked Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Converting OLE Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Converting Embedded Objects . . . . . . . . . . . . . . . . . . . . . . . . . Converting Linked Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 11 VBX Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About VBX Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VBX Controls in Oracle Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VBX Control as an Oracle Forms Item . . . . . . . . . . . . . . . . . . . The Value of a VBX Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . VBX Controls in the Oracle Forms Designer . . . . . . . . . . . . . . . . . Oracle Forms VBX Control Properties . . . . . . . . . . . . . . . . . . . VBX Control Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VBX Controls in Oracle Forms at Runtime . . . . . . . . . . . . . . . . . . . Responding to VBX Control Events . . . . . . . . . . . . . . . . . . . . Firing VBX Control Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting VBX Control Properties . . . . . . . . . . . . . . . . . . . . . . . . Setting VBX Control Properties . . . . . . . . . . . . . . . . . . . . . . . . . Invoking VBX Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a VBX Control in Oracle Forms . . . . . . . . . . . . . . . . . . . . Dynamic Data Exchange (DDE) . . . . . . . . . . . . . . . . . . . . . . . . . . . About DDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Function Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Support Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connect/Disconnect Functions . . . . . . . . . . . . . . . . . . . . . . . . . Transaction Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Type Translation Functions . . . . . . . . . . . . . . . . . . . . . . . DDE.APP_BEGIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.APP_END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.APP_FOCUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10 9 10 11 10 12 10 13 10 13 10 14 10 15 10 17 10 17 10 17 10 20 10 20 10 21 11 1 11 2 11 3 11 3 11 4 11 5 11 5 11 5 11 6 11 7 11 8 11 9 11 10 11 11 11 12 12 1 12 2 12 2 12 3 12 3 12 3 12 3 12 4 12 4 12 6 12 7
Chapter 12
DDE.EXECUTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.GETFORMATNUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.GETFORMATSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.INITIATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.POKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.REQUEST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DDE.TERMINATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Microsoft Windows Predefined Data Formats . . . . . . . . . . . . . . . . Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 13 PL/SQL Interface to Foreign Functions . . . . . . . . . . . . . . . . . . . . . About the PL/SQL Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Foreign Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Types of Foreign Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . Precompiler Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a PL/SQL Interface to Foreign Functions . . . . . . . . . . . . Initializing a Foreign Function . . . . . . . . . . . . . . . . . . . . . . . . . Associating a PL/SQL Subprogram . . . . . . . . . . . . . . . . . . . . . Mimicking a Foreign Function Prototype with PL/SQL . . . . Invoking a Foreign Function from a PL/SQL Interface . . . . . . . . Passing Parameter Values to a Foreign Function . . . . . . . . . . Returning a Value from a Foreign Function . . . . . . . . . . . . . . Simplifying Complex Parameter Data Types . . . . . . . . . . . . . An Example of Creating a PL/SQL Interface . . . . . . . . . . . . . . . . . Accessing the MS Windows SDK from a PL/SQL Interface . . . . Oracle Open Client Adapter for ODBC . . . . . . . . . . . . . . . . . . . . About OCA and ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Oracle Open Client Adapter Architecture . . . . . . . . . . . . . . . . Oracle Open Client Adapter Communications . . . . . . . . . . . . Using Oracle Open Client Adapter with Oracle Forms . . . . . . . . Establishing an ODBC Connection . . . . . . . . . . . . . . . . . . . . . . Executing SQL Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Terminating Transactions and Connections . . . . . . . . . . . . . . Setting Up Applications to Run with OCA . . . . . . . . . . . . . . . . . . OCA Support by Datasource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Oracle Open Client Adapter Restrictions . . . . . . . . . . . . . . . . . . . . Generic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DriverSpecific Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQL Server Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Microsoft Access Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . .
12 8 12 9 12 10 12 11 12 12 12 13 12 14 12 15 12 16 13 1 13 2 13 3 13 3 13 5 13 6 13 6 13 7 13 8 13 9 13 10 13 10 13 11 13 11 13 16 14 1 14 2 14 3 14 4 14 5 14 5 14 6 14 7 14 8 14 10 14 12 14 12 14 15 14 15 14 18
Chapter 14
Contents
xi
Rdb Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using UBT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQL Command Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UBT Command Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UBT Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CONNECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @................................................... DISCONNECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . QUIT/EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SET AUTOCOMMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SPOOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Appendix A Using Oracle Terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Oracle Forms Resource Files . . . . . . . . . . . . . . . . . . . . . . . . . Using Oracle Terminal to Remap Oracle Forms Key Mappings . Using OT to Define Key Bindings for Key Triggers . . . . . . . . Oracle Forms Runtime Key Bindings . . . . . . . . . . . . . . . . . . . . . . . Using Oracle Terminal to Modify Logical Attributes . . . . . . . . . . About Attribute Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . Modifying Oracle Forms Logical Attributes . . . . . . . . . . . . . . . . . Edit Attribute Node Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Font Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Color and Fill Pattern Attributes . . . . . . . . . . . . . . . . . . . . . . . Logical Attribute Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cm_Logicals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Forms_Logicals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . National Language Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About National Language Support . . . . . . . . . . . . . . . . . . . . . . . . . NLS Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error Messages and Boilerplate Text . . . . . . . . . . . . . . . . . . . . Character Encoding Schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About the NLS Language Environment Variables . . . . . . . . . Additional NLS Environment Variables . . . . . . . . . . . . . . . . . Oracle Forms NLS Parameters . . . . . . . . . . . . . . . . . . . . . . . . . Character Set Design Considerations . . . . . . . . . . . . . . . . . . . . Language and Territory Default Format Masks . . . . . . . . . . . . . . . Format Mask Design Considerations . . . . . . . . . . . . . . . . . . . . Format Mask Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Screen Design Considerations . . . . . . . . . . . . . . . . . . . . . . . . . .
14 19 14 20 14 20 14 20 14 21 14 21 14 21 14 23 14 23 14 23 14 23 14 24 A1 A2 A2 A6 A8 A 13 A 13 A 16 A 18 A 18 A 18 A 20 A 20 A 21 B1 B2 B3 B3 B4 B5 B7 B8 B9 B 10 B 10 B 12 B 13
Appendix B
xii
Oracle Forms Interface Translation . . . . . . . . . . . . . . . . . . . . . . . . . Message Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Oracle Translation Manager Approach . . . . . . . . . . . . . Using the Runtime Language Switching Approach . . . . . . . . . . . Using PL/SQL Libraries for Strings in Code . . . . . . . . . . . . . . . . . Using Bidirectional Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B 14 B 14 B 15 B 16 B 17 B 18
Appendix C
PECS: Performance Event Collection Services . . . . . . . . . . . . . About PECS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The PECS System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS Measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Collecting Performance Data on Oracle Forms Events . . . . . . . . . Collecting Performance Data on ApplicationSpecific Events . . Group ApplicationSpecific Events . . . . . . . . . . . . . . . . . . . . . Define PECS Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Run Application with PECS . . . . . . . . . . . . . . . . . . . . . . . . . . . Load the Form and the PECS Data into the Database . . . . . . Analyze the Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Collecting Object Coverage Data . . . . . . . . . . . . . . . . . . . . . . . . . . . Collecting Line Coverage Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the PECS Assistant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About the PECS Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . Steps for Using the PECS Assistant . . . . . . . . . . . . . . . . . . . . . PECS Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS Maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using .DAT Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using PECSLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Location of the PECS Data File . . . . . . . . . . . . . . . . . . . . . . . . . PECS Database Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS Builtins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.ADD_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.ADD_EVENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.COLLECTOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.DISABLE_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.ENABLE_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.END_EVENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.POINT_EVENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PECS.START_EVENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C1 C2 C2 C3 C4 C5 C5 C6 C7 C7 C7 C8 C 10 C 10 C 11 C 11 C 12 C 13 C 13 C 14 C 14 C 15 C 15 C 16 C 17 C 18 C 19 C 20 C 21 C 22 C 23 C 24
Contents
xiii
xiv
CHAPTER
Handling Runtime Errors in Triggers 1 2 Evaluating the Success or Failure of Builtins 1 5 Error Handling for Stored Procedures 1 8
11
When one of these statements in a trigger or PL/SQL block raises an exception, normal processing stops and control transfers to the triggers exception handling section.
12
How Exceptions Propagate in Triggers PL/SQL blocks can be nested as inline blocks in Oracle Forms triggers. For example, a trigger might include a block that encloses another block.
...
When the inner block raises an exception for which there is no exception handler, that block terminates and the exception propagates, or falls out, to the enclosing block. If a handler is not found in the enclosing block, the exception propagates again, finally reaching the outermost block of the trigger. If the outer block does not handle the exception, the trigger fails, and Oracle Forms returns a runtime error. Exceptions Raised in UserNamed Subprograms For purposes of exception handling, calls to usernamed subprograms are treated as inline PL/SQL blocks within a trigger. That is, an unhandled exception raised in a usernamed subprogram propagates to the block in which the subprogram was called.
13
The following table shows the postfailure processing for three types of triggers:
Trigger Type Key * (any key trigger) PreItem OnInsert Result of Trigger Failure Trigger failure is ignored. Oracle Forms attempts to return input focus to the source item. Oracle Forms rolls back all database changes posted by the current commit process and attempts to navigate to the first item in the current record of the block in error. Item validation fails. Oracle Forms sets the error location. When possible, input focus is returned to the source item.
WhenValidateItem
When a trigger fails, Oracle Forms tries to undo any conditions that would cause a runtime error as a result of the triggers failure. For example, the PreItem trigger fires when Oracle Forms attempts to move the input focus from a source item to a target item. When a PreItem trigger fails, navigation cannot be completed successfully, so Oracle Forms returns the input focus to the source item. Similarly, when a commit processing trigger such as OnInsert fails, Oracle Forms performs the appropriate rollback to ensure data integrity. In the trigger descriptions in the online Help and in Chapter 2 of the Oracle Forms Reference Manual, each trigger has an On Failure: entry that describes its failure behavior.
Write exception handlers in the trigger to handle all raised exceptions. Take advantage of Oracle Forms default postfailure trigger processing by deliberately omitting exception handlers; when an exception is raised, the trigger fails, and the appropriate postfailure processing occurs. Write exception handlers for only the specific exceptions you want to handle in the trigger, and leave any other exceptions unhandled to deliberately cause the trigger to fail.
14
Responding to Errors
When an error occurs, you can use the following builtin subprograms to get information about the error, including the error number, type, and message:
ERROR_TYPE (returns CHAR) ERROR_CODE (returns NUMBER) ERROR_TEXT (returns CHAR) DBMS_ERROR_CODE (returns NUMBER) DBMS_ERROR_TEXT (returns CHAR)
These functions report on the outcome of the most recently executed builtin subprogram. In the following WhenButtonPressed trigger, the function FORM_SUCCESS is used to test the outcome of the GO_BLOCK builtin procedure:
Go_Block(xyz_block); IF NOT Form_Success THEN handle the error END IF;
15
This test detects both fatal and failuretype errors, and so is more encompassing than FORM_FAILURE or FORM_FATAL used alone.
END IF;
Because this trigger does not have an exception handling section, raising an exception causes the trigger to fail, and Oracle Forms performs the postfailure processing appropriate for the trigger. Although any valid exception can be raised to cause a trigger to fail, the example uses the builtin exception FORM_TRIGGER_FAILURE.
PROCEDURE Check_Builtin IS BEGIN IF NOT Form_Success THEN RAISE Form_Trigger_Failure; END IF; END;
16
You can define the procedure in a form or an attached library and then call it from any trigger in your form:
/* WhenButtonPressed Trigger: */
Go_Block(xyz_block); Check_Builtin;
Note: Do not use the internal error code associated with the FORM_TRIGGER_FAILURE exception, because the internal error code can change without notice.
When an unhandled exception is raised in a usernamed trigger, the usernamed trigger fails, but the exception does not propagate to the calling trigger. Rather, Oracle Forms treats the failure as an error in the builtin procedure EXECUTE_TRIGGER, and sets the return values of the builtin error functions accordingly. Thus, the outcome of a usernamed trigger can be trapped in the same way as a call to any other builtin subprogram; that is, by evaluating the builtin error functions:
/* Builtin Trigger: */
statement a; Execute_Trigger(my_usernamed_trigger); IF NOT Form_Success THEN RAISE Form_Trigger_Failure; END IF; statement b;
17
checking DBMS_ERROR_TEXT and DBMS_ERROR_CODE builtin subprograms within a formlevel ONERROR trigger creating appropriate userdefined exceptions evaluating the SQLCODE and SQLERRM functions in a WHEN OTHERS exception handler
Once you know that some database error has caused form processing to fail, you can interrogate the DBMS_ERROR_TEXT and DBMS_ERROR_CODE functions to determine exactly what server error has occurred. The full text of the error message is available in the return value for DBMS_ERROR_TEXT.
UserDefined Exceptions
Although PL/SQL includes many predefined exceptionssuch as NO_DATA_FOUND, DUP_VAL_ON_INDEX, and VALUE_ERROR they will never completely cover the range of ORACLE errors you may need to trap. So PL/SQL provides the facility to define your own exceptions and associate them with the occurrence of a particular Oracle error of your choice. The following code illustrates how to use EXCEPTION_INIT to tell PL/SQL to report an error of your choice. For
18
more information refer to the PL/SQL Users Guide and Reference, Version 2.0. Example:
/* ** Example of declaring your own errordriven exceptions */ DECLARE /* ** First declare the name of the exception */ cannot_del_parent EXCEPTION; /* ** Then associate it with the ORA2292 error ** which is violated integrity constraint XYZ ** child record found. Note error number is negative. */ PRAGMA Exception_Init (cannot_del_parent, 2292); BEGIN DELETE FROM PARENT_TABLE WHERE PRIMARY_KEY_FIELD = :BLOCK.PK; /* ** If we get here, then things went ok. */ EXCEPTION /* ** If our error arises, then this exception ** will be raised. We can deal with it elegantly. */ WHEN cannot_del_parent THEN Message(You cannot remove open || order number||:block.pk); RAISE Form_Trigger_Failure; END;
This method is best when the ORACLE error number itself is enough to allow your application to determine what happened. Userdefined error messages can be returned from database triggers, procedures, or functions, as shown earlier with RAISE_APPLICATION_ERROR. Creating corresponding userdefined exceptions is a natural counterpart to trapping the errors you raise. However, some errors returned by the kernel contain the name of the constraint (out of many possible ones) that has been violated, always returning a single ORACLE error number. An example of this would be:
ORA02290: violated check constraint (SCOTT.C_CK)
19
1 10
Example 2:
/* STRIP_CONSTRAINT_NAME: Returns constraint name from error ** Constraint name should appear enclosed by parentheses ** in the Oracle errors 0229002292 and 0229602299. ** Return the text between the parentheses when passed ** the error message text. */ FUNCTION strip_constraint_name( errmsg VARCHAR2 ) RETURN VARCHAR2 IS lv_pos1 NUMBER; lv_pos2 NUMBER; BEGIN lv_pos1 := INSTR(errmsg, (); lv_pos2 := INSTR(errmsg, )); IF (lv_pos1 = 0 OR lv_pos2 = 0 ) THEN RETURN(NULL); ELSE RETURN(UPPER(SUBSTR(errmsg, lv_pos1+1, lv_pos2lv_pos11))); END IF; END;
To trap ORACLE errors that are a result of database block INSERT, UPDATE, and DELETE operations, you must code the respective ONINSERT, ONUPDATE, and/or ONDELETE triggers to actually perform the DML operations so that you can trap the errors. Errors related to the features discussed above that could be trapped by the first example are:
1 11
Errors related to the features discussed above that could be trapped by the second example are:
After INSERT/UPDATE:
ORA02290: violated check constraint (OWNER.CONSTRAINT)
...
ORA20999:
1 12
CHAPTER
About Stored Procedures 2 2 Creating and Modifying Stored Procedures 2 5 Calling Stored Procedures 2 9 About Database Triggers 2 14 Creating and Editing Database Triggers 2 17 Declarative Database Constraints 2 20
21
The procedure provides standard functionality that other tools should sharesuch as validation and calculations. The procedure performs a significant number of DML operationsperhaps to have them performed in a bundle by the server. If new PL/SQL Version 2 features such as TABLES, RECORDS, or TYPES are requiredsince Oracle Forms Version 4.5 includes PL/SQL Version 1.1.
The executable form .FMX file can be significantly larger if references to stored procedures are in large packages.
22
Since Oracle Forms creates the access routine for each stored subprogram to which your trigger or usernamed routine refers, it is not possible to write a form containing calls to stored procedures or functions that will generate against both Oracle Version 6.0 and Version 7.0. Once a form includes a reference to at least one stored subprogram, then it must be generated against a Version 7.0 database, otherwise compilation errors result when the names of stored subprograms cannot be resolved by the PL/SQL compiler. Character (CHAR or VARCHAR2) values passed in to a stored procedure or function, passed out from a stored procedure, or returned from a stored function may not exceed 2000 characters. Actual character parameters exceeding 2000 characters will be truncated to 2000 before passing to the stored procedure or function. Any OUT character parameters or character return values exceeding 2000 characters will be truncated to a length of 2000. The truncation that may occur on IN, OUT or return character values from a procedure or function is performed without raising the PL/SQL VALUE_ERROR exception, and without raising an Oracle Forms truncation error. Calling stored procedures and functions is not supported from a menu PL/SQL context. Changes made to stored subprogram definitions may not be usable by the form developer until after reestablishing a connection to the server.
23
See the appendix of the Oracle7 Server Application Developers Guide that describes these packages, their contents and usage. Only the package dbms_standard is a standard extension. This means that its procedure names are inserted into the scope just outside a package or toplevel procedure, but before the kernels package STANDARD. Public synonyms for supplied packages are created during execution, and EXECUTE privilege is granted to public. You can invoke procedures included in any of these packages from Oracle Forms by using the syntax <package>.<procedure>; for example:
DBMS_SESSION.SET_ROLE(role);
For information on the procedures included in these packages refer to the Oracle7 Application Developers Guide.
24
To create a stored procedure: 1. In the Navigator, expand the Database Objects node, then select the Stored Procedures node and choose Navigator>Create. The New Program Unit dialog appears. 2. Specify name and type, either procedure, function, package spec or package body. The Stored Program Unit Editor appears. For information about using the Stored Program Unit Editor, see The Stored Program Unit Editor later in this chapter. 3. In the Stored Program Unit Editor, define and compile the desired program units. When you generate a form, menu, or library containing references to stored procedures, functions, or packages, Oracle Forms must perform the following:
Ensure that the stored subprogram to which you make reference exists on the server during compilation. Include an intermediate access routine for each stored subprogram you reference. There will be one access routine for each procedure, function or package that is called. If you call functions or procedures within a package, they will use the access routine associated with the entire package. The access routines handle the integration between PL/SQL Version 1 and Version 2, and are included in the .FRM file of your generated form. These access routines are not externalized.
25
To edit a stored procedure: 1. In the Navigator, expand the Database Objects and Stored Procedures nodes. Oracle Forms displays any stored procedures that you either own or have privileges to execute, compile, or drop. 2. Doubleclick on the desired stored procedure. The Stored Program Unit Editor is displayed. 3. Modify the stored procedure as desired and then save it.
New
Save
26
Revert
The Revert command discards any changes made in the source text pane and restores the stored program unit to its previous state. The restored state is the most recent of the following:
after the last navigation to this stored program unit or its creation with the New button after the last selection of the Compile button
The Revert button is only enabled when there have been changes to the source text pane since one of the above states. Drop The Drop command drops an existing stored program unit or aborts the creation of a new one (after seeking confirmation via an alert). After dropping the stored program unit, the editor displays the preceding stored program unit in the Name combo box if one exists; otherwise, it displays the next stored program unit. If there are no stored program units for the current owner, the editor is empty. The Drop button is enabled only if the stored program unit is new or the current user has drop privileges for the currently displayed stored program unit. Close The Close command closes the Stored Program Unit Editor window. If the source text of the currently displayed stored program unit has been modified, the editor presents an Unsaved Changes alert. The Owner combo box identifies the user who owns the stored program unit currently displayed in the editor. Selecting a new entry in the Owner combo box updates the Name combo box and displays the first stored program unit in the Name list (if one exists).
27
Name Combo Box The Name combo box displays the name of the currently selected stored program unit. The Name combo box contains the names of all accessible stored program units owned by the user currently selected in the Owner combo box. A program unit is accessible if the current user has execute privileges on it. Selecting a new entry in the Name combo box updates the editor to display the newly selected stored program unit. If the source text of the current stored program unit has been modified, the editor presents an Unsaved Changes alert. Source Text Pane The source text pane displays the source text of the current stored program unit. It is editable only if the current user has create privileges for the stored program unit; otherwise, it is readonly. The Compilation Message pane displays any compilation messages associated with the current stored program unit. Clicking on a compilation message moves the text cursor in the source pane to the line and column associated with the message. The Compilation Message pane is hidden when the current stored program unit has no associated error messages. Status Bar The Status Bar displays information about the state of the current stored program unit.
28
29
Supported Datatypes for Parameters/Return Values Stored procedures, functions, and packages are created using Version 2.0 of PL/SQL within the Oracle7 database. Although Oracle Forms Version 4.5 is built on PL/SQL Version 1.1, the following PL/SQL Version 2.0 datatypes are also supported for parameters and as function return values:
Recall that your stored procedures and functions can be written internally using all new PL/SQL Version 2.0 datatypes and functionality. The above restriction on datatypes applies only to the interface that your stored routines have with their Version 1.1 PL/SQL counterparts, namely parameters and function return values. However, if you reference a package, regardless of which procedures you may use in your Oracle Forms triggers or procedures, then all of the subprograms in the package must use only the supported datatypes above for parameters. A restriction has been made on referring to stored subprograms that contain parameters defined as:
TABLE%ROWTYPE
or
TABLE.COLUMN%TYPE
These are, therefore, unsupported datatype specifications even though their expansion may refer to a supported data type for a parameter of a stored procedure accessed from Oracle Forms. An attempt to reference a stored procedure or stored function that uses unsupported parameter or returnvalue datatypes will result in the failure to recognize the stored subprogram, and an error is reported when the form is generated:
PL/SQL error 313 at line xxx, column yyy PROCNAME not declared in this scope
or
PL/SQL error 201 at line xxx, column yyy identifier FUNCTNAME must be declared.
2 10
Default Values for Formal Parameters Default values for formal parameters are not supported. However, you can create a stored package that contains:
overloaded procedure specification in the package spec a private implementation using default parameters in the package body
Example:
A form could invoke the package procedure Test.Test with zero, one, or two VARCHAR2 arguments. After creating the package spec and body shown in the example below, the form could invoke:
test.test; test.test(Hi); test.test(Hi, There);
Available to Forms4.5 Client END Test; CREATE PACKAGE BODY Test IS PROCEDURE Private_Test( a in VARCHAR2 := Hello b in VARCHAR2 := There) IS BEGIN Dbms_Output.Put_Line(a); Dbms_Output.Put_Line(b); END; PROCEDURE Test IS BEGIN Private_Test; END; PROCEDURE Test(a VARCHAR2) IS BEGIN Private_Test (a); END; PROCEDURE Test(a VARCHAR2 , b VARCHAR2) IS BEGIN Private_Test (a, b); END; END Test;
2 11
Supported Constructs When invoking a stored procedure or function, only the following subset of possible usages is supported:
Accessing Subprograms in Another Users Schema To access a subprogram (i.e., procedure or function) in another users schema or one in a remote database, you must create a synonym to hide the username or Db_Link name from the PL/SQL compiler such that the result takes the form:
You can create synonyms to nickname remote stored programs, hiding the username or Db_Link:
Where subprogram is either a procedure or a function. Example: To call the package function LIBOWNER.LIB_HR.GET_SSN, you could create a synonym for the LIB_HR package that includes the schema name (the owner name) as follows:
CREATE SYNONYM lib_hr_syn FOR libowner.lib_hr;
2 12
If the package function is at a remote site accessible through a database link named basel, for example, then you could create a synonym for the package, including the database link name:
CREATE SYNONYM basel_lib_hr_syn FOR libowner.lib_hr@basel;
Alternately, you could create a synonym for the function itself, hiding both the schema and Db_Link information:
CREATE SYNONYM basel_lib_hr_get_ssn_syn FOR libowner.lib_hr.get_ssn@basel;
Of course, any of the synonyms above could have been created as PUBLIC SYNONYMS if appropriate. Name Resolution When a form is generated, the PL/SQL compiler may encounter the name of an identifier that could be a procedure or function. The PL/SQL compiler uses a precedence mechanism to resolve ambiguities. If an identifier such as PROCNAME is encountered that has the structure of a procedure or function, the compiler will use the first match found in the following search order: 1. 2. 3. 4. 5. 6. Is it defined within the current PL/SQL block? Is it a standard PL/SQL command? Is it an Oracle Forms builtin subprogram procedure or function? Is it a usernamed procedure or function? Is it defined in package DBMS_STANDARD on the serverside? Does the current user have access to any such procedure or function on the server side?
If the answer is no to all of the above, then the compiler signals an error:
PL/SQL error 313 at line xxx, column yyy PROCNAME not declared in this scope or PL/SQL error 201 at line xxx, column yyy identifier FUNCTNAME must be declared.
2 13
2 14
Besides providing arbitrarily complex data validation, database triggers can also be used to perform any causeandeffect sequence. This makes database triggers particularly well suited for data auditing operations, data replication, and distributed data integrity checking (since constraints cannot reference remote databases). If database triggers are written to supplant Oracle Formsside triggers (e.g. for table auditing) then the formsside functionality will have to be disabled to avoid duplicating table operations. One alternative is to use a package variable as a flag to communicate between the form and the databaseside triggers (or procedures). In that manner, a decision can be made within the trigger or procedure on whether a particular operation might have already been performed by the Oracle Forms code. Triggers (as well as stored procedures and functions) raise errors with the RAISE_APPLICATION_ERROR procedure. The RAISE_APPLICATION_ERROR procedure assigns an error number within the special range 2000020999 and provides an error message. Since it is your PL/SQL database trigger that prepares the error message, the message can vary. Within the Oracle Forms application, these errors can be trapped with the methods mentioned in the next section. Recall that database triggers fire in response to a DML statement such as INSERT, UPDATE, or DELETE. So during normal Oracle Forms committime processing, as Oracle Forms issues INSERT statements to add newly entered records to the database, UPDATE statements to effect changes by the operator to existing records, and DELETE statements to remove records deleted by the operator from the database; database triggers will fire if enabled. For example, consider the scenario where the following database triggers have been defined and enabled on the EMP table:
BEFORE DELETE BEFORE DELETE FOR EACH ROW AFTER DELETE AFTER DELETE FOR EACH ROW
2 15
When the Oracle Forms operator deletes a record that has been queried, the following sequence of events occurs: 1. 2. 3. 4. 5. 6. 7. 8. 9. Oracle Forms locks the record to be deleted. Operator presses [Commit]. Oracle Forms fires the PRECOMMIT trigger. Oracle Forms fires the PREDELETE trigger. Oracle Forms issues a DELETE statement to delete the row. The database fires the BEFORE DELETE trigger. The database fires the BEFORE DELETE FOR EACH ROW trigger. The database deletes the record. The database fires the AFTER DELETE FOR EACH ROW trigger.
10. The Database AFTER DELETE trigger fires. 11. Oracle Forms fires the POSTDELETE trigger. 12. Oracle Forms fires the POSTCOMMIT trigger. Recall that any error raised during Commit processing causes Oracle Forms to roll back the currently committing transaction to the savepoint that was issued when the Commit sequence began. If any Database trigger fails (by raising an unhandled error or calling a RAISE_APPLICATION_ERROR) as a result of a DML statement that Oracle Forms has issued automatically, then an Oracle Error Occurred ... message will appear. An error raised as a result of a DML statement in your PL/SQL trigger, on the other hand, can be handled gracefully, as discussed below. If not handled, the error will produce the message: XXXYYYYYY trigger raised unhandled exception.
2 16
To create a database trigger: 1. In the Navigator, expand the Database Objects and Tables nodes, then select and expand the desired table. Select the Triggers node and then choose Navigator>Create. The Database Trigger Editor appears. For information about using the Database Trigger Editor, see The Database Trigger Editor later in this chapter. 2. In the Database Trigger Editor, define and compile the desired program units.
To edit a database trigger: 1. In the Navigator, expand the Database Objects and Tables nodes, then select and expand the desired table. Oracle Forms displays any database triggers associated with the current module. 2. Doubleclick on the desired database trigger. The Database Trigger Editor appears. 3. In the Database Trigger Editor, modify the database trigger as desired and then compile it.
2 17
Name Combo Box The Name combo box displays the name of the currently selected database trigger. The Name combo box contains the names of all accessible database triggers owned by the user currently selected in the Owner combo box. A database trigger is accessible if the current user has execute privileges on it. Selecting a new entry in the Name combo box updates the editor to display the newly selected database trigger. If the source text of the current database trigger has been modified, the editor presents an Unsaved Changes alert. Triggering When defining a database trigger, you can specify the trigger timing, that is, you can specify when the trigger action is to be executed in relation to the triggering statement: before or after the triggering statement. A triggering event or statement is the SQL statement that causes a trigger to be fired. A triggering event can be an INSERT, UPDATE, or DELETE statement for a specific table. When you create a database trigger, you can specify a trigger restriction. A trigger restriction is an option available for triggers that are fired for each row. Its function is to conditionally control the execution of a trigger. A trigger restriction is specified using a WHEN clause. Allows you to specify the PL/SQL code to be used as the body of the database trigger.
Statement
Trigger Bocy
2 18
New
Creates a new code object of the same type and scope as the current code object. For example, when the current object is a trigger attached to an item, choosing New displays the Triggers LOV that allows you to create a new trigger attached to the same item. When the current object is a program unit, choosing New invokes the New Program Unit dialog. Compiles and saves the code in the Source Code field. The compiler detects syntax errors, semantic errors, and references to nonexistent objects, procedures, and functions. When you compile successfully, the status line displays the message <Successfully Compiled>. Undoes any changes that were made to the source code since the editor was invoked or since the last Apply or Revert command. Revert is disabled when there are no unapplied changes. The Drop command drops an existing database trigger or aborts the creation of a new one (after seeking confirmation via an alert). After dropping the database trigger, the editor displays the preceding database trigger in the Name combo box if one exists; otherwise, it displays the next database trigger. If there are no database triggers for the current owner, the editor is empty. The Drop button is enabled only if the database trigger is new or the current user has drop privileges for the currently displayed database trigger.
Save
Revert
Drop
Closes the Database Trigger Editor. Moves the insertion point to the line at which an error was detected in the Source Code field.
2 19
Entity Constraints
Entity constraints can declaratively enforce a column (or ordered group of columns) to be NOT NULL, UNIQUE within the table, have a DEFAULT value if none is specified on INSERT, and/or satisfy a more complex logical condition given in a CHECK clause. These constraints provide intratable integrity.
Referential Constraints
Referential constraints provide the logical link between a master and a detail table by establishing primary and foreign key relationships. Database constraints protect your data by automatically enforcing at the database level the rules you have declared. If you create a record in a master table and one detail record, for example, the default operation of database constraints restricts updating of the primary key of the master record. Default database constraints also prevent deleting of the master record (unless the ON DELETE CASCADE option is used when declaring all of the foreign key references).
2 20
Database constraints provide the ability to centrally protect the integrity of the data without necessarily coding the logic into each one of the tools. However, the reason that logic was coded into the application in the first place was to give the user immediate feedback on errors, facilitating their rapid correction with online help and appropriate error messages. No user would appreciate entering a batch of fifty new orders, only to press the [Commit] key and learn from ORACLE that the fourth order violated an integrity constraint. You will most likely prefer to check the data both at data entry time and at commit time, recognizing that the small overhead of checking is well worth the additional security it provides. Database Constraints checking is more efficient than its applicationbased counterpart since constraints are processed intelligently by the kernel, completely within the realm (and RAM) of the kernel, and without additional network trips back to the client. When you upgrade from Version 6 to Oracle7 Server, all constraints that may have been declared in Version 6 are initially disabled by default. If you want to take advantage of database constraints, be aware that all of the enabled constraints will be checked for each record that is INSERTED, UPDATED, and DELETED (as appropriate). In particular, newly enabled constraints can suddenly return new errors to your application as they reject invalid data. The developer may wish to add extra error handling into the current application to handle the CONSTRAINT violations that may arise. Note that if a column has been declared to have a DEFAULT value, the kernel will assign the DEFAULT value only when the record is INSERTed, provided that the given column is not listed among the columns in the INSERT clause. Because Oracle Forms 4.5 always lists ALL of the columns (i.e., database fields) in a block for INSERTS and UPDATES, the DEFAULT will never automatically be assigned unless the user either removes the field in question from the block (or marks it as nondatabase), or else codes an ONINSERT trigger to override the normal Oracle Forms insert processing. Also, be aware that some formsbased operations may become unnecessary when constraints are enabled. For example, deleting detail records when a corresponding master is removed, is internally handled by the kernel if the ON DELETE CASCADE option is specified for the parentchild foreign key relationship. The Integrity Constraints option in the Oracle Forms New Block window continues to function under Oracle7 as it did in V6.
2 21
However, if the foreign key relationship is specified with the ON DELETE CASCADE option, then no problem will arise, and the Oracle Forms POSTDELETE trigger will be needlessly performing an extra DELETE statement to remove the detail records that the Cascade Delete of the master already deleted. So potentially any INSERT, UPDATE, or DELETE in your applications could generate an error caused by violating an enabled constraint. To add more sophisticated error handling to your existing forms (in the wake of having enabled many new serverside constraints) see the Error Handling Chapter.
2 22
CHAPTER
About the User Exit Interface 3 2 About Foreign Functions 3 3 Oracle Precompiler Statements 3 5 Creating a User Exit Interface to Foreign Functions 3 12 Invoking a Foreign Function from a User Exit Interface 3 14 A User Exit Interface on Microsoft Windows 13 16 Accessing the Microsoft Windows SDK 3 25
31
32
Replace default Oracle Forms processing when running against a nonOracle data source using transactional triggers. Perform complex data manipulation. Pass data to Oracle Forms from operating system text files. Manipulate LONG RAW data. Pass entire PL/SQL blocks for processing by the server. Control real time devices, such as a printer or a robot. Note: You should not perform host language screen I/O from a foreign function. This restriction exists because the runtime routines that a host language uses to perform screen I/O conflict with the routines that Oracle Forms uses to perform screen I/O. However, you can perform host language file I/O from a foreign function.
Oracle Precompiler foreign functions OCI (ORACLE Call Interface) foreign functions nonORACLE foreign functions
You can also develop foreign functions that combine both the ORACLE Precompiler interface and the OCI.
33
Oracle Precompiler Foreign Functions An Oracle Precompiler foreign function incorporates the Oracle Precompiler interface. This interface allows you to write a subprogram in one of the following supported host languages with embedded SQL commands:
Note: Not all operating systems support all of the listed languages. For more information on supported languages, refer to the Oracle Forms documentation for your operating system. With embedded SQL commands, an Oracle Precompiler foreign function can access Oracle databases as well as Oracle Forms variables and items. You can access Oracle Forms variables and items by using a set of Oracle Precompiler statements that provide this capability. Because of the capability to access both Oracle databases and Oracle Forms variables and items, most of your foreign functions will be Oracle Precompiler foreign functions. For more information on the Oracle Precompiler interface, refer to the Programmers Guide to the Oracle Precompilers. Oracle Call Interface (OCI) Foreign Functions An OCI foreign function incorporates the Oracle Call Interface. This interface allows you to write a subprogram that contains calls to Oracle databases. A foreign function that incorporates only the OCI (and not the Oracle Precompiler interface) cannot access Oracle Forms variables and items. For more information on the OCI, refer to the Programmers Guide to the Oracle Call Interface. NonOracle Foreign Functions A nonOracle foreign function does not incorporate either the Oracle Precompiler interface or the OCI. For example, a nonOracle foreign function might be written entirely in the C language. A nonOracle foreign function cannot access Oracle databases, or Oracle Forms variables and items.
34
EXEC ORACLE
An Oracle Precompiler foreign function source file includes host programming language statements and Oracle Precompiler statements with embedded SQL statements. Precompiling an Oracle Precompiler foreign function replaces the embedded SQL statements with equivalent host programming language statements. After precompiling, you have a source file that you can compile with a host language compiler. For more information on a specific precompiler, refer to the appropriate precompiler documentation for your environment.
35
where sql_statement is any valid Oracle SQL statement, except for the restricted commands noted in this section. You do not need to perform an explicit CONNECT in an Oracle Precompiler foreign function because Oracle Forms establishes the connection automatically. However, Oracle Server does support concurrent connects. For more information, refer to the Programmers Guide to the Oracle Precompilers. Restrictions: You adhere to the following restrictions when you use SQL commands in an Oracle Precompiler foreign function:
Do not issue a SQL COMMIT or ROLLBACK statement from within a foreign function if there are changes in a form that have not been posted to the database when the foreign function is called. Do not issue any command that would implicitly cause a database commit, such as a DDL command within a foreign function, if there are changes in a form that have not been posted to the database when the foreign function is called.
36
where:
form_variable_n Specifies the name of the Oracle Forms item or
into which you are reading a value. Notes: The form_variable can be a reference to any of the following items:
a fullyqualified item (block.item) a form parameter an Oracle Forms system variable an Oracle Forms global variable a host language variable (prefixed with a colon) whose value is any of the above choices
Refer to the Programmers Guide to the Oracle Precompilers for any restrictions on host language variables. Restrictions: Example: It is not possible to get or set values directly into a record group from a foreign function.
/* ** Example: Read an item name from a block (empblock.empname) */ EXEC SQL BEGIN DECLARE SECTION; char itm_buff[255]; /* buffer for item value */ VARCHAR itm_name[255]; /* Forms item name */ EXEC SQL END DECLARE SECTION; strcpy(itm_name.arr,EMBLOCK.EMPNAME); itm_name.len=strlen(EMBLOCK.EMPNAME); EXEC TOOLS GET :itm_name INTO :itm_buff;
37
where:
form_variable host_variable constant
Specifies the name of the Oracle Forms item or variable into which you are reading a value. Specifies the name of the host language variable from which you are reading a value. Specifies the constant that you are reading. Do not precede a constant with a colon.
Notes:
a fullyqualified item (block.item) a form parameter an Oracle Forms system variable an Oracle Forms global variable a host language variable (prefixed with a colon) whose value is any of the above choices
Refer to the Programmers Guide to the Oracle Precompilers for any restrictions on host language variables. Represent host variables and constants in standard SQL format:
Value :holder1 Summit Sporting Goods 413 Result Inserts the value of the host variable, holder1 (preceded by a semicolon). Inserts the constant string value, Summit Sporting Goods (enclosed in single quotes). Inserts the constant numeric value, 413 (no quotes for numeric values).
38
Example:
/* ** Example: Write SMITH into emp.ename */ EXEC SQL BEGIN DECLARE SECTION; char itm_buff[255]; /*buffer for item value */ VARCHAR itm_name[255]; /* Forms item name */ EXEC SQL END DECLARE SECTION; strcpy(itm_name.arr,EMP.ENAME); itm_name.len = strlen(EMP.ENAME); strcpy(itm_buff,SMITH); EXEC TOOLS SET :itm_name VALUES (:itm_buff);
where:
message
Specifies the message you are passing to Oracle Forms. The message can be a quoted string or a host language variable. Specifies the severity level of the message you are passing to Oracle Forms.
severity
Example:
/* ** Example: Error message for text item */ EXEC TOOLS MESSAGE Incorrect argument: Expecting item name. Please reenter.;
39
where:
context_name
Specifies the name of the context you are saving. into which you are reading the context value.
Notes:
Example:
/* ** Example: Get previously saved context information */ EXEC SQL BEGIN DECLARE SECTION; char *pctx; EXEC SQL END DECLARE SECTION; EXEC TOOLS GET CONTEXT appl_1 INTO :pctx;
3 10
where:
host_name context_name
Specifies the host language variable containing the information to be saved. Specifies the name of the saved context.
Notes:
Example:
/* ** Example: Save context information for later use */ EXEC SQL BEGIN DECLARE SECTION; char my_context[20]; EXEC SQL END DECLARE SECTION; strcpy(my_context, context_1); EXEC TOOLS SET CONTEXT :my_context BY appl_1;
3 11
Creating an IAPXTB control structure that registers each user exit interface Integrating a user exit interface with Oracle Forms
FUNCTION TYPE
You must enter one entry in the IAPXTB control structure for every foreign function that can be invoked from a user exit interface. This is true for all foreign functions that can be invoked from a user exit interface, whether a foreign function is in a file that is precompiled and compiled by itself, or precompiled and compiled with several other foreign functions. You should maintain all foreign functions that can be invoked from a user exit interface for a production system in one IAPXTB control structure. You should keep test versions of your foreign functions in a separate IAPXTB control structure.
3 12
To create the IAPXTB control structure: 1. Define the IAPXTB data structure. Make sure you define the data structure with three fields representing the name of the user exit interface, the name of the foreign function, and the language used to develop the foreign function. 2. 3. Enter the data for each foreign function. Compile the IAPXTB source file to generate an object code file. Retain the IAPXTB object code file for integrating the user exit interface with Oracle Forms.
Specific information about creating the IAPXTB control structure in Microsoft Windows is available in the section A User Exit Interface to Foreign Functions on Microsoft Windows. For information about creating the IAPXTB control structure in other environments, refer to the Oracle Forms documentation for your operating system.
3 13
To integrate a user exit interface with Oracle Forms: 1. 2. 3. Identify the foreign function object code file. Identify the IAPXTB control structure object code file. Link the foreign function object code file and the IAPXTB control structure object code file with either a dynamic link library or Oracle Forms Runform.
The USER_EXIT builtin calls the foreign function named in the user_exit_string. Parameters:
user_exit_string
Specifies a user exit name for a foreign function that you want to call from a user exit interface, including any parameters. Maximum length of the user_exit_string is 255 characters. Specifies a userdefined error message that Oracle Forms displays if the call to the foreign function fails. Maximum length of the error_string is 255 characters.
error_string
Restrictions:
When you specify the user exit name that represents a foreign function (in the user_exit_string of the USER_EXIT builtin subprogram) that name must follow the rules of your operating system and host language. Be aware that these rules might include case sensitivity. You should also note that only one foreign function can be invoked per USER_EXIT builtin call.
3 14
Although Oracle Forms automatically invokes the foreign function from the user_exit_string, Oracle Forms does not automatically parse the user_exit_string. It is the responsibility of the foreign function to parse the user_exit_string. You can pass any number of parameters to a foreign function from the user_exit_string of the USER_EXIT builtin. Use this feature to pass information such as item names. For example, to pass two parameters, PARAM1 and PARAM2, to the CALCULATE_VALUES foreign function, you specify the following statement:
User_Exit(CALCULATE_VALUES PARAM1 PARAM2);
3 15
3 16
To create an Oracle Precompiler foreign function that can be invoked from a user exit interface on Microsoft Windows: 1. Write an Oracle Precompiler foreign function using the Oracle precompiler statements to embed SQL commands in your source code. Precompile the foreign function source code with an Oracle precompiler. Compile the output from the Oracle precompiler to generate a foreign function object code file. Be sure to specify the large memory model on your compiler. Create an IAPXTB control structure and compile the source code to generate an IAPXTB object code file. Build a DLL with the foreign function and IAPXTB control structure object code files. Make sure you include the name of the DLL in the FORMS45_USEREXITS variable of the ORACLE.INI file, or rename the DLL to F45XTB.DLL. If you rename the DLL to F45XTB.DLL, replace the existing F45XTB.DLL in the \ORAWIN\BIN directory with the new F45XTB.DLL. Invoke the foreign function from a user exit interface in Oracle Forms.
2. 3.
4. 5. 6.
7.
To assist you in creating the IAPXTB control structure, Oracle Forms provides you with two IAPXTB control structure source files,
3 17
UE_XTB.C and UE_XTBN.C. Each file serves as a template for creating an IAPXTB control structure. Modify a IAPXTB control structure source file to include the foreign functions you define. Include the appropriate file in your project. You only need one of the two source files to create the IAPXTB control structure. UE_XTB.C is a file that contains an example of an entry for the IAPXTB control structure. Modify this file and add your foreign function entries. This is the file that is in the UE_SAMP.MAK project file. is a file that contains an empty IAPXTB control structure. Add your foreign function entries to create an IAPXTB control structure. This is the file that is in the UE_XTBN.MAK project file.
UE_XTBN.C
The following files are project files that contain all the required files to create a DLL containing foreign functions that you can invoke from a user exit interface in Oracle Forms. UE_SAMP.MAK is a project file that includes the IAPXTB control structure from the UE_XTB.C file. Building this project generates UE_SAMP.DLL. You can rename the DLL from UE_SAMP.DLL to F45XTB.DLL and replace the existing F45XTB.DLL in the \ORAWIN\BIN directory, or you can add UE_SAMP.DLL to the list of DLLs defined by the FORMS45_USEREXITS parameter in the ORACLE.INI file. is a project file that includes the IAPXTB control structure from the UE_XTBN.C file. Building this project generates UE_XTBN.DLL. This is the project file that is used to generate the initial F45XTB.DLL that resides in the \ORAWIN\BIN directory. You can rename the DLL from UE_XTBN.DLL to F45XTB.DLL and replace the existing F45XTB.DLL in the \ORAWIN\BIN directory, or you can add UE_XTBN.DLL to the list of DLLs defined by the FORMS45_USEREXITS parameter in the ORACLE.INI file.
UE_XTBN.MAK
3 18
In addition to your foreign function object code files and an IAPXTB control structure object code file, you need the following files in your project file to generate a user exit interface DLL (These files are included in UE_SAMP.MAK and UE_XTBN.MAK): F45XTB.DEF OSSWEP.OBJ contains definitions you need to build your own DLL. is the Dynamic Link Library Windows Entry Point .OBJ file you need to build your own DLL. (You may replace OSSWEP.OBJ with an .OBJ file of your own.) is an .OBJ file that you link to your own .OBJ files.
UEZ.OBJ
3 19
The file includes the user exit name UE_Name. In this example, the following line was added to the original UE_XTB.C file:
UE_Name, UE_Funct, XITCC,
UE_Name
is the user exit name for use by the USER_EXIT builtin subprogram to invoke the foreign function from Oracle Forms. is the name of the foreign function that temporarily takes over processing control from Oracle Forms. specifies the C programming language that is used to develop the foreign function.
UE_Funct XITCC
3 20
If you are creating an Oracle Precompiler foreign function, you must link the following libraries: \orawin\pro20\userexit\sql16win.lib \orawin\pro20\userexit\sqx16win.lib You create UE_SAMP.DLL after building the UE_SAMP.MAK project file. You can rename UE_SAMP.DLL to F45XTB.DLL, make a backup copy of F45XTB.DLL located in \ORAWIN\BIN, and replace the existing F45XTB.DLL with the new F45XTB.DLL. Alternatively, you can add UE_SAMP.DLL to the list of DLLs defined by the FORMS45_USEREXITS parameter in the ORACLE.INI file.
A DLL loads into memory when any one of the foreign functions it contains is invoked from the user exit interface. Although the FORMS45_USEREXITS parameter can list many DLLs that each contain multiple user exit interface foreign functions, only one such DLL is in memory at any time. Oracle Forms determines the foreign function to invoke from a user exit interface using the following criteria:
If the FORMS45_USEREXITS parameter does not exist in the ORACLE.INI file, foreign functions must be contained in a single
3 21
user exit DLL named F45XTB.DLL and located in the \ORAWIN\BIN directory.
If the FORMS45_USEREXITS parameter exists in the ORACLE.INI file and there are multiple user exit interface DLLs define, the first occurrence of the foreign function in the list of DLLs is invoked. If there are multiple user exit interface DLLs that contain nonunique foreign function names, the nonunique function name that is invoked is the first occurrence of function that follows the content in the user exit interface cache memory.
NOTE: To avoid calling an unexpected foreign function, you should not use the same foreign function name more than once in any of your user exit interface DLLs. An example of a nonunique function name is when two different functions have the same name, but are contained in different user exit interface DLLs. User Exit Interface Cache Memory Oracle Forms deals with nonunique function names by maintaining a user exit interface cache memory. Exiting a form clears the user exit interface cache memory, otherwise the user exit interface cache memory retains the last called foreign function in memory until you call another foreign function. Invoking a foreign function that has a nonunique function name depends on what is in the user exit interface cache memory. The first occurrence of a foreign function with a nonunique function name that follows the foreign function in the user exit interface cache memory is invoked. If the user exit interface cache memory is empty, the first occurrence of a function with the nonunique function name in the list of DLLs is invoked. Because the cache memory is not cleared until a you exit a form, subsequent calls to a nonunique function name may result in an unexpected foreign function call. For instance, you may accidentally call a function that follows a function with a unique name as opposed to calling a function that appears earlier in the sequence of user exit interface DLLs. Although in many cases, the user exit interface cache memory correctly identifies foreign functions with nonunique names, you should use unique foreign function names in the list of DLLs that are members of the FORMS45_USEREXITS variable whenever possible.
3 22
EXEC SQL INCLUDE sqlca.h void AddColumn() { EXEC SQL alter table EMP add ID varchar(9); }
2.
Precompile the foreign function with the Pro*C precompiler. The input to the Pro*C precompiler is the file UEXIT.PC. The output from the Pro*C precompiler is the file UEXIT.C. You should also create a header file to prototype your foreign functions. In this example, a UEXIT.H file is created to declare the AddColumn function.
3.
Create the IAPXTB control structure. Modify the file UE_XTB.C file by including the UEXIT.H file and adding the user exit name, foreign function name, and language type. Follow the example in the UE_XTB.C file. In this case, the following entry is added to the file:
Add_ID_Column, AddColumn, XITCC
4.
Modify any required foreign function integration files. Modify the F45XTB.DEF file by adding export statements to include the AddColumn foreign function. Follow the examples in the F45XTB.DEF file.
3 23
5.
Build a DLL for use with Oracle Forms Runform. With the exception of UEXIT.C, the following files should already be included in the UE_SAMP.MAK project file:
c:\orawin\forms\userexit\uez.obj c:\orawin\forms\userexit\osswep.obj c:\orawin\forms\userexit\f45xtb.def c:\orawin\forms\userexit\ue_xtb.c c:\orawin\forms\userexit\uexit.c
After building the UE_SAMP.MAK project, the result is a DLL named UE_SAMP.DLL. Add the UE_SAMP.DLL entry to the list of DLLs defined by the FORMS45_USEREXITS parameter in the ORACLE.INI file. Alternatively, you can rename UE_SAMP.DLL to F45XTB.DLL, backup the F45XTB.DLL in the c:\orawin\bin directory, and copy the new F45XTB.DLL to the c:\orawin\bin directory. 6. Invoke the foreign function from a user exit interface in Oracle Forms. In this case, a WhenButtonPressed Trigger calls the foreign function from a user exit interface. The following statement demonstrates how to invoke the AddColumn foreign function by specifying the user exit name Add_ID_Column in the USER_EXIT builtin subprogram:
/* Trigger: WhenButtonPressed */ USER_EXIT(Add_ID_Column);
3 24
3 25
3 26
CHAPTER
About Connecting to NonORACLE Data Sources 4 2 Connecting with Open Gateway 4 2 Using Transactional Triggers 4 8 About Transaction Processing 4 16
41
run against a nonORACLE data source run against ORACLE or a nonORACLE data source include some blocks that are based on ORACLE tables and other blocks that access a nonORACLE data source use Open Gateway to connect to one nonORACLE data source and use transactional triggers to connect to another
Key Mode block property Locking Mode block property Cursor Mode form module property Savepoint Mode form module property
42
You can set these properties to specify how Oracle Forms should interact with your nonORACLE data source. The specific settings you will use for these properties will depend on the capabilities and limitations of the data source to which you are connecting.
Description
The default setting. Instructs Oracle Forms to use ROWID constructs to identify unique rows in an ORACLE database. Specifies that Oracle Forms should issue UPDATE statements that include primary key values. Use this setting if your database allows primary key columns to be updated and you intend for the application to update primary key values. Specifies that Oracle Forms should not include primary key columns in any UPDATE statements. Use this setting if your database does not allow primary key values to be updated.
Updateable
NonUpdateable
Note: Some Open Gateway products use pseudo ROWIDs that allow you to run your form in the default Unique_Key mode against that particular data source. Note: When the Key Mode property is set to one of the primary key modes, you must identify the primary key items in your form by setting the Primary Key item property True for at least one item in the block. Examples: The following examples illustrate how the Key Mode property affects transaction processing. Consider a DEPT table with columns named DEPTNO, DNAME, and LOC. The DEPTNO column is the primary key.
43
The following figure shows how a row in the DEPT table would be stored in an ORACLE database. Note the ROWID pseudocolumn that ORACLE uses to identify unique rows.
ROWID 000012C1.0001.0001 DEPTNO 30 DNAME SALES LOC CHICAGO
The statement issued for an unqualified query on the preceding table from within Oracle Forms appears as follows:
SELECT rowid, deptno, dname, loc FROM dept;
Now assume that the operator fetches the example row into the DEPT block in the form, changes the DNAME value from SALES to CONSULTING, and then commits the transaction. The following sections show how Oracle Forms manages the update differently, depending on the setting of the Key Mode property. Example 1: Unique Key When the Key Mode property is set to Unique (the default setting) Oracle Forms issues the following SQL statements to reserve the record for update, and then update the record:
SELECT rowid, deptno, dname, loc FROM dept WHERE rowid = 000012C1.0001.0001 AND deptno = 30 AND dname = Sales AND loc = Chicago FOR UPDATE OF deptno, dname, loc NOWAIT; UPDATE dept SET deptno = 30, dname = Consulting, loc = Chicago WHERE rowid = 000012C1.0001.0001;
When the Key Mode property is set to Updateable, Oracle Forms issues the following statements to reserve the record for update, and then update the record:
SELECT deptno, dname, loc FROM dept; SELECT deptno, dname, loc FROM dept WHERE deptno = 30 FOR UPDATE OF deptno, dname, loc; UPDATE dept SET deptno = 30, dname = Consulting, loc = Chicago WHERE deptno = 30;
44
When the Key Mode property is set to NonUpdateable, Oracle Forms issues the following statements to reserve the record for update, and then update the record:
SELECT deptno, dname, loc FROM dept; SELECT deptno, dname, loc FROM dept WHERE deptno = 30 FOR UPDATE OF dname, loc; UPDATE dept SET dname = Consulting, loc = Chicago WHERE deptno = 30;
In this example, the primary key DEPTNO column is not included in the UPDATE statement issued by Oracle Forms. When you use NonUpdateable Key mode, it is usually best to set the Update Allowed item property to False for nonupdateable primary key items. This setting gives immediate feedback to operators that the primary key value cannot be edited in a queried record.
Description
Specifies that Oracle Forms should attempt to lock the corresponding row immediately after an operator or the application modifies an item value in a queried record. With this setting, Oracle Forms locks the record as soon as the operator presses a key to enter or edit the value in a text item. Specifies that Oracle Forms should wait to lock the corresponding row in the database until the transaction is about to be committed. With this setting, the record is locked only while the transaction is being posted to the database, not while the operator is editing the record.
DELAYED
Note: It is possible to implement an optimistic locking scheme by using the OnLock trigger to suppress locking as necessary.
45
ORACLE Version 6 and the Oracle7 Server support rowlevel locking to maximize concurrency. NonORACLE databases do not always support rowlevel locking, but rather, support page or tablelevel locking. Instead of locking only the row that has been modified for update, these databases lock the entire page or table. When a form is running against a database that supports page or tablelevel locking, the effect of locking on resource contention is potentially more severe because more records are affected. Between immediate locking and delayed locking there is a potential tradeoff between low concurrency and lost updates. Using immediate locking can result in low concurrency, while delaying locking can result in lost updates. An update can be lost when another user locks and updates the same row before the first operator finishes updating and committing a record. When this happens, Oracle Forms issues a message that the record has been modified by another user. The operator must then requery the updated row and make the desired changes again. For more details, refer to the description of the Locking Mode property in online Help, or in Oracle Forms Reference Manual, Vol. 2.
Because ORACLE allows the database state to be maintained across transactions, Oracle Forms allows cursors to remain open across COMMIT operations. This reduces overhead for subsequent execution of the same SQL statement because the cursor does not need to be reopened and the SQL statement does not always need to be reparsed.
46
Some nonORACLE databases do not allow database cursor state to be maintained across transactions. Therefore, you can set the Cursor Mode property to Close to satisfy those requirements. However, keep in mind that closing cursors at commit time and reopening them at execute time can degrade performance in three areas:
during the COMMIT operation during future execution of other SQL statements against the same records during execution of queries
For more details, refer to the description of the Cursor Mode property in the online Help, or in Oracle Forms Reference Manual, Vol. 2.
Description
Specifies that Oracle Forms should issue a savepoint at form startup and at the start of each Post and Commit process. Specifies that Oracle Forms is to issue no savepoints, and that no rollbacks to savepoints are to be performed.
False
When Savepoint Mode is set to False, Oracle Forms does not allow a form that has uncommitted changes to invoke another form with the CALL_FORM procedure. For more details, refer to the description of the Savepoint Mode property in online Help, or in Oracle Forms Reference Manual, Vol. 2.
47
OnCheckUnique OnClose OnColumnSecurity OnCommit OnCount OnDelete OnFetch OnInsert OnLock OnLogon
48
In addition, there are preevent triggers and postevent triggers you can use to trap events that occur just prior to and immediately after the corresponding Onevent: OnEvent Trigger
OnCommit OnDelete OnInsert OnLogon OnLogout OnSelect OnUpdate
The transactional triggers that apply to transaction processing in a block (OnSelect, OnFetch, etc.) can be defined at either the block level or the form level. Transactional triggers that apply to the Runform session (OnLogon, OnSavepoint, OnRollback, etc.) can be defined at the form level only.
49
The flow chart illustrates how a query is processed differently depending on whether an OnSelect trigger is defined in the form. When no OnSelect trigger is present, Oracle Forms performs the default processing required to issue the SELECT statement that identifies the rows in the database that meet the current query criteria (as specified by the example record). If, however, an OnSelect trigger has been defined at the appropriate definition level, Oracle Forms bypasses the default processing for selecting records, and instead executes the code in the OnSelect trigger. In this case, the OnSelect trigger is being executed in place of the default Oracle Forms processing.
4 10
When you define an Onevent trigger in a form, you are essentially telling Oracle Forms not to do what it would normally have done at that point of transaction processing, because you are going to manage that function yourself by writing appropriate code in the Ontrigger. That is, you are replacing the default functionality with the functionality you specify in the Onevent trigger.
4 11
Builtin Subprograms for OnEvent Triggers For most of the transactional Onevent triggers, there is a corresponding builtin subprogram. OnEvent Trigger
OnCheckUnique OnClose OnColumnSecurity OnCommit OnCount OnDelete OnFetch OnInsert OnLock OnLogon OnLogout OnRollback OnSavepoint OnSelect OnSequenceNumber OnUpdate
Corresponding Builtin
CHECK_RECORD_UNIQUENESS none ENFORCE_COLUMN_SECURITY COMMIT_FORM COUNT_QUERY DELETE_RECORD FETCH_RECORDS INSERT_RECORD LOCK_RECORD LOGON LOGOUT ISSUE_ROLLBACK ISSUE_SAVEPOINT SELECT_RECORDS GENERATE_SEQUENCE_NUMBER UPDATE_RECORD
When you call one of these builtin subprograms from its corresponding transactional trigger, Oracle Forms performs the default processing that it would have done normally at that point in the transaction. For example, if you call the INSERT_RECORD procedure from an OnInsert trigger, Oracle Forms performs the default processing for inserting a record in the database during a commit operation. When these builtins are issued from within their corresponding transactional triggers, they are known as dotherightthing builtins. That is, they do what Oracle Forms would normally have done at that point if no trigger had been present. Thus, an OnInsert trigger that calls the INSERT_RECORD procedure is functionally equivalent to not having an OnInsert trigger at all. Such a trigger is explicitly telling Oracle Forms to do what it would have done by default anyway.
4 12
Augmenting Default Processing You can call dotherightthing builtins from transactional triggers when you want to augment default processing. That is, when you want Oracle Forms to do what it would normally do, and also do something else. For example, you might create a form with three blocks, two of which are based on tables in an ORACLE database and one of which is based on data in a nonORACLE database. At startup, the form needs to log on to ORACLE, and also to establish that the nonORACLE data source is available. Your OnLogon trigger might look like this: OnLogon Trigger:
/* Do the default logon to ORACLE */ Logon; /* Now initialize the nonORACLE data source */ User_Exit(other_db);
If you had failed to include the LOGON builtin in this trigger, Oracle Forms would never have performed its default logon processing. A related use for dotherightthing builtins is to create applications that can run against both an ORACLE database and a nonORACLE data source. By including a conditional statement in the appropriate transactional triggers, you can build a form that performs default transaction processing when running against ORACLE, or executes the appropriate user exits to run against a nonORACLE data source. The decision can be based on the current value of a form parameter or global variable that gets set at form startup. OnInsert Trigger:
IF :PARAMETER.which_db = oracle THEN Insert_Record; ELSE User_Exit(do_insert); END IF;
4 13
If you use any of the dotherightthing builtins in your transactional triggers, be sure to check for their success or failure immediately afterward by using one of these techniques:
Call Check_Package_Failure (which should automatically have been created in any form that contains a relation).
or
Check the FORM_SUCCESS (BOOLEAN) function and raise the Form_Trigger_Failure exception if the dotherightthing builtin fails.
Since a failure does not halt the currentlyexecuting trigger, if you do not check for failure and raise the exception, the trigger will continue to execute and exit successfully. Unless Form_Trigger_Failure is raised appropriately, Runform will assume that your OnDelete trigger accomplished its goal. Using the NULL Statement Another use for the Onevent triggers is to suppress default processing completely, without replacing or augmenting it with alternative code. You can suppress default transaction processing by including the NULL statement in the appropriate Onevent trigger. An example of functionality you might want to suppress is default locking. By default, Oracle Forms takes advantage of the record locking capabilities of ORACLE by attempting to obtain locks as operators query and modify records. The OnLock trigger fires whenever Oracle Forms requests a lock. If, however, your nonORACLE data source does not support locking, or you want to implement a fullyoptimistic locking scheme, you must suppress default locking to avoid errors.
4 14
For example, to suppress locking you could define the following OnLock trigger: OnLock Trigger
NULL;
This trigger suppresses default processing by replacing it with NULL, that is, by doing nothing.
4 15
Logon and Logout Processing Query and Fetch Processing Count Query Processing Commit Processing Savepoint and Rollback Processing Check Column Security Processing Generate Sequence Number Processing Lock Record Processing
These sections frequently refer to specific triggers, builtin subprograms, object properties, and processing flow charts that are described elsewhere in the Oracle Forms documentation set:
4 16
For descriptions of specific transactional triggers, refer to the online Help or Chapter 2, Triggers, in the Oracle Forms Reference Manual, Vol. 1. For descriptions of specific dotherightthing builtins, refer to the online Help or Chapter 3, Builtin Subprograms, in the Oracle Forms Reference Manual, Vol. 1. For information on object properties, refer to the online Help or Chapter 5, Properties, in the Oracle Forms Reference Manual, Vol. 2. The following properties are especially important for nonORACLE data source support: Column Security Database_Value Datasource Key Mode Locking Mode Primary Key Query_Hits Query_Options Records_to_Fetch Savepoint Mode Savepoint_Name Transactional Triggers Update_Permission
For information on user exits, refer to Chapter 3, User Exit Interface to Foreign Functions, in Oracle Forms Advanced Techniques. For descriptions of runtime processes, refer to the following flow charts in Chapter 8, Processing Flowcharts, in the Oracle Forms Reference Manual, Vol. 2. Check Record Uniqueness Close the Query Count_Query Execute_Query Fetch Records
4 17
Generate Sequence Number Lock_Record Lock the Row Logon Logout Open the Query Post and Commit Transactions Prepare the Query Savepoint
Logout Triggers:
In a nonORACLE data source application, the OnLogon and OnLogout triggers are usually required. These triggers fire when Oracle Forms normally interacts with ORACLE, and so must either suppress or replace the default interaction. In fact, if you were to build a form that required no data source at all, such as a demo or tutorial
4 18
application, you would still need to include an OnLogon trigger to suppress the default logon attempt. Using the LOGON_SCREEN Builtin If your nonORACLE data source does not enforce security, you need only suppress the default Oracle Forms logon in an OnLogon trigger. If, however, you plan to enforce a security scheme, you may want to capture the current operators username, password, and connect string to use when logging on to the nonORACLE data source. You can do so with the LOGON_SCREEN builtin procedure. LOGON_SCREEN causes Oracle Forms to display the default Runform logon screen. The logon screen has fields for an operator to enter a username, password, and connect string. Once an operator accepts the logon screen, these values are known to Oracle Forms, and you can obtain them programmatically with a call to GET_APPLICATION_PROPERTY. The following example trigger illustrates this sequence: OnLogon Trigger:
/* Display the logon screen to get the operators username, password, and connect string */ Logon_Screen; /* Ask Oracle Forms connect string that */ :control.op_name := :control.op_pw := :control.op_con := for the username, password, and were entered Get_Application_Property(USERNAME); Get_Application_Property(PASSWORD); Get_Application_Property(CONNECT_STRING);
/* Now call a user exit that connects to the nonORACLE data source */ User_Exit(my_connect);
The user exit code includes an EXEC TOOLS GET statement that reads the values of the control items containing the username, password, and connect string and then uses those values to log on to the nonORACLE data source. Note: A user exit can read the values of form bind variables, including items, global variables, and form parameters. A user exit cannot read a local PL/SQL variable in a form. However, you can assign the value of a local PL/SQL variable to a NULL canvas item and then refer to that value in the user exit. Another method would be to pass parameters from the form to the user exit as part of the user exit command string.
4 19
Determining the Data Source You can use the builtin function GET_APPLICATION_PROPERTY (DATASOURCE) to determine the data source to which Oracle Forms is currently connected (ORACLE, DB2, etc.). It is important to note that this property identifies the default connectioneither to ORACLE or to an Open Gateway connection. When there is no default connection, for example, when there is an OnLogon trigger that replaces the default logon with a logon to a nonORACLE data source, the return value of GET_APPLICATION_PROPERTY(DATASOURCE) is NULL. For more information, refer to the following flow charts in Chapter 8 of the Oracle Forms Reference Manual, Vol. 2:
Logon Logout
The first part of Count Query processing is similar to the first part of Query and Fetch processing. Both require Oracle Forms to initialize the example record, clear the block, and prepare the query. In a Count Query operation, Oracle Forms then determines how many records meet the query criteria and displays that number in a message on the message line. In Query and Fetch processing, Oracle Forms identifies the records and then fetches them into the block as needed. During a Count Query operation, the following transactional triggers fire if they are present:
Of these, the OnCount trigger is required if you want to implement the count query hits feature against a nonORACLE data source. (The PreQuery and PreSelect triggers are used to augment default query
4 20
processing, rather than directly replace it. Note that these triggers also fire during normal Query and Fetch processing.) OnCount Trigger To replace default count query processing, the code in the OnCount trigger must do the following:
Call a user exit that interacts with the nonORACLE data source to determine the number of records that match the current query criteria. Call SET_BLOCK_PROPERTY to set the value of the Query_Hits block property to the number of records identified by the user exit.
For example, your OnCount trigger might call a user exit that identifies the number of records that meet the query criteria and then executes the EXEC TOOLS SET statement to set the value of a global variable in the form accordingly. The global variable can then be referenced in a call to SET_BLOCK_PROPERTY:
User_Exit(get_count); Set_Block_Property(block3,QUERY_HITS,:global.record_count);
When the OnCount trigger completes execution, Oracle Forms issues the standard query hits message, using the value of the Query_Hits block property to indicate the number of records identified by the query criteria:
FRM40355: Query will retrieve <value of Query_Hits block property> records.
Oracle Forms will display the query hits message even if the OnCount trigger fails to set the value of the Query_Hits block property. In such a case, the message reports 0 records. If you want to augment, rather than replace, default Count Query processing, you can call the COUNT_QUERY builtin from the OnCount trigger. Note: You can also call GET_BLOCK_PROPERTY to examine the current value of the Query_Hits property. Be aware, however, that the Query_Hits setting is interpreted differently depending on where you examine it:
In an OnCount trigger, Query_Hits specifies the number of records identified by the query criteria. During fetch processing (outside an OnCount trigger), Query_Hits specifies the number of records that have been placed on the blocks list of records so far.
4 21
For more information on Count Query processing, refer to the following flow charts in Chapter 8 of the Oracle Forms Reference Manual, Vol. 2.
Fetch Phase:
OnFetch (fires as many times as needed to fetch all records) PostQuery (fires once for each record placed on the blocks list of records) OnClose
Of these, the OnSelect and OnFetch triggers are required when you implement support for a nonORACLE data source. The OnSelect trigger is responsible for constructing a query based on the current example record, then executing it against the nonORACLE datasource to identify those records that match the query criteria.
4 22
The OnFetch trigger is responsible for determining how many records are required by the block, creating the appropriate number of records on the blocks waiting list (using the data that were identified by the OnSelect trigger and then retrieved from the nonORACLE data source), and signaling to the form when all of the records have been fetched. A query remains open until all of the records identified by the query criteria have been fetched, or until the operator or the application aborts the query. While the query remains open, the OnFetch trigger continues to fire whenever the form needs more records to be placed on the blocks list of records. For example, as the operator scrolls down through the blocks list of records, the OnFetch trigger will fire as many times as necessary to fetch more records to be displayed in the block. Note: Default query and fetch processing is described in the following flow charts in the Oracle Forms Reference Manual, Vol. 2:
Check Block for Query Open the Query Prepare the Query Fetch Records
Selection Processing The OnSelect trigger fires at the point during default processing when Oracle Forms normally constructs, opens, parses, and executes a query. When you implement support for a nonORACLE data source, the code in your OnSelect trigger replaces this default functionality By default, query and fetch processing is a twostep process, one step to identify the records in the data source, and another to fetch them into the form. This approach may or may not be appropriate for a nonORACLE data source application. As long as the code in the OnFetch trigger creates enough records to meet the requirements of the block, it is up to you when and how the data for those records are actually retrieved from the nonORACLE data source. One method would be to have the user exit called in the OnSelect trigger actually retrieve some or all of the records, rather then deferring that operation until the Fetch phase. Using this technique, the code in the OnSelect trigger might create a clientside record cache from which records would be subsequently read into the form by the user exit called from the OnFetch trigger.
4 23
Or, you might use the OnSelect trigger only to suppress default Selection processing, and do all of your query and fetch processing in the OnFetch trigger. The specifics of your implementation will depend on the characteristics of the data source to which you are connecting. For some applications, you may need to know what type of query Oracle Forms is processing. You can find out by using GET_BLOCK_PROPERTY to read the value of the Query_Options property. The Query_Options property is readonly, and is set at runtime to one of the following values: COUNT_QUERY Indicates that the current query operation is a count query operation. This value occurs only when Query_Options is examined from within an OnCount trigger. Indicates that the FOR_UPDATE option was specified for EXECUTE_QUERY. By default, FOR_UPDATE causes Oracle Forms to attempt an immediate lock on records being selected. Indicates that the query is being processed against a view, rather than a table. By default, this causes Oracle Forms to issue its default SELECT statement without using row IDs. Because the use of row IDs is unique to ORACLE, this is usually not relevant when running against a nonORACLE data source. Indicates that no query is being processed.
FOR_UPDATE
VIEW
NULL
Fetch Processing The OnFetch trigger replaces Oracle Forms default fetch processing, and must perform the following actions:
determine how many records to fetch create that number of records on the blocks waiting list signal to the form when there are no more records to fetch so that the query can be closed
4 24
The following example shows an OnFetch trigger that populates an employee block named emp. The emp block contains three text items, empno, ename, and sal. OnFetch Trigger:
DECLARE recs NUMBER; emp_id NUMBER; emp_name VARCHAR2(40); emp_sal NUMBER; BEGIN /* Determine how many records are needed */ recs := Get_Block_Property(emp, RECORDS_TO_FETCH); /* Attempt to fetch that many records from the data source */ FOR j IN 1..recs LOOP /* If a row is retrieved, then create a queried record for it and populate the record with data values retrieved from the nonORACLE data source /* IF fetch_row(emp_id, emp_name, emp_sal) THEN Create_Queried_Record; :emp.empno := emp_id; :emp.ename := emp_name; :emp.sal := emp_sal; END IF; END LOOP; END;
Determining How Many Records to Fetch The first requirement for the OnFetch trigger is to determine how many records are required by the block. As shown in the example, this is accomplished by examining the value of the Records_To_Fetch block property:
/* Determine how many records are needed */ recs := Get_Block_Property(emp, RECORDS_TO_FETCH);
The Records_To_Fetch block property is a runtime, readonly property whose value is set internally by Oracle Forms, based on how many records the form has requested for the block. The first time the OnFetch trigger fires during a query, the Records_To_Fetch property is set to the array size or to the number of records displayed + 1, whichever is greater. Note: A blocks default array size is specified by the Records Fetched block property. The number of records a block can display is specified by the Records Displayed block property, and determines whether a block is a single or multirecord block.
4 25
Creating Queried Records Once the number of records required is known, the OnFetch trigger must create that number of records on the blocks waiting list. The waiting list is an intermediary record buffer that contains records that have been fetched from the data source, but have not yet been placed on the blocks list of active records. Creating queried records is usually accomplished with a loop that uses the Records_To_Fetch value as its index, as shown in the example:
/* Attempt to fetch that many records from the data source */ FOR j IN 1..recs LOOP /* If a row is retrieved, then create a queried record for it and populate the record with data values retrieved from the nonORACLE data source /* IF fetch_row(emp_id, emp_name, emp_sal) THEN Create_Queried_Record; :emp.empno := emp_id; :emp.ename := emp_name; :emp.sal := emp_sal; END IF; END LOOP;
The builtin procedure CREATE_QUERIED_RECORD is called once inside the loop for each record required by the block. CREATE_QUERIED_RECORD creates a record on the blocks waiting list. The new record is essentially an empty placeholder. To populate the empty record with data from the nonORACLE data source, the data values for each column in the fetched record must be assigned to the corresponding fields in the new queried record, using standard bind variable syntax. You must do the assignment immediately after the record is created; it is not possible to create a batch of records and then subsequently try to populate them. Notice that the previous example does not show how records from the nonORACLE data source are retrieved and managed before their values are placed into queried records on the blocks waiting list. Again, the specifics of your implementation will depend on the data source to which you are connecting, and on how you choose to manage these operations. In most implementations, a call to a user exit is made from inside the loop in the OnFetch trigger. The user exit is responsible for getting a record from the nonORACLE data source, assigning column values from the fetched record to form variables, and then returning control to the OnFetch trigger so that the trigger code can create a queried record on the blocks waiting list and populate it with the values from the nonORACLE data source.
4 26
As you can see, this technique requires that the user exit and Oracle Forms be tightly coupled. Specifically, you need the ability to set and get the values of form bind variables from within the user exit, and the ability to pass control between the form trigger and the user exit without losing the current context of either. To make this sort of interaction possible, Oracle has included the following commands that you can execute in user exits that you create with an Oracle Precompiler:
EXEC TOOLS GET EXEC TOOLS SET EXEC TOOLS GET CONTEXT EXEC TOOLS SET CONTEXT
For information on these commands, see Oracle Forms Advanced Techniques, Chapter 3, User Exit Interface to Foreign Functions. Signaling an EndofFetch As mentioned previously, a query remains open until all of the records identified by the query criteria have been fetched, or until the operator or the application aborts the query. When the form requests more records to be fetched from an open query (because, for example, the operator scrolls to the end of the blocks list of records), the OnFetch trigger will fire as necessary to meet the demand for more records. Eventually, however, all of the records that match the query criteria will have been placed on the blocks list of records by the OnFetch trigger. When this occurs, the OnFetch trigger needs a way to signal to the form that no more records are available so that the OnFetch trigger stops firing. Oracle Forms uses the following mechanism to accomplish this: When the OnFetch trigger fires successfully but does not create any queried records (by executing CREATE_QUERIED_RECORD), Oracle Forms assumes there are no more records to be fetched, and so closes the query and does not fire the OnFetch trigger again. In the previous example trigger, you saw that a queried record was created only if the usernamed, BOOLEAN function called fetch_row returned TRUE. In an actual application, the fetch_row function might call a user exit to determine if another row is available in the nonORACLE data source. If fetch row returns TRUE, that is, if there was another row to be fetched, then CREATE_QUERIED_RECORD creates a record. Otherwise, the loop executes without creating any more records.
4 27
FOR j IN 1..recs LOOP /* If a row is retrieved, then create a queried record for it and populate the record with data values retrieved from the nonORACLE data source /* IF fetch_row(emp_id, emp_name, emp_sal) THEN Create_Queried_Record; only if there is another :emp.empno := emp_id; row in the data source :emp.ename := emp_name; :emp.sal := emp_sal; END IF; END LOOP;
Oracle Forms also looks at the number of records created by the OnFetch trigger and sets the value of the Records_To_Fetch block property accordingly:
The first time the OnFetch trigger fires for a query, the value of Records_To_Fetch is set to the array size or to the number of records displayed + 1, whichever is greater. If the OnFetch trigger creates this many queried records, the next time the OnFetch trigger fires, the value of Records_To_Fetch will be the same number. If the OnFetch trigger creates fewer records than specified by Records_To_Fetch, Oracle Forms fires the OnFetch trigger again immediately, and sets Records_To_Fetch to the previous value minus the number of queried records created by the previous execution of the OnFetch trigger.
Note: The OnFetch trigger must never create more queried records than are required by the form (as indicated by the Records_To_Fetch property). Doing so will irretrievably disrupt form processing. (You can raise the builtin exception FORM_TRIGGER_FAILURE when fetch errors occur in the OnFetch trigger to return to normal form processing.) Closing the Query By default, Oracle Forms closes a query when all of the records have been fetched or the operator or the application aborts the query. In a nonORACLE data source application, no action is required by you to explicitly close a query. In certain cases, however, you might need to close, or clean up, the connection to your nonORACLE data source. For example, if the user exit that was called from the OnFetch trigger was maintaining a record cache or some other context, you might want to free up those resources when they are no longer required because the query has been closed.
4 28
You can accomplish operations of this type in an OnClose trigger. Note that unlike other Onevent triggers, the OnClose trigger actually augments, rather than replaces, the default close query operation. (Oracle Forms must always close a query at the appropriate time to avoid an inconsistent state in the form.)
Commit Processing
Commit Processing refers to the sequence of events that occurs when the operator or the application initiates a database commit operation, either with a key or menu command, or by executing the COMMIT_FORM builtin procedure. Default commit processing happens in three parts:
Validation When the operator or the application initiates a commit operation, Oracle Forms validates the records on each base table blocks list of records. Posting During posting, Oracle Forms moves to each block in the form and writes any pending updates, inserts, and deletes to the database. Committing By default, Oracle Forms issues a savepoint at the start of a commit operation. Changes that have been posted to the database but not yet committed can be rolled back to this savepoint. To finalize the commit transaction, Oracle Forms must explicitly issue the COMMIT statement. This happens as the final step of Commit processing.
For a detailed description of default commit processing, refer to the following flow charts in Chapter 8 of the Oracle Forms Reference Manual, Vol. 2:
Check Record Uniqueness Post and Commit Transactions Savepoint Validate the Form
During Commit processing, the following transactional triggers will fire as necessary if they are present:
OnSavepoint (fires once at the beginning of the transaction) PreCommit (fires once at the beginning of validation) PreDelete/OnDelete/PostDelete (fires once for each record being deleted)
4 29
PreUpdate/OnUpdate/PostUpdate (fires once for each record being updated) PreInsert/OnInsert/PostInsert (fires once for each record being inserted) OnCheckUnique (may fire once for each record inserted or updated, depending on primary key constraints) PostFormsCommit (fires after posting, before the database commit) OnCommit (fires once at the end of the transaction) PostDatabaseCommit (fires after OnCommit)
Of these, the following are always required in a nonORACLE data source application that allows operators to modify queried records:
The OnCheckUnique trigger is also required if your application is verifying that each record has a unique primary key before updating or inserting the record in the data source. (This happens by default when the block has the Primary Key block property and one or more items in the block have the Primary Key item property set to True.) When Oracle Forms is running against ORACLE, posting and committing are separate operations. If, however, your nonORACLE data source does not support this functionality, changes you write to the data source are final, and do not have to be committed as a separate operation. In this case, you might define an OnCommit trigger only to suppress the default Oracle Forms COMMIT statement, and write all of your changes to the data source in user exits called by the OnDelete, OnUpdate, and OnInsert triggers. Note: The OnSavepoint trigger fires at the start of Commit processing, and is discussed in the topic Savepoint and Rollback Processing.
4 30
Processing Inserts, Updates, and Deletes During commit processing, the OnDelete, OnUpdate, and OnInsert triggers fire once for each record in the block that was changed. These triggers replace the default processing that Oracle Forms would normally perform at that point. For example, the OnUpdate trigger fires when Oracle Forms would normally issue the appropriate SQL UPDATE statement to update the row in the database that corresponds to the record that was modified by the form operator. To replace default processing, you need to write a separate user exit for the OnDelete, OnUpdate, and OnInsert triggers. These user exits are responsible for performing the appropriate action on the corresponding row in the nonORACLE data source. Again, the specifics of your implementation will depend on the characteristics of your data source. The following OnDelete trigger calls a user exit named kill_row that is responsible for deleting the appropriate row from the nonORACLE data source: OnDelete Trigger:
User_Exit(kill_row);
Obviously, the code in the user exit needs to know which record is being processed by Oracle Forms so that it can act on the corresponding row in the nonORACLE data source. This is made possible by the fact that Oracle Forms processes inserts, updates, and deletes sequentially, one record at a time. Within an OnDelete, OnUpdate, or OnInsert trigger, the record being deleted, inserted, or updated is always the current record. This means that you can use standard bind variable syntax (:block_name.item_name) to reference the values of items in the current record from within these triggers. (Remember that a user exit can read the values of form bind variables with the EXEC TOOLS GET statement.) Checking for Unique Primary Keys You can designate one or more items in a block as primary key items by setting the Primary Key item and block properties to True. When these properties are set, Oracle Forms enforces primary key uniqueness by
preventing updates to primary key columns in the base table preventing the insertion of records that contain duplicate primary key values
4 31
Oracle Forms checks the uniqueness of primary key values just before inserting or updating the record in the database. When a record has been inserted in a block, Oracle Forms will always perform the uniqueness check. When a record has been updated, Oracle Forms performs the uniqueness check only if one or more primary key item values were modified. Oracle Forms checks the uniqueness of a record by constructing and executing the appropriate SQL statement to select for database rows that match the record about to be inserted or updated. If a row having a duplicate primary key is found, Oracle Forms displays message FRM40600: Row has already been inserted. and disallows the insert or update. When this happens, the input focus remains in the offending record, allowing the operator to correct the problem before trying to commit again. If your nonORACLE data source application supports primary key uniqueness, you can replace Oracle Forms default uniqueness checking by calling an appropriate user exit from an OnCheckUnique trigger. When the Primary Key item and block properties are set to True, this trigger fires just before the OnInsert trigger and, when necessary (because a primary key value was modified), just before the OnUpdate trigger. OnCheckUnique Trigger The code in the OnCheckUnique trigger might perform the following tasks:
read the values of the primary key items in the current record compare those values against rows in the data source if a duplicate row is found, display an appropriate message or alert to inform the operator, then raise the builtin exception FORM_TRIGGER_FAILURE to explicitly cause the trigger to fail and abort commit processing
The following example shows what such a trigger might look like: OnCheckUnique Trigger::
DECLARE duplicate BOOLEAN; BEGIN User_Exit(do_check); IF duplicate THEN Message(Primary key must be unique. Bell; RAISE Form_Trigger_Failure; END IF; END;
Unable to commit.);
4 32
In this example, the user exit do_check checks for duplicate primary key values in the nonORACLE data source, then sets the value of the BOOLEAN variable duplicate accordingly. Raising the FORM_TRIGGER_FAILURE exception causes the trigger to fail, which in turn causes Oracle Forms to abort commit processing and roll back to the last savepoint.
4 33
When you implement custom savepoint functionality by writing OnSavepoint and OnRollback triggers, you can capture the savepoint names that Oracle Forms would use by default by calling GET_APPLICATION_PROPERTY to examine the current value of the Savepoint_Name property:
my_savepoint := Get_Application_Property(SAVEPOINT_NAME);
The value of Savepoint_Name depends on whether you examine it from an OnSavepoint or OnRollback trigger:
In an OnSavepoint trigger, Savepoint_Name returns the name of the savepoint that Oracle Forms would be issuing by default, if no OnSavepoint trigger were present. In an OnRollback trigger, Savepoint_Name returns the name of the savepoint to which Oracle Forms would roll back, if no OnRollback trigger were present.
In an application that runs against both ORACLE and a nonORACLE data source, you can use the ISSUE_SAVEPOINT builtin to issue the correct savepoint from an OnSavepoint trigger:
IF Get_Application_Property(DATASOURCE) = ORACLE THEN Issue_Savepoint(Get_Application_Property(SAVEPOINT_NAME); ELSE User_Exit(non_ora); END IF;
queries the database to determine the base table columns to which the current form operator has update privileges for columns to which the operator does not have update privileges, Oracle Forms makes the corresponding base table items in the form nonupdateable by setting the Update Allowed item property to False dynamically
By default, Oracle Forms performs these steps at form logon, processing each block in sequence.
4 34
If your nonORACLE data source application does not require columnlevel security, you can suppress the default processing by making sure that the Column Security property is set to False for each block in the form, or by defining an OnColumnSecurity trigger that suppresses default processing. OnColumnSecurity Trigger If you want to implement a security check comparable to Oracle Forms default processing, you must define an OnColumnSecurity trigger. The code in the OnColumnSecurity trigger might do the following:
call GET_APPLICATION_PROPERTY to get the current form operators username and password interact with the nonORACLE data source to determine the columns to which the current operator has update privileges call SET_ITEM_PROPERTY to set the Update_Permission property to False for any items that operators should not be allowed to modify (when Update_Permission is False, operators are not allowed to update the item, and its value is not included in any UPDATE statement generated by Oracle Forms.)
The OnColumnSecurity trigger fires once for each block that has the Column Security property On, and can be defined at either the form level or block level. Note, however, that when you define this trigger at the form level, there is no explicit way to determine which block Oracle Forms is currently processing. (Because the OnColumnSecurity trigger fires at startup, before the form is instantiated, the value of SYSTEM.CURRENT_BLOCK is still undefined.) In this case, you must keep track of the current block yourself, based on the fact that blocks with the Column Security property set to True are processed sequentially, according to the sequence of the blocks in the form. (Block sequence is defined at design time by the order of blocks listed in the Object Navigator.) When you define the OnColumnSecurity trigger at the block level, the current block context is, of course, readily apparent.
4 35
Sequences are often used to generate unique primary key values for records that will subsequently be inserted in the database. In a form, you can specify that an items default value should be the next integer from a database sequence by setting the Default property to
:SEQUENCE.my_seq.NEXTVAL.
When a SEQUENCE is used as a default item value, Oracle Forms queries the database to get the next value from the SEQUENCE whenever the Create Record event occurs. You can suppress or override this functionality with an OnSequenceNumber trigger. In practice, it is unlikely that you would be referencing a SEQUENCE as a default item value in a nonORACLE data source application. It is possible, however, that you would want to implement equivalent functionality, using values provided by some other source. In this case, it is often better to perform this operation in a WhenCreateRecord trigger.
4 36
CHAPTER
MultipleForm Applications
ou can build applications by integrating multiple form, menu, and library modules. This chapter explains how to use multiple form modules in a single application. It includes the following topics:
About MultipleForm Applications 5 2 Invoking Independent Forms with OPEN_FORM 5 4 Replacing the Current Form with NEW_FORM 5 9 Calling Modal Forms with CALL_FORM 5 10 Managing Commit Processing When Using CALL_FORM 5 15 Passing Parameters to Forms 5 23 Integrating Form and Menu Modules 5 26
MultipleForm Applications
51
Invoking Forms
There are three ways that one form can programmatically invoke another form:
Execute the OPEN_FORM procedure to open an independent form. Execute the NEW_FORM procedure to replace the current form with a different form. Execute the CALL_FORM procedure to call a modal form.
When one form invokes another form by executing OPEN_FORM, the first form remains displayed, and operators can navigate between the forms as desired. An opened form can share the same database session as the form from which it was invoked, or it can create a separate session of its own. For most GUI applications, using OPEN_FORM is the preferred way to implement multipleform functionality. When one form invokes another form by executing NEW_FORM, Oracle Forms exits the first form and releases its memory before loading the new form. Calling NEW_FORM completely replaces the first form with the second. If there are changes pending in the first form, the operator will be prompted to save them before the new form is loaded. When one form invokes another form by executing CALL_FORM, the called form is modal with respect to the calling form. That is, any windows that belong to the calling form are disabled, and operators cannot navigate to them until they first exit the called form.
52
Both OPEN_FORM and CALL_FORM allow you to leave the calling form displayed. Using this technique, forms can be integrated so tightly that operators are not aware they are invoking separate forms. Any locks obtained by a form are maintained across both OPEN_FORM (in the same session), CALL_FORM and NEW_FORM procedure calls. Thus, a called form automatically has the same locks as its calling form. CALL_FORM is an unrestricted procedure, OPEN_FORM and NEW_FORM are restricted. Therefore, CALL_FORM is valid in Enter Query mode, while OPEN_FORM and NEW_FORM are not.
a content canvasview or stacked canvasview assigned to a window other than the root window a stacked canvasview assigned to the root window
When the target canvasview is assigned to a different window, Oracle Forms displays the second form in a separate window, and the first forms root window display remains unchanged. When the target canvasview is a stacked canvasview assigned to the root window, Oracle Forms displays it in the first forms root window. However, if the stacked canvasview is smaller than the content canvasview (usually the case), the first forms content view will remain at least partially visible.
MultipleForm Applications
53
By default, the opened form is activated immediately and focus is set to the first navigable item in the form. You can specify this default behavior explicitly by including the optional ACTIVATE parameter in the call to OPEN_FORM:
Open_Form(stocks,ACTIVATE);
If you do not want the opened form to receive focus, call OPEN_FORM with the NO_ACTIVATE parameter, as shown here:
Open_Form(stocks,NO_ACTIVATE);
When you open a form with ACTIVATE specified (the default), focus is set to the opened form immediately, and any trigger statements that follow the call to OPEN_FORM are ignored and never execute. When you open a form with NO_ACTIVATE specified, any trigger statements that follow the call to OPEN_FORM execute after the opened form has been loaded into memory and its initial startup triggers (if any) have been fired. Whether you open a form with ACTIVATE or NO_ACTIVATE, any triggers that would normally fire at form startup will execute in the form being opened. This could potentially include PreForm, WhenNewFormInstance, WhenNewBlockInstance, WhenNewRecordInstance, and WhenNewItemInstance. You can close an independent form with the CLOSE_FORM procedure, as shown here:
Close_Form(stocks);
54
The GO_FORM procedure takes one parameter that specifies the name of the target form:
Go_Form(schedule);
NEXT_FORM and PREVIOUS_FORM navigate to the next or previous form in the sequence defined by the order the forms were opened at runtime:
Next_Form; Previous_Form;
Many triggers fire in response to navigational events, including Pre and Post triggers (PreBlock, PostRecord, etc.) and WhenNewInstance triggers (WhenNewBlockInstance, WhenNewItemInstance, etc.). When you build an application with multiple forms, it is important to understand how trigger processing is affected by navigation. In a multipleform application, each open form has one item that is the current item for that form. If you initiate navigation to an open form programmatically with GO_FORM, NEXT_FORM, PREVIOUS_FORM, or EXIT_FORM, the target item is always the current item in the target form. For example, when Form A opens and activates Form B, focus is set to the current item in Form B. If Form B subsequently calls EXIT_FORM or PREVIOUS_FORM, the focus returns to the current item in Form Ain this case, the item that was current when Form A opened Form B. Keep in mind the following points about interform navigation:
When navigating between independent forms, no validation occurs in the starting form. It is possible to navigate out of a field that is currently invalid provided that the target field is in a different form. Upon returning to the starting form and attempting to navigate within that form, normal validation is enforced. When navigating between independent forms, no triggers fire. The only exceptions are WhenWindowDeactivated, which fires in the form that initiates navigation, and WhenWindowActivated, which fires in the target form. The Pre, Post, and WhenNewInstance triggers do not fire when navigating between forms.
When the operator navigates from Form A to Form B by clicking with the mouse, the target item can be either the current item in Form B or an item other than the current item in Form B.
MultipleForm Applications
55
If the operator clicks on the current item in Form B, no triggers fire. If the operator clicks on an item other than the current item, only triggers that would normally fire when navigating from the current item in Form B to the target item fire, and validation occurs as required. Thus, form processing proceeds exactly as it would if the operator were navigating from the current item in Form B to the target item, without regard to any external forms.
To open a form in its own, independent session, call OPEN_FORM with the SESSION parameter, as shown here:
Open_Form(stocks,ACTIVATE,SESSION);
This statement opens the STOCKS form in its own session, and sets focus to it immediately. When a COMMIT is initiated in any form, Oracle Forms does validation and commit processing for each open form that shares the same session as that form. Forms are processed in the sequence defined by the order in which they were opened, starting with the form that initiated the
56
COMMIT. If an error occurs during commit processing, the input focus is returned to the form that initiated the COMMIT. When you call OPEN_FORM with the NO_SESSION parameter (the default), Oracle Forms does not issue a savepoint for the form as it does when you use CALL_FORM. If Form A opens Form B, both forms share the same session. If Form B executes CLEAR_FORM (which does an implicit ROLLBACK), all of the changes that were made in both Form A and Form B will be rolled back. Creating independent sessions is usually appropriate for forms that access different tables, and that manage transactions that are logically independent. For example, an order entry form might have a menu option to invoke an appointment calendar form. If the appointment calendar is opened in the same session as the order entry form, the operator will have to commit any changes made to the order entry and calendar forms at the same time. If, however, the calendar form is opened in a separate session, the operator can enter a new appointment and save it to the database independently, without having to commit in the order entry form. Note: Oracle Forms Runform must be running with the Session option turned On when you execute OPEN_FORM with the session_mode parameter set to SESSION. If the Session option is Off, Oracle Forms issues an error and does not open the indicated form. You can set session On for all Runform invocations by setting the FORMS45_SESSION environment variable to TRUE. When you set the FORMS45_SESSION variable, all Runform invocations inherit its setting, unless you override the environment variable by setting the Session option from the Runform command line.
MultipleForm Applications
57
Once a form has been opened, you can obtain its internal ID with the builtin FIND_FORM function:
DECLARE form_id FormModule; BEGIN Open_Form(stocks,NO_ACTIVATE); form_id := Find_Form(stocks); :GLOBAL.formid := To_Char(form_id.id); END;
In this example, a variable of type FormModule is declared. (FormModule is one of the native Oracle Forms types.) Once the STOCKS form is opened, its internal ID is assigned to the variable by calling the FIND_FORM function. Then, the instance identifier is converted to CHAR and assigned to a global variable with the syntax:
:GLOBAL.formid := To_Char(form_id.id);
Once you have stored the instance identifier in a global variable, you can retrieve it at any time for operations on the specific form instance. The following example passes the instance identifier to the builtin procedure GO_FORM:
DECLARE form_id FormModule; BEGIN form_id.id := To_Number(:GLOBAL.formid); Go_Form(form_id); END;
The GO_FORM procedure takes a parameter of type FormModule, so the first step is to declare a variable of that type to hold the instance ID currently held in the global variable. Notice also that the instance identifier must be cast to NUMBER to be a valid FormModule value. By combining the use of global variables with the builtin COPY procedure, you can store the instance identifier for several different forms, as shown here:
DECLARE form_id FormModule; temp CHAR(10); BEGIN Initialize a counter, open the STOCKS form, and store its internal ID in form_id Default_Value(1,GLOBAL.counter); Open_Form(stocks,NO_ACTIVATE); form_id := Find_Form(stocks); The Copy() procedure reads only global variables
58
and item values, so put the instance identifier in in a a temporary global variable :GLOBAL.temp_var := To_Char(form_id.id); Now assign the ID to the next occurrence of the global variable :GLOBAL.form<x>, where x is the counter value Copy(Name_In(GLOBAL.temp_var), GLOBAL.form||:GLOBAL.counter); :GLOBAL.counter := To_Number(:GLOBAL.counter)+1; END;
This example creates a set of global variables (:GLOBAL.form1, :GLOBAL.form2 ... GLOBAL.formn) which contain the instance identifiers for each open form. You can then use the appropriate variable for programmatic operations on a specific form.
If you leave the optional parameters unspecified, Oracle Forms runs the new form using the defaults for those parameters. Hence,
New_Form(form_B);
is logically equivalent to
New_Form(form_B,TO_SAVEPOINT,NO_QUERY_ONLY);
If the calling form was itself a called form invoked with the CALL_FORM procedure, the new form assumes the parent forms position in the call stack. Further, Oracle Forms runs the new form with the same CALL_FORM parameters (HIDE or NO_HIDE, DO_REPLACE or NO_REPLACE, and QUERY_ONLY or NO_QUERY_ONLY) as the calling form.
MultipleForm Applications
59
CALL_FORM loads the indicated form while leaving the calling form loaded. For example, when Form A calls Form B, Form B becomes the active form in the session, but Form A remains in memory. If the operator exits Form B, Form A again becomes the active form. Form B, in turn, can execute the CALL_FORM procedure to invoke Form C. When successive forms are loaded via the CALL_FORM procedure, the resulting module hierarchy is known as the call form stack. When a form calls another form with CALL_FORM, the called form is modal with respect to the calling form. Windows that belong to the calling form are disabled, and operators cannot navigate to them until the operator exits the called form. In contrast to the CALL_FORM procedure, NEW_FORM exits the current form and releases its associated memory before running the new form at the current position in the call form stack.
The following specification shows the formal parameters and default values for the builtin procedure CALL_FORM:
Call_Form(formmodule_name CHAR [,display NUMBER := HIDE, switch_menu NUMBER := NO_REPLACE, query_mode NUMBER := NO_QUERY_ONLY, parameterlist_name CHAR]);
5 10
The only required parameter is formmodule_name. If you leave the optional parameters unspecified, Oracle Forms runs the called form using the default values for those parameters. Hence,
Call_Form(form_B);
is logically equivalent to
Call_Form(form_B,HIDE,NO_REPLACE,NO_QUERY_ONLY);
When you execute CALL_FORM, you can specify whether the calling form should remain displayed by passing an appropriate constant for the display parameter. Valid constants are HIDE (the default) and NO_HIDE. The following procedure call invokes Form B and leaves Form A (the calling form) displayed:
Call_Form(form_B,NO_HIDE);
Only the called form is active, and operators cannot navigate to items in the calling form until they exit the called form.
EXIT_FORM procedure NEW_FORM procedure Exit command on the default Action menu [Exit/Cancel] key
When a called form exits, control returns to the calling form, and processing resumes where it left off. This means that the trigger, menu item command, or usernamed routine that executed the CALL_FORM procedure resumes processing at the statement immediately following the CALL_FORM procedure call.
MultipleForm Applications
5 11
For example, the called form might have a button labeled QUIT that allows operators to quit the entire application from a called form. The WhenButtonPressed trigger for each button sets the value of a global variable to indicate that the operator wants to either quit the session or return to the calling form. WhenButtonPressed Trigger on QUIT button in Called Form B:
:GLOBAL.quit_check := quit; Exit_Form;
Then, in the calling form, read the value of the global variable immediately after the CALL_FORM procedure statement: Trigger Text in Calling Form A:
Call_Form(form_B); /* ** The following statements execute immediately after ** returning from the called form. */ IF :GLOBAL.quit_check = quit THEN Exit_Form; END IF;
or
New_Form(form_B,TO_SAVEPOINT,QUERY_ONLY);
Note: Oracle Forms runs any form called from a form in queryonly mode as a QUERY_ONLY form, even if the CALL_FORM or NEW_FORM syntax specifies that the called form is to run in NO_QUERY_ONLY (normal) mode.
5 12
Navigation: Any attempt to navigate programmatically to a disabled form in a call form stack is disallowed. Calling Forms: An open form cannot execute the CALL_FORM procedure if a chain of called forms has been initiated by another open form. Clear All/Rollbacks: When a form is invoked with CALL_FORM, Oracle Forms issues a savepoint. Any subsequent ROLLBACK, in any active form, will roll back only changes that were made since the last savepoint was issued; that is, since the execution of CALL_FORM.
Restrictions on Navigation Consider the following example. Form A executes CALL_FORM to call Form B. Form B then executes OPEN_FORM to open Form C. Form C then opens Form D. Form B then calls Form E.
MultipleForm Applications
5 13
Restrictions on Calling Forms At this point in the example, there are three active, navigable forms (E, C, and D), and two disabled, nonnavigable forms (A and B). Any attempt to navigate programmatically to Form A or Form B will raise an error. Together, Form A, Form B, and Form E represent the current call form stack in the application. If Form C attempted to call a form with CALL_FORM, an error would occur because of the restriction that an open form cannot issue a CALL_FORM when there is an existing stack of called forms that was initiated by another form (Form A, in this example).
Before Form C can successfully execute CALL_FORM, the operator or the application would have to exit Form E and return to Form B, then exit Form B to close out the call form stack. If Form D exits, focus returns to the form from which Form D was opened, in this case, Form C. If Form C then exits, focus returns to Form E, even though Form B originally opened Form C. This is because Form B is currently disabled as a result of having issued a CALL_FORM to invoke Form E. Restrictions on Clear All/Rollback Oracle Forms issues a savepoint whenever a form executes CALL_FORM to invoke a modal form. When there are multiple open forms running in the same session, each transaction event, in any form, is part of the same continuum. This means that if the operator selects the Clear All command on the default menu, or any form executes CLEAR_FORM (both of which cause an implicit ROLLBACK), only changes that have been made since the called form was invoked (and the savepoint was issued) will be rolled back. Any changes that happened before that time, in any form, will remain in effect.
5 14
MultipleForm Applications
5 15
obtained by a calling form are maintained until control is returned to that form.
5 16
a form executes the EXIT_FORM builtin procedure the operator selects the Exit item on the default Action menu (this is equivalent to calling EXIT_FORM with default parameters) a form executes the NEW_FORM builtin procedure a form executes the CLEAR_FORM builtin procedure the operator selects the Action, Clear All command from the default menu (this is equivalent to calling CLEAR_FORM with default parameters)
Whether changes are preserved or rolled back depends on the rollback mode specified for these operations. When you call the EXIT_FORM, NEW_FORM, or CLEAR_FORM procedures, the rollback mode is determined by the constant you supply for the rollback_mode parameter: TO_SAVEPOINT, NO_ROLLBACK, or FULL_ROLLBACK.
MultipleForm Applications
5 17
Description The default rollback mode. Oracle Forms rolls back uncommitted changes (including posted changes) to the last savepoint. If the form is a called form, any changes that were posted in the calling form are preserved. But changes in the current form or locks acquired are lost. Oracle Forms does not issue a rollback, and posted changes are preserved. (Unposted changes in the current form are lost.) When calling a new form or exiting a called form, any locks that were obtained by the current form remain in effect. Oracle Forms rolls back all uncommitted changes pending in the current session (including posted changes). This includes changes made in the current form, posted changes made in forms that called the current form, and posted changes made in forms that were called by the current form.
NO_ROLLBACK
FULL_ROLLBACK
Note that full rollbacks are not allowed when a form is in postonly mode, and calling a procedure with the FULL_ROLLBACK parameter returns an error such as FRM40739: Clear_Form with
FULL_ROLLBACK not allowed in postonly form.
Note: Oracle Forms interprets a ROLLBACK statement in a PL/SQL block as a CLEAR_FORM builtin procedure with no parameters.
5 18
Similarly, the Exit menu item on the Action menu is functionally equivalent to calling the EXIT_FORM procedure with default parameters:
Exit_Form(ASK_COMMIT,TO_SAVEPOINT);
Because these menu items map directly to key commands, you can change their functionality by writing an appropriate Key trigger. For example, you might want to change the default behavior of the Clear All menu item to roll back all changes in the session, including changes posted in calling forms. To do so, you could write the following KeyCLRFRM (clearform) trigger to cause a full rollback: KeyCLRFRM Trigger:
Clear_Form(NO_COMMIT,FULL_ROLLBACK);
Similarly, you can change the rollback mode for the Exit menu item to NO_ROLLBACK, so that changes posted in the current form are not rolled back on exit. To do so, write the following KeyExit trigger: KeyEXIT Trigger:
Exit_Form(ASK_COMMIT,NO_ROLLBACK);
MultipleForm Applications
5 19
Recall that Oracle Forms runs a called form in postonly mode when there are unposted changes in the calling form. Although postonly mode is useful in many applications, externalizing it to endusers can add complexity to your applications interface. For some applications, it may be better to prevent forms from running in postonly mode altogether. To do so, design the application so that changes are always explicitly posted before another form is called. To post changes in a form, execute the POST builtin procedure just prior to calling a form with the CALL_FORM or NEW_FORM procedure. For example, you can include the POST procedure in the menu item command or WhenButtonPressed trigger that calls the next form:
Post; IF (System.Form_Status <> QUERY) THEN Call_Form(form_B,NO_HIDE); END IF;
When changes are posted in the calling form, the called form does not run in postonly mode, and operators can issue a commit from the called form. The following steps illustrate this sequence, and show how posting allows a called form to commit changes that were made in the calling form: 1. 2. 3. 4. 5. 6. Update or delete records in Form A. Post in Form A. Call Form B. Insert, update, or delete records in Form B. Commit in Form B. (This commits the changes made in Form B and the posted changes in Form A.) Exit Form B.
5 20
In this example, posting is used to allow a calling form to commit changes that were posted in a called form. The called form is allowed to run in postonly mode, and any changes made in the called form are posted before returning to the calling form. The following steps illustrate this sequence: 1. 2. 3. 4. 5. 6. Update or delete records in Form A. Call Form B. (Form B is in postonly mode because changes were made in Form A that were not explicitly posted.) Insert, update, or delete records in Form B. Post in Form B. Exit Form B with NO_ROLLBACK parameter. Commit in Form A. (This commits changes made in Form A and changes posted in Form B.)
When Form B exits and returns control to Form A (step 5), the rollback mode is set to NO_ROLLBACK to preserve changes that were posted in Form B. Because the default rollback mode when exiting a form is TO_SAVEPOINT, you must explicitly override this functionality to avoid a rollback. For example, if the operator selects the Exit item on the default Action menu, changes made in the called form will be lost. To override the default Exit command, you might write the following trigger: KeyEXIT Trigger:
IF System.Form_Status = CHANGED THEN Post; END IF; Exit_Form(NO_COMMIT,NO_ROLLBACK);
This same technique can be used when you leave the current form by executing the NEW_FORM procedure rather than by calling EXIT_FORM.
IF System.Form_Status = CHANGED THEN Post; END IF; New_Form(NO_COMMIT,NO_ROLLBACK);
In this case, changes posted by the called form can then be committed by the new form that takes its place.
MultipleForm Applications
5 21
the name of the current form (CURRENT_FORM) the name of the form that called the current form. (CALLING_FORM). the username and password of the current operator (USERNAME, PASSWORD)
For example, to determine which form called the current form (with CALL_FORM), you could write the following code:
DECLARE parent_form CHAR(20) :=Get_Application_Property(CALLING_FORM); BEGIN IF parent_form = form_A THEN Post; Exit_Form(NO_COMMIT,NO_ROLLBACK); ELSE Commit_Form; Exit_Form; END IF; END;
returns NULL.
5 22
MultipleForm Applications
5 23
In this example, a parameter list named form_a_params is created and its object ID is assigned to a variable named the_list. A text parameter named p1 is then added to the list with ADD_PARAMETER, and its value is set to BICYCLE. Finally, the parameter list is passed to Form B as the last argument to the OPEN_FORM procedure. For this example to work, a form parameter named p1 must have been declared in Form B at design time, and its datatype and length must be compatible with the value being passed.
5 24
Parameter Validation
When you pass the Default parameter list to a form, remember that each parameter in the list must have been defined in that form at design time. Oracle Forms validates the individual parameters against the parameters defined in that form as follows:
Each parameter must have been defined in the called form at design time. If you pass a parameter list that includes an undefined parameter, the OPEN_FORM, CALL_FORM or NEW_FORM fails, and Oracle Forms issues error FRM47023: No
such parameter named <parameter name> exists in <form module name>.
The datatype and length of the parameter defined in the called form must be compatible with the parameter value being passed. (Values in a parameter list are untyped strings, whereas form parameters are declared as type CHAR, NUMBER, or DATE.) If the parameter is incompatible with the value, the OPEN_FORM, CALL_FORM, or NEW_FORM call fails, and Oracle Forms issues error FRM47024: Parameter <parameter name> type does
not match definition in <name of called form>.
You can modify the Default parameter list by adding and deleting parameters with the builtin procedures ADD_PARAMETER and DELETE_PARAMETER. To avoid a validation error, you can remove unwanted parameters from the list before passing it to a form. For example, if Form B requires only parameters p1 and p2, you could remove p3 from the list before passing the list to Form B.
DECLARE the_list PARAMLIST:= Get_Parameter_List(default); BEGIN Delete_Parameter(the_list, p3); Open_Form(form_B,ACTIVATE, NO_SESSION,default); END;
MultipleForm Applications
5 25
5 26
runs Form B with the menu that was attached to Form B at design time, rather than keeping the current menu.
MultipleForm Applications
5 27
procedure, the menu module attached to each form is loaded when that form is invoked. When all of the forms in an application share the same menu, reloading the same menu each time a new form is invoked (and potentially querying the database each time) may be unacceptable. To avoid this problem, create a startup form that exists only to call the frontend form (and its master menu) by executing CALL_FORM with the NO_REPLACE parameter. With this design, Oracle Forms does not reload the menu each time a different form is invoked from the main menu. Because the frontend form is itself a called form, any form modules invoked with the NEW_FORM procedure automatically inherit the NO_REPLACE restriction, and run under the master menu. Invoking Forms from a Master Menu with CALL_FORM When items on the master menu invoke forms with the CALL_FORM builtin procedure, you can specify whether called forms should inherit the master menu with the switch_menu parameter (DO_REPLACE or NO_REPLACE).
For example, to replace the current menu with a menu called my_new_menu you could write the following procedure call:
Replace_Menu(my_new_menu);
5 28
CHAPTER
About Mouse Events, Triggers, and System Variables 6 2 Performing Actions Based on the Mouse Button Pressed 6 4 Performing Actions Based on Mouse Location 6 5
61
operator presses the mouse down operator presses the mouse down and releases the mouse button operator clicks the mouse operator doubleclicks the mouse operator moves the mouse into a canvas or item operator moves the mouse out of a canvas or item operator moves the mouse
WhenMouseUp
WhenMouseClick
WhenMouseDoubleClick
WhenMouseEnter
62
Description Initiates an action when the operator moves the mouse out of an item or canvasview. Initiates an action when the operator moves the mouse within an item or canvasview.
63
The record number of the record the mouse is in. The offset from the first visible record that the mouse is in.
Note: Oracle Forms does not perform mouse navigation internally to fire the mouse triggers. As a result, mouse move, enter, and leave can fire on the noncurrent item, or on an item that does not contain a record (for example, the fifth record in a multirecord block which is in Enter Query mode).
Click Combined with Modifier Key To perform an action based on the modifier key pressed when the operator clicks the mouse, use the WhenMouseClick trigger in conjunction with the SYSTEM.BUTTON_SHIFT_STATE system variable.
64
Mouse Coordinates To initiate an action based on the current X and Y mouse coordinates, use a WhenMouseMove trigger in conjunction with the SYSTEM.MOUSE_X_POS and SYSTEM.MOUSE_Y_POS system variables. In the following example, the SYSTEM.MOUSE_X_POS and SYSTEM.MOUSE_Y_POS system variables are used within a WhenMouseClick trigger to dynamically reposition items.
DECLARE item_to_move VARCHAR(50); the_button_pressed VARCHAR(50); target_x_position VARCHAR(3); target_y_position VARCHAR(3); BEGIN /* ** Get the name of the item that was clicked. */ item_to_move := :System.Mouse_Item; the_button_pressed := :System.Mouse_Button_Pressed;
65
/* ** ** ** */
If the mouse was clicked on an area of a canvas that is not directly on top of another item, move the item to the new mouse location.
IF item_to_move IS NOT NULL AND the_button_pressed = 2 THEN target_x_position := :System.Mouse_X_Pos); target_y_position := :System.Mouse_Y_Pos); Set_Item_Property(item_to_move,position, target_x_position,target_y_position); target_x_position := NULL; target_y_position := NULL; item_to_move := NULL; END IF; END;
Mouse in Record To perform an action based on the record number the mouse is in, use WhenMouseMove or a WhenMouseClick trigger in conjunction with the SYSTEM.MOUSE_RECORD system variable. Mouse in Canvas To perform an action based on the canvas the mouse is in, use a WhenMouseMove or a WhenMouseClick trigger in conjunction with the SYSTEM.MOUSE_CANVAS system variable. In the following example, the SYSTEM.MOUSE_CANVAS system variable is used within a WhenMouse_Move trigger to determine which canvas the mouse is in.
DECLARE canvas_name VARCHAR(50); BEGIN canvas_name := :System.Mouse_Canvas; END;
To determine which window the mouse is in, add the following line to the example above:
window_name := :Get_View_Property(canvas_name,window_name);
66
CHAPTER
Using Timers
his chapter explains how to create and manipulate timers. It includes the following sections:
Using Timers
71
Creating Timers
A timer is an internal time clock that you programmatically create to perform an action each time the timer expires. Timer duration can be between 1 and 2,147,483,647 millisecond (1 second=1000 milliseconds). The maximum duration of a timer is approximately 24.85 days. When you work with timers you perform these steps: 1. 2. Using the CREATE_TIMER builtin subprogram, create the desired number of repeating or nonrepeating timers. Create a WhenTimerExpired trigger that performs the desired action whenever your timer expires.
where: timer_name Specifies the timer name of up to 30 alphanumeric characters. The name must begin with an alphabetic character. The datatype of the name is CHAR. Specifies the duration of the timer in milliseconds. The range of values allowed for this parameter is 1 to 2147483648 milliseconds. Values > 2147483648 will be rounded down to 2147483648. Note that only positive numbers are allowed. The datatype of the parameter is NUMBER. See Restrictions below for more information. Specifies whether the timer should repeat or not upon expiration. Takes the following constants as arguments: REPEAT Indicates that the timer should repeat upon expiration. Default. NO_REPEAT Indicates that the timer should not repeat upon expiration, but is to be used once only, until explicitly called again. Note: WhenTimerExpired is a formlevel trigger. It fires any time a timer expires. If your application contains several timers, your WhenTimerExpired trigger should contain code that will handle the different timers accordingly.
milliseconds
iterate
72
Example:
/* Create a repeating timer that expires every hour */ DECLARE hour_timer TIMER; one_hour NUMBER(7):=3600000; BEGIN hour_timer:= CREATE_TIMER(alarm,one_hour,REPEAT); END;
A WhenTimerExpired trigger cannot fire during transactions, trigger processing, navigation, etc. Thus, a WhenTimerExpired trigger only fires while Oracle Forms is waiting to accept user input. As a result, a timer may not expire exactly on the millisecond, but it will fire after the specified number of milliseconds.
By default, a timer repeats on expiration unless you specify NO_REPEAT. When a timer is created, Oracle Forms puts it on a queue. A WhenTimerExpired trigger will only fire once for each timer that is on the queue.
A repeating timer will not repeat while it is on the queue. It will begin repeating once it has been serviced off of the queue by a WhenTimerExpired trigger. Thus, only one instance of a timer may be placed on the expired timer queue at a time. If the operator exits an application prior to timer expiration, any timer on the queue will not be executed by the WhenTimerExpired trigger.
Using Timers
73
74
Note: You cannot change a timers name programmatically. You can use the SET_TIMER builtin subprogram to modify timer intervals and repeat parameters. For example:
/* ** Builtin: FIND_TIMER ** ** Example: If the timer exists, reset it. Otherwise create ** it. */ PROCEDURE Reset_Timer_Interval( Timer_Name VARCHAR2, Timer_Intv NUMBER ) IS tm_id Timer; tm_interval NUMBER; BEGIN /* ** User gives the interval in seconds, the timer routines ** expect milliseconds */ tm_interval := 1000 * Timer_Intv; /* Lookup the timer by name */ tm_id := Find_Timer(Timer_Name); /* If timer does not exist, create it */ IF Id_Null(tm_id) THEN tm_id := Create_Timer(Timer_Name,tm_interval,NO_REPEAT); /* ** Otherwise, just restart the timer with the new interval */ ELSE Set_Timer(tm_id,tm_interval,NO_REPEAT); END IF; END;
Using Timers
75
Deleting a Timer
You can delete repeating and nonrepeating timers by using the DELETE_TIMER builtin subprogram. You can use the FIND_TIMER and DELETE_TIMER builtin subprograms to find and delete any timer that is created during the current session. Example:
/* ** Builtin: DELETE_TIMER ** Example: Remove a timer after first checking to see if it ** exists */ PROCEDURE Cancel_Timer (tm_name VARCHAR2) IS tm_id TIMER; BEGIN tm_id:=Find_Timer(tm_name); IF NOT Id_Null(tm_id) THEN Delete_Timer(tm_id); ELSE Message(Timer || has already been cancelled.); END IF; END;
76
CHAPTER
About Integration with Other Oracle Tools 8 2 Calling Other Products from Oracle Forms 8 3 Passing Parameters to Other Products 8 5 Using Chart Items to Embed Oracle Graphics Displays 8 8 The OG Package 8 15 Invoking Forms from 3GL Programs 8 22
81
Pass command line parameters to the product. Pass text parameters to the product. Pass record groups to the product that can be used to satisfy named queries defined in the called product, thus eliminating or reducing the need for the called product to query records from the database itself.
When applicable, you can specify that the called product run in batch or runtime mode, and you can pass command line parameters to specify runtime options for the called product. Called products can either run in the background or be displayed alongside the form. For instance, when a form invokes Oracle Reports, the report can be displayed on the screen where it can be viewed by the operator, or it can be sent directly to a printer. Creating chart items in forms makes possible an additional level of integration between Oracle Forms and Oracle Graphics. A chart item is a special type of form item that is associated with a specific Oracle Graphics display (chart, graph, or other graphical display). Chart items can be updated dynamically when required by the application. When you use chart items, Oracle Forms can pass data to Oracle Graphics for use in constructing the display, or Oracle Graphics itself can query the data required. Once Oracle Graphics creates the display, Oracle Graphics passes the display to Oracle Forms to be displayed in the form interface. Another option for integration between Oracle Forms and Oracle Graphics is OLE2 container support. Oracle Graphics is an OLE2 server application that can be linked or embedded in a custom OLE item in a form. Note, however, that OLE container functionality is supported only on MS Windows, whereas chart item integration, which relies on the Oracle Tools integration system, is fully portable, and also allows for bidirectional data passing.
82
For example, to invoke Oracle Reports, you could make the following call:
Run_Product(REPORTS,stats,ASYNCHRONOUS,BATCH,FILESYSTEM);
By default, when you invoke Oracle Reports or Oracle Graphics with RUN_PRODUCT, the called product logs on to ORACLE using the current form operators USERID. Oracle Forms uses the parameters you pass to RUN_PRODUCT to construct a valid command line invocation of the called product. RUN_PRODUCT takes the following parameters: Product A numeric constant that specifies the Oracle tool to be invoked: FORMS, REPORTS, GRAPHICS, or BOOK. Document Specifies the document or module to be opened by the called product. Commmode Specifies the communication mode to be used when running the called product. Valid numeric constants for this parameter are SYNCHRONOUS and ASYNCHRONOUS.
SYNCHRONOUS specifies that control returns to Oracle Forms only after the called product has been exited. The operator cannot work in the form while the called product is running. Synchronous is required when passing a record group to a called product as a DATA_PARAMETER; for example, when invoking Oracle Graphics to return an Oracle Graphics display that will appear in a form chart item. ASYNCHRONOUS specifies that control returns to the calling application immediately, even if the called application has not completed its display. Do not use ASYNCHRONOUS when passing a record group to a called product as a DATA_PARAMETER; for example, when invoking Oracle Graphics to return an Oracle Graphics display that will appear in a form chart item.
Execmode Specifies the execution mode to be used when running the called product, either BATCH or RUNTIME. When you run Oracle Reports and Oracle Graphics, execmode can be either BATCH or
83
RUNTIME. When you run Oracle Forms, always set execmode to RUNTIME. Location Specifies the location of the document or module you want the called product to execute, either the file system or the database. List Specifies the name or ID of a parameter list to be passed to the called product. Display Specifies the name of the Oracle Forms chart item that will contain the display generated by Oracle Graphics. For more information, refer to the description of RUN_PRODUCT in the Oracle Forms Reference Manual, Vol. 1.
Note: A separate logon is always required if the Oracle Graphics display executes Data Manipulation Language (DML) commands against the database.
84
a command line parameter to be used by the called product at startup; for example, a value for the RUNREP command line parameter DESTYPE, which indicates the display destination for the report a userdefined parameter defined in Oracle Reports or Oracle Graphics; for example, a value for a department number parameter required by a report a bind or lexical reference defined in Oracle Reports or Oracle Graphics; for example, a value for the bind reference :SALARY, or a value for the lexical reference &MINTOTAL
The value of a data parameter is always the name of a record group defined in the current form. When Oracle Forms passes a data parameter to Oracle Reports or Oracle Graphics, the data in the
85
specified record group can substitute for a query that Oracle Reports or Oracle Graphics would ordinarily execute to run the report or display. Note: Passing data parameters is not supported when invoking Oracle Forms from Oracle Forms.
execute the CREATE_PARAMETER_LIST builtin function to programmatically create a parameter list execute the ADD_PARAMETER builtin procedure to add one or more parameters to the parameter list, specifying the key, type, and value for each parameter being added execute the RUN_PRODUCT builtin procedure and include the ID or name of the parameter list to be passed to the called product
For more information on parameters and parameter lists, see Chapter 16, Defining Form Parameters. The following example illustrates these steps by creating a parameter list to be passed to Oracle Reports when running a report called Daily_Sums.
/* Declare an appropriately typed variable to store ** the parameter list ID */ DECLARE list_id ParamList; BEGIN /* Create a parameter list named input_params */ list_id := Create_Parameter_List(input_params); /* Add two parameters to the list that pass values ** for RUNREP command line parameters; for each parameter ** specify its key, type (text or data), and value */ Add_Parameter(list_id,DESTYPE,TEXT_PARAMETER,PRINTER); Add_Parameter(list_id,DESNAME,TEXT_PARAMETER,PS_3);
86
/* Now run the report, referencing the parameter list ID ** in the last argument to the RUN_PRODUCT procedure */ Run_Product(REPORTS,daily_sums,SYNCHRONOUS,RUNTIME, FILESYSTEM,list_id); END;
Parameter Attributes When you add call ADD_PARAMETER to add a parameter to a parameter list, you specify three attributes: key paramtype value The name of the parameter. The parameter type, either DATA_PARAMETER or TEXT_PARAMETER. The parameter value. For a TEXT_PARAMETER, the value is any CHAR value. For a DATA_PARAMETER, the value is always the CHAR name of a record group defined in the current form.
Parameter Associations When you execute the RUN_PRODUCT procedure and pass a parameter list to another product, Oracle Forms uses the parameters in the list to construct a valid command line invocation for the called product. Any text parameters in the list are interpreted as either predefined command line parameters, or as userdefined bind or lexical parameters. Similarly, any data parameters are understood to map directly to named queries in Oracle Reports or Oracle Graphics. When you pass a parameter to a called product, the parameter key (that is, the name of the parameter) must be the same as the name of the corresponding parameter or query in the called product:
When passing a value for a command line option, the text parameter key must be the same as the command line keyword (DESTYPE or COPIES). When passing a value for a bind or lexical reference, the text parameter key must be the same as the name of the bind or lexical reference. When passing data, the data parameter key must have the same name as the query defined in the called product.
There can be any number of text and/or data parameters in a parameter list. For example, a form can pass data parameters for any number of named queries defined in a single report or display. Note: When you use RUN_PRODUCT to invoke Oracle Reports, DATA_PARAMETERs can be passed only to master queries. Passing DATA_PARAMETERs to child queries is not supported.
87
Note: Passing DATA_PARAMETERs is not supported when invoking Oracle Forms from Oracle Forms with RUN_PRODUCT.
4.
Pass text parameters or data parameters from the form to Oracle Graphics that Oracle Graphics can use to update the display. Pass text parameters or data parameters from Oracle Graphics to Oracle Forms. Write mouse event triggers to pass mouse events from Oracle Forms to Oracle Graphics. Oracle Graphics can then update the display in the chart item, just as it would in Oracle Graphics runtime. Control the display from Oracle Forms by calling Oracle Graphics procedures from within form triggers.
88
You can use the services in the special OG package to create dynamic Oracle Graphics displays. The OG package is defined in the OG.PLL library, which is delivered as part of your Oracle Forms installation. To call subprograms in the OG package, you need to attach the OG.PLL library to your form. OG contains the following subprograms:
When you create a chart item, consider the size of the display in Oracle Graphics and the size of the chart item in the form. When you display a chart item with RUN_PRODUCT, the display is scaled to fit the dimensions of the chart item. If the chart item is smaller than the actual display size, some distortion may occur. When you populate a chart item with OG.OPEN, you can specify whether the display should be
89
scaled to fit, or should retain its actual dimensions and be clipped if necessary. Fonts, colors, and patterns used to create the display in Oracle Graphics are matched as closely as possible to the attributes available on the runtime system. You can create chart items in both single and multirecord blocks. When you use a chart in a multirecord block, you must execute a separate RUN_PRODUCT, OG.OPEN, or OG.REFRESH call for each record, that is, for each instance of the chart item. For example, you might create a multirecord base table block with a chart item that displays a graph based on the data in each record. You can build such a form using a blocklevel PostQuery trigger that executes a RUN_PRODUCT call for each record retrieved by the query. (PostQuery fires once for each record retrieved by a query.)
8 10
Each of these procedures takes a parameter list ID as its final argument. Thus, any time you call these procedures in a form you have the option to send the Oracle Graphics display text or data parameters. The following example shows two ways to pass parameters when populating a chart item with an Oracle Graphics display. This example demonstrates passing parameters with RUN_PRODUCT. First, a display called sal_chart is created in Oracle Graphics that compares the salaries paid to managers and line employees in a given department. A query was defined in Oracle Graphics that accepts a parameter dept_num that defines the department number to be used in the WHERE clause of the query. In the form, the designer created a singlerecord block based on the DEPT table, then added a chart item to the block called chart_item. A WhenNewFormInstance trigger was defined that executes the following call at form startup:
Og.Open(sal_chart,dept.chart_item);
The OPEN procedure starts Oracle Graphics in batch mode and associates the display sal_chart with the chart item dept.chart_item. When the form operator queries a department record into the form, the chart item displays the pie chart showing the salary breakdown for employees in that department. There are two ways to implement this functionality:
Pass a text parameter. The form passes Oracle Graphics a parameter with a value for the dept_num parameter that was defined in the display; Oracle Graphics then uses that value to execute the query, builds the display, and passes it to the form chart item.
Pass a data parameter. The form programmatically creates and populates a query record group, then passes the resulting record set to Oracle Graphics as a data parameter. The data queried by the form satisfies the named query defined in the sal_chart display. Oracle Graphics uses the data to build the display (without querying the database), then populates the form chart item.
8 11
Passing a Text Parameter The following sample code shows the text of a blocklevel PostQuery trigger that might be used to pass a department number to Oracle Graphics for use in constructing the sal_chart display.
PROCEDURE pass_param IS pl_id ParamList; BEGIN /* Create a parameter list for data passing */ pl_id := Create_Parameter_List(my_param_list); /* Add a text parameter to the list to supply a value for the ** dept_num parameter that Oracle Graphics is expecting */ Add_Parameter(pl, dept_num, TEXT_PARAMETER, TO_CHAR(:dept.deptno)); /* Call Oracle Graphics to populate the chart item */ Og.Refresh(sal_chart,dept.chart_item,pl); /* Get rid of the parameter list */ Destroy_Parameter_List(pl); END;
Passing a Data Parameter The following sample code shows the text of a blocklevel PostQuery trigger that might be used to pass data records to Oracle Graphics. In this example, Oracle Forms issues a query and stores the resulting data in a record group. A data parameter is then passed to Oracle Forms that references the record group, and Oracle Graphics uses the data to construct the sal_chart display.
PROCEDURE pass_data IS val CHAR(20) := chart_data; Name of Record Group in form pl ParamList; rg RecordGroup; qry VARCHAR(2000); stat NUMBER; BEGIN /* Prepare a query in a string */ qry := SELECT empno, sal FROM emp WHERE deptno=|| To_Char(:dept.deptno); /* Try to get the ID of the chart_data record group */ rg := Find_Group(chart_data); /* If it doesnt exist, create the group based on the ** query in the qry string
8 12
*/ IF Id_Null(rg) THEN rg := Create_Group_From_Query(chart_data,qry); END IF; /* Make sure the chart_data record group is empty */ Delete_Group_Row(rg, ALL_ROWS); /* Populate the chart_data record group with the query ** in the qry string */ stat := Populate_Group_With_Query(rg,qry); /* Create a parameter list for data passing */ pl := Create_Parameter_List(foo); /* Add a data parameter to the parameter list to ** specify the relationship between the named query ** query0 in the Oracle Graphics display and the named ** record group in the form, chart_data. */ Add_Parameter(pl,query0, DATA_PARAMETER,val); /* Invoke Oracle Graphics to create the chart Og.Refresh(sal_chart,dept.chart_item,pl); /* ** Get rid of the parameter list */ Destroy_Parameter_List(pl); END; */
8 13
Once you build the display, you can create the chart item in Oracle Forms, and then do the following:
Write a trigger that calls the OG.OPEN packaged procedure to open the display and prepare it to receive mouse events. (When you use OG.OPEN, you do not need to call RUN_PRODUCT to initialize Oracle Graphics.)
OG.Open(map,blk3.chart_item);
If you want the display to be visible at form startup, you would typically call OG.OPEN in a WhenNewFormInstance or PreForm trigger. The display would then be able to receive mouse events immediately. After that, whenever you wanted Oracle Graphics to update the chart item, you could call OG.REFRESH, passing new parameters or data as needed. If you wanted to defer populating the chart item until some event occurred, such as the operator executing a query in the form, you might wait to call OG.OPEN until the appropriate event trigger fired, such as PostQuery or WhenButtonPressed.
Write the appropriate mouse event trigger to respond to mouse events in the chart item. Oracle Forms includes a set of mouse event triggers that fire in response to mouse events, including mouse events that happen in a chart item. To notify Oracle Graphics that a mouse event has occurred in a chart item, you need to write an Oracle Forms mouse trigger that calls either the OG.MOUSEDOWN or OG.MOUSEUP packaged procedures. These procedures notify Oracle Graphics that a mouse event occurred, and pass the X,Y coordinates of the click on the display.
8 14
The OG Package
The OG package provides a set of PL/SQL subprograms that you can use when you are embedding Oracle Graphics displays in Oracle Forms chart items. The services in the OG package are based on the portable Oracle Tools integration mechanism, and allow you to create dynamic chart displays in a form. The OG package is defined in the OG.PLL library, which is delivered as part of your Oracle Forms installation. To call subprograms defined in the OG package, you need to attach the OG.PLL library to your form. For information on attaching libraries, refer to the Oracle Forms Developers Guide, Chapter 20, Working with Libraries.
OG.CLOSE
Syntax: Builtin Type: Description: Parameters:
OG.CLOSE(display,item);
procedure Closes the indicated Oracle Graphics display. display item The CHAR name of the display. The CHAR name of the chart item with which the display is associated.
Example:
OG.Close(totals.ogd,blk3.chart_item);
OG.GETCHARPARAM
Syntax: Builtin Type: Returns: Description:
OG.GETCHARPARAM( display,item,param );
Function VARCHAR2 Returns the current value for the indicated Oracle Graphics CHAR parameter. display item param The CHAR name of the display. The CHAR name of the chart item with which the display is associated. The name of the parameter whose value you want to examine.
Parameters:
Example:
8 15
OG.GETNUMPARAM
Syntax: Builtin Type: Returns: Description:
OG.GETNUMPARAM( display,item,param );
Function NUMBER Returns the current value for the indicated Oracle Graphics NUMBER parameter. display item param The CHAR name of the display. The CHAR name of the chart item with which the display is associated. The name of the parameter whose value you want to examine.
Parameters:
Example:
OG.INTERPRET
Syntax:
OG.INTERPRET( display,item,pls_string) ; OG.INTERPRET( display,item,pls_string,refresh ); OG.INTERPRET( display,item,pls_string,refresh,plist );
Description:
Instructs Oracle Graphics to execute the indicated PL/SQL statement for the indicated display. The PL/SQL statement can include calls to Oracle Graphics builtin and usernamed subprograms, as well as anonymous blocks of PL/SQL code. procedure display item pls_string The CHAR name of the display. The CHAR name of the chart item with which the display is associated. The PL/SQL statements to execute (type CHAR). Include the trailing semicolon as required. If you are issuing more than one statement at a time, include the appropriate DECLARE, BEGIN, and END keywords. Optional BOOLEAN parameter that specifies whether the chart item display should be updated
refresh
8 16
after the PL/SQL statement executes in Oracle Graphics. Set to TRUE or FALSE. (Default=TRUE.) plist Optional; specifies the ID of a parameter list to be passed to Oracle Graphics. Use a variable of type PARAMLIST. (Default=TOOLS.null_parameter_ list.)
Example:
OG.MOUSEDOWN
Syntax:
OG.MOUSEDOWN( display,item); OG.MOUSEDOWN( display,item,x,y ); OG.MOUSEDOWN( display,item,x,y,refres h); OG.MOUSEDOWN( display,item,x,y,refresh,clickcount ); OG.MOUSEDOWN( display,item,x,y,refresh,clickcount,button ); OG.MOUSEDOWN( display,item,x,y,refresh,clickcount,button, constrained); OG.MOUSEDOWN( display,item,x,y,refresh,clickcount,button, constrained,plist);
procedure Passes a mouse down event from Oracle Forms to the Oracle Graphics display associated with the indicated chart item. MOUSEDOWN is typically called from a WhenMouseDown or WhenMouseClick trigger attached to the chart item in Oracle Forms. When a mouse down event is passed from the form to the display, Oracle Graphics responds just as it would if the mouse down had occurred in Oracle Graphics runtime. By default, OG.MOUSEDOWN passes Oracle Graphics the X,Y display coordinates of the mouse down event. Specifying these parameters explicitly is necessary only if you want to override the actual coordinates.
Parameters:
display item x
The CHAR name of the display. The CHAR name of the chart item with which the display is associated. Optional; specifies the X NUMBER coordinate at which Oracle Graphics should interpret the mouse click to have occurred. (Default=The actual X coordinate of the mouse down event.)
8 17
Optional; specifies the Y NUMBER coordinate at which Oracle Graphics should interpret the mouse click to have occurred. (Default=The actual Y coordinate of the mouse down event.) Optional; specifies whether Oracle Graphics should update the chart item display. Set to TRUE or FALSE. (Default=TRUE) Optional; specifies a NUMBER counter for mouse down events that occur as part of a sequence of mouse events. For example, a doubleclick event includes a mouse down (count 1), a mouse up, a second mouse down (count 2), and a second mouse up. (Default=The actual clickcount.) Optional; specifies a NUMBER corresponding to the mouse button that Oracle Graphics should interpret as having been pressed for the mouse event. (Default=The actual button that was pressed. ) Optional; specifies whether the mouse click should be interpreted as having occurred while the SHIFT key was pressed. Set to TRUE or FALSE. (Default=FALSE) Optional; specifies the ID of a parameter list to be passed to Oracle Graphics. Use a variable of type PARAMLIST. (Default=TOOLS.null_parameter_ list.)
refresh
clickcount
button
constrained
plist
OG.MOUSEUP
Syntax:
OG.MOUSEUP(display,item); OG.MOUSEUP(display,item,x,y ); OG.MOUSEUP(display,item,x,y,refresh ); OG.MOUSEUP(display,item,x,y,refresh,button ); OG.MOUSEUP(display,item,x,y,refresh,button,constrained ); OG.MOUSEUP(display,item,x,y,refresh,button,constrained,plist );
procedure Passes a mouse up event from Oracle Forms to the Oracle Graphics display associated with the indicated chart item. MOUSEUP is typically called from a WhenMouseUp or WhenMouseClick trigger attached to the chart item in Oracle Forms. When a mouse up event is
8 18
passed from the form to the display, Oracle Graphics responds just as it would if the mouse up had occurred in Oracle Graphics runtime. By default, OG.MOUSEUP passes Oracle Graphics the X,Y display coordinates of the mouse up event. Specifying these parameters explicitly is necessary only if you want to override the actual coordinates. Parameters: display item x The CHAR name of the display. The CHAR name of the chart item with which the display is associated. Optional; specifies the X NUMBER coordinate at which Oracle Graphics should interpret the mouse click to have occurred. (Default=The actual X coordinate of the mouse up event.) Optional; specifies the Y NUMBER coordinate at which Oracle Graphics should interpret the mouse click to have occurred. (Default=The actual Y coordinate of the mouse up event.) Optional; specifies whether Oracle Graphics should update the chart item display. Set to TRUE or FALSE. (Default=TRUE) Optional; specifies a NUMBER corresponding to the mouse button that Oracle Graphics should interpret as having been pressed for the mouse event. (Default=The actual button that was pressed.) Optional; specifies whether the mouse click should be interpreted as having occurred while the SHIFT key was pressed. Set to TRUE or FALSE. (Default=FALSE) Optional; specifies the ID of a parameter list to be passed to Oracle Graphics. Use a variable of type PARAMLIST. (Default=TOOLS.null_parameter_ list.)
refresh
button
constrained
plist
8 19
OG.OPEN
Syntax:
OG.OPEN(display,item); OG.OPEN(display,item,clip ); OG.OPEN(display,item,clip,refresh ); OG.OPEN(display,item,clip,refresh,plist );
procedure Activates the indicated Oracle Graphics display associated with the indicated chart item. The OPEN procedure includes a call to the builtin RUN_PRODUCT, but also allows you to specify additional parameters to control how Oracle Graphics should be activated. OPEN is typically called in a WhenNewFormInstance trigger to initialize a graphics display at form startup. display item clip The CHAR name of the display. The CHAR name of the chart item with which the display is associated. Optional BOOLEAN parameter that specifies whether Oracle Graphics should scale the chart display to fit the dimensions of the chart item, or use the default display size, cropping the display as needed to fit the chart item. Set to TRUE or FALSE. (Default=TRUE) Optional BOOLEAN parameter that specifies whether the chart item display should be updated. Optional; specifies the ID of a parameter list to be passed to Oracle Graphics. Use a variable of type PARAMLIST. (Default=TOOLS.null_parameter_ list.)
Parameters:
refresh plist
Example:
OG.Open(shop.ogd,control.chart2);
8 20
OG.REFRESH
Syntax: Builtin Type: Description:
OG.REFRESH(display,item); OG.REFRESH(display,item,plist );
procedure Causes Oracle Graphics to update the bitmap display for the indicated chart item. Use OG.REFRESH to pass new parameters or data to Oracle Graphics to use to update a display for a chart item. To call OG.REFRESH successfully, Oracle Graphics must already have been initialized through a call to OG.OPEN. display item plist The CHAR name of the display. The CHAR name of the chart item with which the display is associated. Optional; specifies the ID of a parameter list to be passed to Oracle Graphics. Use a variable of type PARAMLIST. (Default=TOOLS.null_parameter_ list.)
Parameters:
8 21
where command_line specifies the Oracle Forms Runform command line, and command_length specifies the number of characters in command_line. The following IFZCAL statement runs the ORDER_ENTRY form in debug mode with the SCOTT username:
ifzcal(f40run order_entry scott/tiger debug=YES,40);
Note: If the operator is not logged into ORACLE and the command line does not invoke the Oracle Forms Login screen, Oracle Forms uses the userid provided in the IFZCAL call. If the command line does not provide a userid, Oracle Forms uses any existing OPS$ login. If the command line provides neither a userid nor an OPS$ login, the Logon screen displays. If the operator is not logged on to ORACLE and the command line invokes the the Oracle Forms Logon screen (logon_screen=YES), Oracle Forms displays the Logon screen. If the command line provides an OPS$ login, Oracle Forms uses that logon and ignores any operator entry. If the command line does provide an OPS$ login, Oracle Forms uses the userid provided by the operator. If the operator is logged into ORACLE and the command line does not invoke the Logon screen, Oracle Forms uses the existing connection even if a userid is specified on the command line. If the command line invokes the Logon screen in this case, Oracle Forms ignores any entries by the operator. Restrictions: Do not use IFZCAL in a user exit. Doing so can ruin data structures. To invoke additional forms when Runform is already running, use OPEN_FORM or CALL_FORM.
8 22
CHAPTER
About Portability 9 2 Planning 9 3 The Porting Process 9 4 Setting Standards 9 5 Choosing a Form Coordinate System 9 6 Using Colors 9 7 Choosing Fonts 9 8 Using Icons 9 10 Setting Window Size 9 10 Form Functionality 9 11 CharacterMode Considerations 9 12
91
About Portability
Portability is the quest for uniformity in a diverse environment. Ideally, portability means:
You can develop an application on one platform, such as a UNIX workstation, and You can run the application transparently (without changes) on multiple other platforms, such as MS Windows and Macintosh.
In reality, the different ways that various platforms and windowing systems implement the basics that provide their distinctive look and feel mean that the distinguishing characteristics of one user interface may appear differently on another user interface. For example, the placement and presentation of the Help menu is different on MS Windows, Macintosh, and Motif. Portability includes:
Platform portability: the ability to develop and deploy on different platforms. Example: Develop on UNIX, deploy on MS Windows and Macintosh.
Device portability (including variations in screen size and resolution, as well as monochrome/color differences): the ability to develop and deploy on the same platform, but different devices. Example: Develop on MS Windows, deploy on both MS Windows large screen, high resolution and MS Windows small screen, low resolution.
UI portability: the ability to deploy the same application on GUI and charactermode devices. Example: Develop on MS Windows, deploy on MS Windows and a VT220.
92
Planning
A major goal in planning for portability is to anticipate the kinds of user interfaces on which your system will be deployed over time. Although this information can be difficult to obtain in advance, you may find it worthwhile to consider these questions:
On which platform do you currently develop applications? Are you planning to migrate to a different development platform? What platform do your forms operators currently use? Are there plans to migrate to another range of deployment interfaces?
Forms developers using Motif on large color monitors. Sales staff using smallscreen MS Windows laptops in the field. Forms operators using MS Windows on largescreen monochrome monitors.
To help you plan for developing crossplatform applications, obtain the platformspecific Installation Guide for each platform youre using.
93
94
Setting Standards
One common approach to designing crossplatform applications is to start by creating and then refining standards, based on prototyping efforts and usability testing. Because each companys requirements are unique, the best standards for your company will also be unique. Consider developing three types of standards:
Coding standards, including naming standards for all objects and files. GUI standards, including standards for screen appearance, such as color, spacing and layout, as well as standards for specific GUI objects, such as buttons and check boxes. Usage standards, including lookandfeel standards that ensure that various parts of the application react to user input in the same way.
MS Windows: The Windows Interface: An Application Design Guide Motif: Motif Style Guide Macintosh: Macintosh Human Interface Guidelines
Template Forms
In addition to creating a standards document, you may also want to embody the standards in a template form. Then, instead of starting a new form, developers open the template form and save it under a new name. The template form provides a starting point so applications can be developed according to the standards. Template forms include anything that may be used across all forms in an application:
object groups property classes toolbars libraries that include shareable prewritten, pretested subroutines, such as calculations, validations, and utility routines
95
96
Using Colors
Because your users spend a significant amount of each day using the screens you design, you may want to consult with a human factors engineer for help with choosing colors that are both easy to use and aesthetically pleasing. Research shows that black text on various lightcolored backgrounds provides the most contrast for users. You may want to choose three separate light background colors to signal three categories of information, such as the main window, popup windows, and small objects such as buttons and LOVs. To ensure crossplatform consistency, you will want to test the colors you choose to be sure they are effective on all platforms. Color coding of fields is only useful if the user is trained in the meaning of the colors, and uses a monitor that can render them accurately. To avoid problems with monochrome and character mode terminals:
Test each color and color combination to make sure that all widgets and labels are visible on both color and monochrome monitors. Use color redundantly: Color should never be the only cue to a specific meaning. For example, in an accounting application, negative amounts might be shown in red, but they should also be preceded by a minus sign.
Limiting the use of color is essential for portability. Keep in mind the characteristics of the monitors used to run an application. Code to the lowest common denominator for size, resolution, depth, and color.
A 4bit VGA monitor will limit your selection of color. MS Windows GUI objects can use only one of 16 colors, so even though Oracle Forms provides a 256color palette, if you want the background of items like checkboxes to be the same color as the canvas, choose the canvas color from the MS Windows 16color palette. If your application must run on both color and monochrome monitors, use a monochromatic color scheme, with a color palette such as black, white, light grey, and dark blue.
Another approach is to start with one master template containing all the application libraries, any standard referenced objects, and the standard color palette. By using this template as a starting point (use Save As to give each individual form a new name), each form will include the standard color palette.
97
Choosing Fonts
When you develop portable applications, you will want to pay particular attention to your choice of fonts, for both text items and boilerplate items. Check first for availability of the font you plan to use. Is it available on all the platforms youre using? Then test your font choices on each platform. Even fonts with the same name can have a different appearance on different platforms. For a polished appearance, youll want to choose the font that looks best on each platform. Use font aliasing to specify font mapping when porting an application from one platform to another. In the past, many portable applications used Courier, a nonproportional font. However, using Courier has several disadvantages:
Courier is not available on all platforms (only Geneva and Chicago are required on Macintosh). GUI users may expect proportional fonts and reject nonproportional fonts.
Tip: Remember that using named Visual Attributes to set defaults such as font and color so that theyll change from platform to platform works only for Oracle Forms objects. Boilerplate text, however, remains static. To specify crossplatform font substitution, use font aliasing. (Use named Visual Attributes to change colors dynamically at runtime.)
98
Font Aliasing
Font aliasing lets you use the uifont.ali file to specify what crossplatform font substitution you prefer. Each platform will have a separate uifont.ali file to define font substitution. Example 1: You develop on MS Windows using the MS Sans Serif font. To run on UNIX, add this line to your font alias file :
MS Sans Serif=Helvetica
Example 2: You develop on UNIX using the Helvetica font. To run on MS Windows, add this line to your font alias file :
Helvetica=MS Sans Serif
Example 3: You develop on UNIX using the Helvetica font. To run on Macintosh, add this line to your font alias file :
Helvetica=Geneva
For more information on font aliasing, refer to your platformspecific Installation Guide.
99
Using Icons
Icons can be used to identify windows, menu items, and buttons. While icons are an essential part of GUI design, they are not inherently portable, so if you are developing crossplatform applications, you will want to limit the number of icons.
Icon files are not portable, so you will need a complete set of icon files for each platform. Image size for all bitmaps must be designed to accommodate the lowest resolution on the platform. For example, a PC with VGA resolution will allow fewer pixels for rendering than a PC with SVGA resolution, so developing in VGA and porting to SVGA will work better than developing in SVGA and porting to VGA. Icons will need to be tested on a platformbyplatform basis.
Applications that must run in character mode should be designed to support a grid of 80 x 22 cells, plus 2 lines for the console (message and status area). To avoid scrolling, applications that must run on VGA and SVGA monitors must fit within their respective window size constraints.
9 10
Form Functionality
When youre building portable applications, you may want to use the GET_APPLICATION_PROPERTY builtin to return the following values:
For example, you could use Get_Application_Property (OPERATING_SYSTEM) to obtain the name of the platform this application runs on. Then you could use WhenNewFormInstance to set properties appropriate for the current platform before the form is used.
Recommendations
To implement portable form functionality, consider the following recommendations:
To call Oracle Reports, Oracle Graphics, and Oracle Book, use RUN_PRODUCT. (Use the HOST builtin only for calling other external applications.) Avoid user exits, which must be rewritten or at least recompiled for each platform. Isolate platformspecific functionality: MS Windows: DDE, OLE, and VBX. Macintosh: AppleEvents.
Be aware of differences in Macintosh functionality: Only text items are navigable, other items (such as buttons) are not navigable. Text item beveling does not apply (raised and lowered beveling looks the same).
9 11
CharacterMode Considerations
Porting to character mode platforms requires attention to both font and functionality issues:
Work within limitations caused by differences between proportional and nonproportional fonts. Use widget mnemonics to substitute for using the mouse to press buttons, check boxes, and radio buttons (for example, use AltP to press a Print button).
For more information, see the Oracle Forms Reference Manual, Vol. 2, App. A, Compatibility with Prior Versions, under Migration Strategies.
9 12
9 13
Help Hint (Menu Item) Identification Size Visual Attribute Type: Character Mode Logical Attribute
9 14
CHAPTER
10
About OLE 10 2 About OLE Objects 10 3 About OLE Servers and OLE Containers 10 4 About the Registration Database 10 4 About OLE Object Activation Styles 10 5 About OLE Automation 10 7 When to Embed and Link OLE Objects 10 7 OLE in Oracle Forms 10 8 Using OLE in the Oracle Forms Designer 10 9 Using OLE in Oracle Forms at Runtime 10 11 Creating an OLE Container in Oracle Forms 10 12 Linking and Embedding OLE Objects 10 13 Displaying OLE Objects 10 15 Editing OLE Objects 10 17 Converting OLE Objects 10 20
10 1
About OLE
Oracle Forms supports Object Linking and Embedding(OLE) on the Microsoft Windows and Macintosh platforms. OLE provides you with the capability to integrate objects from many application programs into a single compound document. Compound documents enable you to use the features from multiple application programs. An OLE server application creates OLE objects that are embedded or linked in an OLE container application; OLE containers store and display OLE objects. Applications can be OLE server applications, OLE container applications, or both. Oracle Forms is an OLE container application, and Oracle Graphics and Microsoft Word are examples of OLE server applications. An OLE object is embedded or linked in an OLE container, an item in Oracle Forms. In Oracle Forms, embedded objects become part of the form module, and linked objects are references from a form module to a linked source file. You can modify OLE objects by activating them. Activating an OLE object provides you access to features from the OLE server application that originated the OLE object. Embedded objects can be activated with inplace activation or external activation. Linked objects can only be activated with external activation. OLE server applications can create many object classes. The object classes that an OLE server can create are installed in a registration database. If a registration database does not already exist, one is created during installation of an OLE server application. The registration database contains the object classes that are valid for embedding and linking into an OLE container in a form module. For instance, Microsoft Word classes include MS Word 6.0 Document, MS Word 6.0 Picture, and MS WordArt 2.0.
10 2
Embedded Objects
An embedded OLE object is created by an OLE server application and is embedded in an Oracle Forms form module. An embedded object is stored as part of a form module or as a LONG RAW column in a database. Embedded objects can be queried as OLE container items. An example of object embedding is to insert a spreadsheet in an OLE container of a form module. The spreadsheet is stored as part of the form module or as a LONG RAW column in a database; there is no separate source file containing the spreadsheet.
Linked Objects
A linked OLE is created by an OLE server application. A linked object is stored in a separate source file that is created from an OLE server application. An image representation of the linked object and the information about the location of the linked objects source file is stored in a form module or as a LONG RAW column in a database. The content of the linked object is not stored as part of a form module or as a LONG RAW column in a database; it is retained in a separate file known as the linked source file. An example of object linking is to link a word processor document in a form module. An image of the document appears in the OLE container of the form module and the location of the document is stored as part of the form module or as a LONG RAW column in a database.
10 3
10 4
Inplace Activation
Inplace activation occurs when an OLE container and its embedded object remain in place when activated; Oracle Forms remains surrounding the OLE container. Inplace activation is available for embedded objects, but it is not available for linked objects.
When an object is activated, the object appears inside a hatched border. To deactivate inplace activation, click anywhere outside the hatched border. During inplace activation, some menu options of the OLE server application replace Oracle Forms menu options. If the window
10 5
containing the OLE container has a toolbar, inplace activation also replaces the Oracle Forms toolbar with the OLE server application toolbar. Replacing menu options and toolbars provide access to features that are available from the OLE server application. Oracle Forms menu options and toolbars reappear when you deactivate inplace activation.
External Activation
External activation occurs when an OLE object appears in a separate window that is opened by an objects originating OLE server application. Because an OLE server application starts up with its own windows, Oracle Forms menu options and toolbars remain intact during external activation. External activation is available for both embedded and linked objects.
When an OLE object is activated, the objects originating OLE server application is launched, and the OLE object appears in a separate OLE server application window. The separate window has the menu options and toolbars of the OLE server application. To deactivate external activation, you must explicitly exit the OLE server application. When the contents of a linked source file is modified with external activation, a linked object can be updated manually or automatically. Manual updates require an explicit instruction for an object to reflect changes from a linked source file. Automatic updates occur as soon as you modify a linked source file.
10 6
The object that you are embedding does not have to be the most current version of data because updating is performed from within a form module instead of a standalone document. The object does not need to be included in more than one document, so that changes are only necessary in the object embedded in the form module and nowhere else. The source document cannot be accessed if the object is linked. In this case, only a single form module needs to be maintained and not a form module in addition to the source document. The form module size is not a concern, because with embedding, the size of the form module increases by approximately the size of the embedded object.
10 7
The object that you are linking has to be the most current version of data because updating is performed from outside a form module on a standalone document. The object needs to be included in more than one document, so that changes affect multiple form modules and other documents. The source document can always be accessed if the object is linked. The form module size is a concern: Linking, unlike embedding, does not increase the size of the form module by the size of the object.
Embedding and linking of OLE server objects into Oracle Forms OLE containers. Inplace activation of embedded contents in Oracle Forms OLE containers. Programmatic access to OLE objects, properties, and methods through OLE automation support from PL/SQL. Seamless storage of OLE objects in a database in LONG RAW columns.
An OLE container is an item in Oracle Forms. An OLE object is linked or embedded into an OLE container. OLE objects can be base table items or control items. Oracle Forms supports OLE inplace activation. Inplace activation allows you to access menus and toolbars from OLE server applications to edit embedded OLE objects while you are in Oracle Forms. Oracle Forms also supports OLE automation. Using PL/SQL, you can invoke commands and functions that are exposed by OLE servers supporting OLE automation. From Oracle Forms, you can save OLE objects to a database, as well as query OLE objects from a database. OLE objects are saved as LONG RAW columns in the database. When linked objects are saved, only the image and the link information are retained in the database. The contents of a linked object remains in a linked source file. Saving an
10 8
embedded object retains all the contents of an embedded object in the database. An example of using OLE in Oracle Forms is an application that integrates Microsoft Word documents with a form module. The integration of a form module and Microsoft Word document provides you with access to features from both Oracle Forms and Microsoft Word. You can format the Microsoft Word document with any of the text processing features from Microsoft Word, and you can use all of the Oracle Forms features for displaying and manipulating the data from the database.
The characteristics of an OLE object in Oracle Forms depends on the properties of the OLE container. OLE container properties determine how OLE objects are activated, displayed, and manipulated.
10 9
OLE popup menu is not an option at runtime. The OLE popup menu can offer an array of operations that you can use with OLE objects. From the Designer, you can restrict the object classes for embedding and linking in an OLE container at runtime. For example, if you specify that the object class of an OLE container is restricted to the ExcelWorkSheet class, only a Microsoft Excel worksheet can be an OLE object in the OLE container. If no object class restriction is specified, any OLE object that is categorized as an object class in the registration database is a potential OLE object in the OLE container. When an OLE container is created, the properties associated with the OLE container are initially set to default values. The OLE container properties are divided into the following three groups of properties:
Activation Properties
OLE Class OLE Resize Style OLE Tenant Aspect OLE Tenant Types Show OLE Tenant Type
Activation properties specify whether editing an OLE object is performed with inplace activation or external activation. OLE popup menu properties determine if an OLE popup menu is available and what options appear on the OLE popup menu. OLE Tenant Properties specify conditions that are required for an OLE object in an OLE container. You can manually insert OLE objects in an OLE container from the Oracle Forms Designer. The OLE object that you insert into an OLE container adheres to the OLE container property settings. Inserting an OLE object into an OLE container from the Oracle Forms Designer initializes the OLE container. The initialization of an OLE container determines the initial content of the OLE container at runtime. At
10 10
runtime, any form query from a LONG RAW column of the database to populate the OLE container will overwrite the content that is used for initialization purposes.
10 11
10 12
Embedding Objects
Access to the Insert Object option on the OLE popup menu is necessary for manual insertion of an OLE object into an OLE container. You can create a new OLE object to insert into an OLE container, or you can embed an OLE object from an existing file into an OLE container. To embed a new OLE object: 1. Create an OLE container with the OLE Tenant Types property set to Any or Embedded. Make sure the Show OLE Popup Menu property is True, and the Insert Object item of the OLE Popup Menu Items is set to Display and Enable. 2. Move the mouse cursor on the OLE container and press the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Insert Object. The Insert Object dialog appears. From the Insert Object dialog, select Create New, choose an object type from the Object Type list, and click OK. The OLE server application starts up. Create the object in the OLE server application. Exit the OLE server application.
3.
4. 5.
10 13
To embed an object from an existing file: 1. Create an OLE container with the OLE Tenant Types property set to Any or Embedded. Make sure the Show OLE Popup Menu property is True, and the Insert Object item of the OLE Popup Menu Items is set to Display and Enable. 2. Move the mouse cursor on the OLE container and press the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Insert Object. The Insert Object dialog appears. From the Insert Object dialog, select Create from File, and specify the file name of the object to embed. You can use the Browse option to help locate the file. If you use the Browse option, click OK from the Browse dialog after selecting a file. 4. After you determine the file name, click OK on the Insert Object dialog.
3.
Linking Objects
Because linked objects contain information about the location of an OLE object, you can only link OLE objects from existing files. You cannot create an object when you are trying to link, because the location of new objects is not yet established. To link an object: 1. Create an OLE container with the OLE Tenant Types property set to Any or Linked. Make sure the Show OLE Popup Menu property is True, and the Insert Object item of the OLE Popup Menu Items is set to Display and Enable. 2. Move the mouse cursor on the OLE container and press the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Insert Object. The Insert Object dialog appears.
10 14
3.
From the Insert Object dialog, select Create from File, and specify the file name of the object to link. You can use the Browse option to help locate the file. If you use the Browse option, click OK from the Browse dialog after selecting a file.
4.
Check Link on the Insert Object dialog. After you determine the file name, click OK on the Insert Object dialog.
the content of the OLE object as it appears in the OLE server an icon of the OLE server application that originated the OLE object a thumbnail preview of the OLE object that appears in a reduced view
10 15
You specify the display option with the OLE Tenant Aspect property. You can also choose Display As Icon on the Insert Object dialog of the OLE popup menu. When you select Display As Icon, an icon appears in the OLE container to represent the embedded or linked object. Display As Icon overrides the value of the OLE Tenant Aspect property. To display an object as an icon using Display As Icon: 1. 2. Create an OLE container. From the Insert Object dialog, determine the object to embed or link. Before closing the Insert Object dialog, select Display As Icon. When you select Display As Icon, the current icon that represents the OLE server application that originated the OLE object for insertion is displayed in the Insert Object dialog. Icon selections can be changed by selecting Change Icon. The Change Icon dialog shows the current icon selection and the default icon selection. You can change both the current and default icon selections by selecting the desired icon. Different icons are stored in different files. After selecting an icon, click OK from the Change Icon dialog. 3. From the Insert Object dialog, click OK.
10 16
10 17
To update a linked object automatically: 1. Move the mouse cursor on the OLE container. Make sure the Show OLE Popup Menu property is True, and the Links item of the OLE Popup Menu Items is set to Display and Enable. 2. With the mouse cursor on the OLE container, use the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Links. The Links dialog appears. The Links dialog shows the current update option for the selected linked source file. Select the Automatic radio button that appears next to the Update label. Click Close to save your changes and exit the Links dialog.
3.
4.
To open a linked source file from the Links dialog: 1. Move the mouse cursor on the OLE container. Make sure the Show OLE Popup Menu property is True, and the Links item of the OLE Popup Menu Items is set to Display and Enable. 2. With the mouse cursor on the OLE container, use the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Links. The Links dialog appears. The Links dialog shows the current links to source files. Select a link to a source file, and select Open Source. The OLE server application that originated the linked source file starts up. Edit the linked source file.
3.
10 18
4.
Exit the OLE server application to save your changes and return to Oracle Forms.
To change an existing link from one linked source file to another: 1. Move the mouse cursor on the OLE container. Make sure the Show OLE Popup Menu property is True, and the Links item of the OLE Popup Menu Items is set to Display and Enable. 2. With the mouse cursor on the OLE container, use the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Links. The Links dialog appears. The Links dialog shows the current links to source files. Select a link to a source file, and select Change Source. The Change Source dialog appears. Select another linked source file. Click OK on the Change Source dialog to establish a new link. Select Close on the Links dialog to return to Oracle Forms.
3.
4.
To break a link to a linked source file: 1. Move the mouse cursor on the OLE container. Make sure the Show OLE Popup Menu property is True, and the Links item of the OLE Popup Menu Items is set to Display and Enable. 2. With the mouse cursor on the OLE container, use the right mouse button to access the OLE popup menu. From the OLE popup menu, choose Links. The Links dialog appears. The Links dialog shows the current links to source files. Choose a link to a source file, and select Break Link. Notice the link is removed from the Links dialog. Select Close from the Links dialog to return to Oracle Forms.
3.
4.
10 19
10 20
3. 4.
The Convert dialog shows the current object type and the conversion possibilities. Select a conversion object type. Select either Convert To or Activate As. Convert To permanently alters the format of the object to the selected object type. Activate As is a temporary conversion that provides a method for editing or viewing an object when an OLE server application cannot be found. Click OK on the Convert dialog to save changes.
5.
10 21
10 22
CHAPTER
11
VBX Controls
Forms for Microsoft O racleThis chapter includesWindows provides support for VBX controls. the following topics:
About VBX Controls 11 2 VBX Controls in Oracle Forms 11 3 VBX Controls in the Oracle Forms Designer 11 5 VBX Controls in Oracle Forms at Runtime 11 6 Creating a VBX Control in Oracle Forms 11 12
VBX Controls
11 1
VBX controls are a special type of dynamic link library distributed on files with the .VBX extension. A single VBX file can contain many different VBX controls, and each VBX control is defined by a set of properties, events, methods, and error messages. Refer to the documentation that accompanies your VBX control for more information on properties, events, methods, and error messages. Although you can develop your own VBX controls for use in Oracle Forms, developing VBX controls requires a significant amount of effort. The procedure for developing VBX controls is documented in the Microsoft Visual Basic Professional Edition Manuals. However, it is recommended that you use VBX controls developed by third party vendors.
11 2
Both the knob VBX control and the poplist can be used to make selections
A VBX control, like some Oracle Forms items, can also be used to input data. An item on a form can require the entry of a number in the range from 1 to 10. Using a poplist, you can display the choices on a list for selection. Similarly, a VBX control that is a knob can be used to provide choices by turning the knob. Instead of the choices appearing in the poplist, the choices are depicted by the position of the knob.
VBX Controls
11 3
VBX controls can be used in place of Oracle Forms items when any of the following conditions are met:
A VBX control is the best representation for your data in Oracle Forms. A VBX control is the best method of data input into Oracle Forms. You want a simple method of enhancing the user interface to build professional Oracle Forms applications.
11 4
You can set the VBX Control Value Property from the Oracle Forms Designer. In addition, you can programmatically get and set the VBX Control Value Property by using the VBX.GET_VALUE_PROPERTY and VBX.SET_VALUE_PROPERTY builtin subprograms from the VBX package in Oracle Forms. For more information on the VBX builtin subprograms, refer to the Oracle Forms Reference Manual, Vol. 1.
VBX Controls
11 5
This is a list of VBX properties that are mapped to Oracle Forms Properties:
VBX Property BackColor Enabled FontBold FontItalic FontName FontSize FontStrikeThru FontUnderline ForeColor Height Left TabIndex* TabStop* Top Visible Width Y Position (in Oracle Forms coordinates) Displayed Width Oracle Forms Property Background Color Enabled Font Weight Font Style Font Name Font Size Font Style Font Style Foreground Color Height X Position (in Oracle Forms coordinates)
*These properties do not have a onetoone mapping with Oracle Forms properties. The properties are handled internally by Oracle Forms and do not appear in the Properties window.
responding to VBX control events firing VBX control events getting VBX control properties setting VBX control properties invoking VBX control methods
11 6
:System.Custom_Item_Event = SpinDown THEN :QTY := :QTY 1; ELSE IF :System.Custom_Item_Event = SpinUp THEN :QTY := :QTY + 1; END IF; END IF:
VBX Controls
11 7
Example 1:
11 8
Example 2:
/* ** Builtin: VBX.FIRE_EVENT ** Example: Raises SpinDown event of spin button control. ** The SpinDown event does not require an event ** parameter. */ DECLARE ItemName VARCHAR2(40) := SPINBUTTON; BEGIN VBX.FIRE_EVENT(ItemName,SpinDown,NULL); END;
VBX Controls
11 9
Some VBX control properties are arrays of properties. Like scalarvalued properties, you can programmatically obtain the current setting of a VBX control property using the VBX.GET_PROPERTY builtin subprogram. Example 2:
/* ** Builtin: VBX.GET_PROPERTY ** Example: Uses the VBX.GET_PROPERTY builtin to obtain an ** indentation value from the Indent property ** array of the VBX control named OUTLINE. ** The Indent property value is returned to the ** IndentVal variable and is used as input to the ** userdefined SetIndent subprogram. ** Trigger: WhenCustomItemEvent */ DECLARE ClickEvent VARCHAR2(80); IndentVal CHAR; BEGIN ClickEvent := :system.custom_item_event; IF (UPPER(ClickEvent) = CLICK) then IndentVal := VBX.Get_Property(OUTLINE,Indent[2]); SetIndent(TO_NUMBER(IndentVal)); END IF; END;
11 10
BEGIN IF :System.Custom_Item_Event = SpinDown THEN VBX_VAL_PROP := Index; VBX_VAL := 5; VBX.Set_Property(ItemName,VBX_VAL_PROP,VBX_VAL); END IF; END;
Some VBX control properties are arrays of properties. Like scalarvalued properties, you can programmatically set the VBX control property using the VBX.SET_PROPERTY builtin subprogram. Example 2:
/* ** Builtin: VBX.SET_PROPERTY ** Example: Uses the VBX.SET_PROPERTY builtin to set the ** value of an element in the Indent property ** array of the VBX control named OUTLINE. ** Trigger: WhenButtonPressed */ DECLARE ItemName VARCHAR2(40) := OUTLINE; BEGIN IF :System.Custom_Item_Event = Click THEN Set_Property(ItemName,Indent[2],5); END IF; END;
VBX Controls
11 11
For information about the methods of a particular VBX control, refer to the documentation for the specific VBX control. For information on the VBX.INVOKE_METHOD builtin subprogram, refer to the Oracle Forms Reference Manual, Vol. 1. Example:
/* ** Builtin: VBX.INVOKE_METHOD_PROPERTY ** Example: Adds an entry to a combo box. The entry to ** add to the combo box is the first optional argument. ** The position where the entry appears is the second ** optional argument. */ DECLARE ItemName VARCHAR2(40) := COMBOBOX; BEGIN VBX.Invoke_Method(ItemName,ADDITEM,blue,2); END;
5.
11 12
CHAPTER
12
About DDE 12 2 Limitations 12 2 Function Overview 12 3 Function Descriptions 12 4 Microsoft Windows Predefined Data Formats 12 15 Exceptions 12 16
12 1
About DDE
Oracle Forms for Microsoft Windows supports Dynamic Data Exchange(DDE). DDE is a mechanism by which applications can communicate and exchange data. DDE client support is a procedural extension to Oracle Forms for Microsoft Windows. A PL/SQL package for DDE support, consisting of the functions listed in this chapter, provides application developers with an Application Programming Interface(API) for accessing DDE functionality from within PL/SQL procedures and triggers. The DDE functions enable Oracle Forms, a DDE client application, to communicate with DDE server applications in the following ways:
by importing data by exporting data by executing commands against the DDE server
Note: The information in this chapter assumes that you have a working knowledge of DDE, as implemented under Microsoft Windows.
Limitations
Oracle Forms does not include the following:
Data linking (advise transaction) Oracle Forms cannot automatically receive an update notice when a data item has changed.
Server support Oracle Forms cannot respond to commands or requests for data from a DDE client; Oracle Forms must initiate the DDE conversation (although data may still be transferred in either direction).
12 2
Function Overview
As part of the DDE package, the DDE functions available from within PL/SQL procedures and triggers can be grouped into the following categories:
Support functions Connect/Disconnect functions Transaction functions Data type Translation functions
Support Functions
These functions are used to start and stop other DDE Server applications. DDE.APP_BEGIN DDE.APP_END DDE.APP_FOCUS Begins a DDE server application. Ends a DDE server application. Focuses a DDE server application.
Connect/Disconnect Functions
These functions are used to connect to and disconnect from DDE server applications. DDE.INITIATE DDE.TERMINATE Starts a DDE conversation with a DDE server application. Ends a DDE conversation with a DDE server application.
Transaction Functions
These functions are used to exchange data with DDE server applications. DDE.EXECUTE DDE.POKE DDE.REQUEST Executes a command recognized by a DDE server application. Supplies information to a DDE server application. Requests information from a DDE server application.
12 3
DDE.APP_BEGIN
Syntax: Parameters:
Parameter Command Mode Type VARCHAR2 PLS_INTEGER Description command line for executing a program application window starting mode
Returns: Description:
PLS_INTEGER Begins a DDE server application program. In the Command string, the DDE server application program name can include a path. If the DDE server application name does not include a path, then the following directories are searched:
the current directory the Windows directory the Windows system directory the directory containing the executable file for the current task the directories listed in the PATH environment variable the directories mapped in a network
12 4
The DDE server application program name may be followed by arguments, which should be separated from the application program name with a space. You can start the DDE server application in either normal, minimized, or maximized size with the mode parameter. The application mode constants for DDE.APP_BEGIN are the following:
Mode DDE.APP_MODE_NORMAL DDE.APP_MODE_MINIMIZED Description Start application window in normal size. Start application window in minimized size. Start application window in maximized size.
DDE.APP_MODE_MAXIMIZED
This function returns an application identifier that is a PLS_INTEGER. The application identifier is used in all subsequent calls to DDE.APP_END and DDE.APP_FOCUS for that application window. Example:
DECLARE AppID PLS_INTEGER; BEGIN /* Start Microsoft Excel with spreadsheet emp.xls loaded. */ AppID := DDE.App_Begin(C:\excel\excel.exe C:\emp.xls, DDE.APP_MODE_MINIMIZED); END;
12 5
DDE.APP_END
Syntax: Parameters:
Parameter AppID Type PLS_INTEGER Description Application identifier that is returned from DDE.APP_BEGIN
DDE.APP_END (AppID)
Description:
Ends a DDE server application program that DDE_APP_BEGIN starts. The DDE server application can also be terminated in standard Microsoft Windows fashion, such as by doubleclicking the Control menu.
Restrictions: Example:
To terminate a DDE server application, the DDE server application must have been previously started by calling DDE.APP_BEGIN.
DECLARE AppID PLS_INTEGER: BEGIN /* Start Microsoft Excel with spreadsheet emp.xls loaded. */ AppID := DDE.App_Begin(C:\excel\excel.exe C:\emp.xls DDE.APP_MODE_NORMAL); ... /* End Microsoft Excel program. */ DDE.App_End(AppID); END;
12 6
DDE.APP_FOCUS
Syntax: Parameters:
Parameter AppID Type PLS_INTEGER Description application identifier returned by DDE.APP_BEGIN
DDE.APP_FOCUS (AppID)
Description:
Activates a DDE server application program started by DDE.APP_BEGIN. The application can also be activated in standard Microsoft Windows fashion, such as by clicking within the application window.
Restrictions: Example:
To activate a DDE server application, the DDE server application must have been previously started by calling DDE.APP_BEGIN.
DECLARE AppID PLS_INTEGER; BEGIN /* Start Microsoft Excel application in fullscreen mode. */ AppID := DDE.App_Begin(C:\excel\excel.exe, DDE.APP_MODE_MAXIMIZED); /* Activate the application window. */ DDE.App_Focus(AppID); END;
12 7
DDE.EXECUTE
Syntax: Parameters:
Parameter ConvID Command Timeout Type PLS_INTEGER VARCHAR2 PLS_INTEGER Description DDE conversation id Command string for the server to execute Timeout duration in milliseconds
The value of Command depends on what values are supported by the server application. Timeout specifies the maximum length of time, in milliseconds, that this routine waits for a response from the DDE server application. If the user specifies an invalid number, such as negative number, then the default value of 1000 ms is used. The duration of the timeout depends on machine configuration and the DDE server application. Description: Example:
DECLARE ConvID PLS_INTEGER; BEGIN /* Open a DDE conversation with Microsoft Excel for Windows */ ConvID := DDE.Initiate(EXCEL, C:\abc.xls); /* Recalculate the Excel spreadsheet.*/ DDE.Execute(ConvID, [calculate.now()], 1000); END;
Executes a command string that is acceptable in the receiving DDE server application.
12 8
DDE.GETFORMATNUM
Syntax: Parameters:
Parameter FormatStr Type VARCHAR2 Description Data format name string
DDE.GETFORMATNUM (FormatStr)
Returns: Description:
PLS_INTEGER Translates or registers a specified data format name and returns a format number. This function converts a data format from a string to a number. This number can be used in Poke and Request transactions to represent the DataFormat parameter. If the specified name is not registered, this function registers it and returns a unique format number. This is the only way to use a format in a Poke or Request transaction that is not one of the predefined formats. This function returns the numeric representation of the data format string that is a PLS_INTEGER. See the section, Microsoft Windows Predefined Data Formats, later in this chapter for the predefined data format constants.
Example:
DECLARE FormatNum PLS_INTEGER; MyFormatNum PLS_INTEGER; BEGIN /* Get predefined format number for CF_TEXT (should return CF_TEXT=1). */ FormatNum := DDE.GetFormatNum(CF_TEXT); /* Register a userdefined data format called MY_FORMAT. */ MyFormatNum := DDE.GetFormatNum(MY_FORMAT); END;
12 9
DDE.GETFORMATSTR
Syntax: Parameters:
Parameter FormatNum Type PLS_INTEGER Description Data format number
DDE.GETFORMATSTR (FormatNum)
Returns: Description:
CHAR Translates a data format number into a format name string. This function returns the string representation of the data format number that is a CHAR. This function returns a data format name if the data format number is valid. Valid format numbers include the predefined formats in the section, Microsoft Windows Predefined Data Formats, and any userdefined formats that were registered with DDE.GETFORMATNUM.
Example:
DECLARE FormatStr CHAR(20); BEGIN /* Get a data format name (should return the string CF_TEXT) */ FormatStr := DDE.GetFormatStr(CF_TEXT); END;
12 10
DDE.INITIATE
Syntax: Parameters:
Parameter Service Type VARCHAR2 Description DDE Server applications DDE service code Topic name for the conversation
Topic
VARCHAR2
The values of Service and Topic depend on the values supported by a particular DDE server application. Service is usually the name of the DDE server application program. For applications that operate on filebased documents, Topic is usually the document filename; in addition, the System topic is usually supported by each service. Returns: Description: PLS_INTEGER Opens a DDE conversation with a DDE server application. An application can start more than one conversation at a time with multiple services and topics, provided the conversation identifiers are not interchanged. This function returns the DDE conversation identifier that is a PLS_INTEGER. The conversation identifier that is returned must be used in all subsequent Execute, Poke, Request, and Terminate calls for that conversation. To terminate the conversation, you should call DDE.TERMINATE. Example:
DECLARE ConvID PLS_INTEGER; BEGIN /* Open a DDE conversation with Microsoft Excel for Windows on topic abc.xls. */ ConvID := DDE.Initiate(EXCEL, c:\abc.xls); END;
12 11
DDE.POKE
Syntax: Parameters:
Parameter ConvID Type PLS_INTEGER Description DDE conversion identifier that is returned by DDE.INITIATE Data item name to which the data is to be sent Data buffer to send Format of outgoing data Timeout duration in milliseconds
Item
VARCHAR2
The value of Item depends on what values are supported by the DDE server application on the current conversation topic. The predefined data format constants listed in the section, Microsoft Windows Predefined Data Formats, can be used for DataFormat. A userdefined format that is registered with DDE.GETFORMATNUM can also be used, provided the DDE server application recognizes the format. It is your responsibility to ensure that the DDE server application processes the specified data format. Timeout specifies the maximum length of time, in milliseconds, that this routine waits for a response from the DDE server application. If you specify an invalid number, such as negative number, then the default value of 1000 ms is used. The duration of the timeout depends on machine configuration and the DDE server application. Description: Example:
DECLARE ConvID PLS_INTEGER; BEGIN /* Open a DDE conversation with Microsoft Excel for Windows on topic abc.xls. */ ConvID = DDE.Initiate(EXCEL, C:\abc.xls); /* Send data foo to cell at row 2, column 2. */ DDE.Poke(ConvID, R2C2, foo, DDE.CF_TEXT, 1000); END;
12 12
DDE.REQUEST
Syntax: Parameters:
Parameter ConvID Type PLS_INTEGER Description DDE conversion identifier returned by DDE.INITIATE Requested data item name Result data buffer Format of requested data Timeout duration in milliseconds
The value of Item depends on what values are supported by the DDE server application on the current conversation topic. It is your responsibility to ensure that the return data buffer is large enough for the requested data. If the buffer size is smaller than the requested data, the data is truncated. The predefined data format constants listed in the section, Microsoft Windows Predefined Data Formats, can be used for DataFormat. A userdefined format that is registered with DDE.GETFORMATNUM can also be used, provided the DDE server application recognizes this format. It is your responsibility to ensure that the DDE server application will process the specified data format. Timeout specifies the maximum length of time, in milliseconds, that this routine waits for a response from the DDE server application. If you specify an invalid number, such as negative number, then the default value of 1000 ms is used. The duration of the timeout depends on machine configuration and the DDE server application.
12 13
Description: Example:
DDE.TERMINATE
Syntax: Parameters:
Parameter ConvID Type PLS_INTEGER Description DDE conversion identifier returned by DDE.INITIATE
DDE.TERMINATE (ConvID)
Description:
Terminates the specified conversation with a DDE server application. After the DDE.TERMINATE call, all subsequent Execute, Poke, Request, and Terminate requests using the terminated conversation identifier will result in an error.
Restrictions: Example:
You should use DDE.INITIATE to start a DDE conversation with a server application before attempting to use DDE.TERMINATE.
DECLARE ConvID PLS_INTEGER; BEGIN /* Open a DDE conversation with Microsoft Excel for Windows on topic abc.xls. */ ConvID := DDE.Initiate(EXCEL, C:\abc.xls); ... /* Terminate the Microsoft Excel for Windows conversation */ DDE.Terminate(ConvID); END;
12 14
DDE.CF_DIF DDE.CF_DSPBITMAP
DDE.CF_ DSPMETAFILEPICT
DDE.CF_DSPTEXT
DDE.CF_TIFF DDE.CF_WAVE
12 15
Exceptions
Exception DDE.DDE_APP_FAILURE Description An application program specified in a DDE.APP_BEGIN call could not be started. An application ID specified in a DDE.APP_END or DDE.APP_FOCUS call does not correspond to an application that is currently running. A format number specified in a DDE.GETFORMATSTR call is not known. A format string specified in a DDE.GETFORMATNUM call does not correspond to a predefined format and could not be registered as a userdefined format. The application was unable to initialize DDE communications, which caused a call to the DDE layer to fail. An invalid parameter, such as a NULL value, is passed to a DDE package routine. A transaction failed because the server application is busy. A request for a synchronous data transaction has timed out. A request for a synchronous execute transaction has timed out. A parameter failed to be validated. Some of the possible causes are as follows: The application used a data handle initialized with a different itemname handle or clipboard data format than that required by the transaction. The application used an invalid conversation identifier. More than one instance of the application used the same object. A memory allocation failed.
DDE.DDE_APP_NOT_FOUND
DDE.DDE_FMT_NOT_FOUND
DDE.DDE_FMT_NOT_REG
DDE.DDE_INIT_FAILED
DDE.DDE_PARAM_ERR
DDE.DMLERR_MEMORY_ERROR
12 16
Description A clients attempt to establish a conversation has failed. The service or topic name in a DDE.INITIATE call may be in error. A transaction failed. The item name in a Poke or Request transaction may be in error. A request for a synchronous poke transaction has timed out. An internal call to the PostMessage function has failed. The server terminated before completing a transaction. An internal error has occurred in the DDE layer.
DDE.DMLERR_NOTPROCESSED
12 17
12 18
CHAPTER
13
About the PL/SQL Interface 13 2 About Foreign Functions 13 3 Creating a PL/SQL Interface to Foreign Functions 13 6 Invoking a Foreign Function from PL/SQL 13 9 An Example of Creating a PL/SQL Interface 13 11 Accessing the Microsoft Windows SDK from PL/SQL 13 16
13 1
13 2
Replace default Oracle Forms processing when running against a nonOracle data source using transactional triggers. Perform complex data manipulation. Pass data to Oracle Forms from operating system text files. Manipulate LONG RAW data. Pass entire PL/SQL blocks for processing by the server. Control real time devices, such as a printer or a robot. Note: You should not perform host language screen I/O from a foreign function. This restriction exists because the runtime routines that a host language uses to perform screen I/O conflict with the routines that Oracle Forms uses to perform screen I/O. However, you can perform host language file I/O from a foreign function.
Foreign functions that can be invoked from a PL/SQL interface must be contained in a dynamic library. The procedure for creating a dynamic library depends on your operating system. For more information on creating dynamic libraries in your environment, refer to the documentation for your operating system.
Oracle Precompiler foreign functions OCI (ORACLE Call Interface) foreign functions nonORACLE foreign functions
You can also develop foreign functions that combine both the ORACLE Precompiler interface and the OCI.
13 3
Oracle Precompiler Foreign Functions An Oracle Precompiler foreign function incorporates the Oracle Precompiler interface. This interface allows you to write a subprogram in one of the following supported host languages with embedded SQL commands:
Note: Not all operating systems support all of the listed languages. For more information on supported languages, refer to the Oracle Forms documentation for your operating system. With embedded SQL commands, an Oracle Precompiler foreign function can access Oracle databases as well as Oracle Forms variables and items. You can access Oracle Forms variables and items by using a set of Oracle Precompiler statements that provide this capability. Because of the capability to access both Oracle databases and Oracle Forms variables and items, most of your foreign functions will be Oracle Precompiler foreign functions. For more information on the Oracle Precompiler interface, refer to the Programmers Guide to the Oracle Precompilers. Oracle Call Interface(OCI) Foreign Functions An OCI foreign function incorporates the Oracle Call Interface. This interface allows you to write a subprogram that contains calls to Oracle databases. A foreign function that incorporates only the OCI (and not the Oracle Precompiler interface) cannot access Oracle Forms variables and items. For more information on the OCI, refer to the Programmers Guide to the Oracle Call Interface. NonOracle Foreign Functions A nonOracle foreign function does not incorporate either the Oracle Precompiler interface or the OCI. For example, a nonOracle foreign function might be written entirely in the C language. A nonOracle foreign function cannot access Oracle databases, or Oracle Forms variables and items.
13 4
Precompiler Statements
All Oracle Precompiler foreign functions can use host language statements to perform procedural operations. Precompiler foreign functions can also use the following types of statements to perform additional functions such as accessing the database and manipulating Oracle Forms variables and items. For more information on the following Oracle Precompiler statements, refer to Chapter 3, User Interface to Foreign Functions.
Statement EXEC SQL EXEC TOOLS GET EXEC TOOLS SET EXEC TOOLS MESSAGE EXEC TOOLS GET CONTEXT Use Performs SQL commands. Retrieves values from Oracle Forms to a foreign function. Sends values from a foreign function to Oracle Forms. Passes a message from a foreign function to display in Oracle Forms. Obtains context information previously saved in a foreign function. Saves context information from one foreign function for use in subsequent foreign function invocations. Executes Oracle Precompiler options.
EXEC ORACLE
An Oracle Precompiler foreign function source file includes host programming language statements and Oracle Precompiler statements with embedded SQL statements. Precompiling an Oracle Precompiler foreign function replaces the embedded SQL statements with equivalent host programming language statements. After precompiling, you have a source file that you can compile with a host language compiler. For more information on a specific precompiler, refer to the appropriate precompiler documentation for your environment.
13 5
Initializing the foreign function Associating a PL/SQL subprogram with the foreign function Mimicking the foreign function prototype with PL/SQL
A PL/SQL package encapsulates the components that are used in creating a PL/SQL interface to a foreign function. You can include PL/SQL interfaces to multiple foreign functions in a single PL/SQL package. For each PL/SQL interface to a foreign function, you must follow the procedure of initializing the foreign function, associating a PL/SQL subprogram with the foreign function, and mimicking the foreign function prototype in PL/SQL. Alternatively, you can opt to include a PL/SQL interface to a single foreign function in a PL/SQL package.
2.
3.
4.
13 6
For more details about the ORA_FFI package, refer to the Oracle Procedure Builder Developers Guide. The ORA_FFI package documentation is also available in Oracle Forms online Help. Here is an example of initializing a foreign function:
PACKAGE BODY calc IS BEGIN /* This example shows how to initialize the foreign function int ADD(int X, int Y) that is contained in the dynamic library CALC.DLL; */ lh_calc := ora_ffi.load_library(c:\mathlib\, calc.dll); fh_add := ora_ffi.register_function(lh_calc,add, ora_ffi.C_STD); ora_ffi.register_return(fh_add,ORA_FFI.C_INT); ora_ffi.register_parameter(fh_add,ORA_FFI.C_INT); ora_ffi.register_parameter(fh_add,ORA_FFI.C_INT); END;
3.
13 7
For more details on the ORA_FFI package, refer to the Oracle Procedure Builder Developers Guide. The ORA_FFI package documentation is also available in Oracle Forms online Help. Here is an example of associating a subprogram with a foreign function:
PACKAGE BODY calc IS /* This example shows how to associate a PL/SQL subprogram with the given function prototype, int ADD(int X, int Y); */ FUNCTION ff_ADD(ff_handle ORA_FFI.FUNCHANDLETYPE, X IN BINARY_INTEGER, Y IN BINARY_INTEGER); RETURN BINARY_INTEGER; PRAGMA interface(C, ff_ADD, 11265); BEGIN ... END;
2. 3.
13 8
Invoking a foreign function from a PL/SQL interface passes process control to the foreign function. Upon completion of the foreign function, process control is returned to Oracle Forms.
13 9
13 10
13 11
13 12
*/ FUNCTION icd_gpps(funcHandle IN ora_ffi.funcHandleType, pSection IN OUT VARCHAR2, pEntry IN OUT VARCHAR2, pDefault IN OUT VARCHAR2, pReturnBuffer IN OUT VARCHAR2, pRetrunBufferN IN BINARY_INTEGER, pFilename IN OUT VARCHAR2) RETURN BINARY_INTEGER; PRAGMA(c,icd_gpps,11265); FUNCTION WritePrivateString(pSection IN VARCHAR2, pEntry IN VARCHAR2, pString IN VARCHAR2, pFilename IN VARCHAR2) RETURN BOOLEAN IS /* WritePrivateString calls the Windows function */ /* Make copies of in out arguments */ lSection VARCHAR2(1024) := pSection; lEntry VARCHAR(1024) := pEntry; lString VARCHAR2(1024) := pString; lFilename VARCHAR(1024) := pFilename; BEGIN /* validate argumentsalthough NULL is a valid argument for Windows functions, we are going to prohibit this case because of the format of the string that is returned */ IF (lSection is NULL) OR (lEntry is NULL) OR (lString is NULL) OR (lFilename is NULL) THEN RAISE VALUE_ERROR; END IF; RETURN(icd_wpps(fh_wpps,lSection,lEntry,lString, lFilename)<>0); END WritePrivateString; FUNCTION GetPrivateString(pSection IN VARCHAR2, pEntry IN VARCHAR2, pDefault IN VARCHAR2, pReturnBuffer IN OUT VARCHAR2, pReturnBufferN IN BINARY_INTEGER, pFilename IN VARCHAR2) RETURN BINARY_INTEGER IS /* GetPrivateString calls the Windows function */ /* Make copies of in out arguments */ lSection VARCHAR2(1024) := pSection; lEntry VARCHAR(1024) := pEntry;
13 13
lDefault VARCHAR2(1024) := pDefault; lFilename VARCHAR(1024) := pFilename; BEGIN /* validate argumentsalthough NULL is a valid argument for Windows functions, we are going to prohibit this case because of the format of the string that is returned */ IF (lSection is NULL) OR (lEntry is NULL) OR (lDefault is NULL) OR (lFilename is NULL) OR (pReturnBufferN <= 0) THEN RAISE VALUE_ERROR; END IF; /* Pad the buffer with spaces */ pReturnBuffer := rpad( , pReturnBufferN); RETURN(icd_gpps(fh_gpps,lSection,lEntry,lDefault, pReturnBuffer,pReturnBufferN,lFilename)); END GetPrivateString; BEGIN /* Declare a library handle to the Windows 386 Kernel */ lh_windows := ora_ffi.load_library(NULL,krnl386.exe); /* Register the components of WritePrivateString This is function prototype for WritePrivateProfileString: BOOL WritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename) */ fh_wpps := ora_ffi.register_function(lh_windows, WritePrivateProfileString, ora_ffi.PASCAL_STD); ora_ffi.register_return(fh_wpps,ORA_FFI.C_SHORT); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); /* Register the components of GetPrivateString This is function prototype for GetPrivateProfileString: int GetPrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszDefault, LPCSTR lpszReturnBuffer,
13 14
int cbReturnBuffer, LPCSTR lpszFilename) */ fh_gpps := ora_ffi.register_function(lh_windows, GetPrivateProfileString, ora_ffi.PASCAL_STD); ora_ffi.register_return(fh_gpps,ORA_FFI.C_INT); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_INT); ora_ffi.register_parameter(fh_wpps,ORA_FFI.C_CHAR_PTR); END OraWinProfile;
Here is an example of how to invoke the WritePrivateProfileString and the GetPrivateProfileString functions from a PL/SQL interface in Oracle Forms:
DECLARE tmpb BOOLEAN; tmpn NUMBER; buffer VARCHAR(1024) := ; buffern BINARY_INTEGER := 1024; BEGIN tmpb := OraWinProfile.WritePrivateString(Section, Entry, string1, PROFILE.INI); tmpn := OraWinProfile.GetPrivateString(Section, Entry, Bad Entry, buffer, buffern, PROFILE.INI); MESSAGE(buffer); END;
You invoke the WritePrivateString and GetPrivateString functions from the OraWinProfile package. After executing the example PL/SQL code, the following two lines are appended to the PROFILE.INI file.
[Section] Entry=String1
The identical results would have been obtained if the Windows Profile String functions, WritePrivateString and GetPrivateString, were called from outside Oracle Forms. From this example, you can see how a variety of foreign functions can be invoked in Oracle Forms from a PL/SQL interface.
13 15
13 16
CHAPTER
14
About OCA and ODBC 14 2 Setting Up Applications to Run with OCA 14 8 Oracle Open Client Adapter Restrictions 14 12 Using UBT 14 20
14 1
Supports both readonly and readwrite access to ORACLE and nonORACLE databases that provide ODBC drivers. Supports standard SQL features, as described in the ODBC SQL grammar. Supports Developer/2000 tools. Represents ODBC database dictionary information through the standard ORACLE data dictionary views. ODBC/ORACLE data type conversions support most ORACLE datatypes. National Language Support Character set translation between server side and client side character sets. ASCII and EBCDIC. Major 8bit character sets supported in database object name.
Unlike Open Gateway, no supporting Oracle kernel is required for Data Dictionary support. Full read/write capability limited only by the ODBC backend. Allows SQL pass through and supports native SQL.
14 2
Data Source
Developer/2000 Application
14 3
Rdb
14 4
process and execute one or more SQL statements end each transaction by committing it or rolling it back terminate the connection when the application has finished interacting with the data source
For information on restrictions when running Oracle Forms against ODBC datasources, refer to Oracle Open Client Adapter Restrictions later in this chapter. For information on setting up an Oracle Forms application to run against ODBC datasources, refer to Setting Up Applications to Run with Oracle Open Client Adapter later in this chapter.
The logon ID or account name for access to the data source (optional). The user password that allows access to the requested data source (optional). The name of the data source being requested by the application. If the user specifies a * as a wildcard, a dialog listing all available data sources will appear.
password
odbc_datasource_ name
Example:
scott/tiger@odbc:sqlserver
14 5
Note: If you omit the @odbc:database_name string or provide a normal connect string, ORACLE database calls are not mapped to ODBC calls; the adapter has no effect. Your Developer/2000 tool behaves as it normally behaves when connecting to ORACLE. The following SQL*Plus session illustrates the above concept:
Note: Connection information for each data source is stored in the ODBC.INI file.
14 6
Note that ODBC defines a standard syntax for SQL statements. If an application submits a SQL statement that does not use the ODBC syntax, the driver passes it directly to the target DBMS unmodified.
14 7
Column Security block property Cursor Mode form module property Key Mode block property Locking Mode block property Primary Key block and item property Savepoint Mode form property
Setting these properties configures a form to run against an ODBC data source. Note: These properties (except Primary Key) can be set manually or by inheritance via two OCAspecific property classes, OCA_MODULE_PROPERTY and OCA_BLOCK_PROPERTY. These property class objects can be copied from the demo form OCA_PROP.FMB. OCA_PROP.FMB is located at \ORACLE_HOME\OCA\ODBC10\DEMO. To specify a primary key, you must select the appropriate item and then define its Primary Key property. For more information about property classes, refer to Chapter 4, Setting Object Properties, in the Oracle Forms Developers Guide. Property Column Security (block) Required Setting False By default, the Column Security property is set to False. Oracle Forms does not enforce column update privileges. Rather, the database enforces the privileges when Oracle Forms attempts to update the database. Do not set this property to True. The Column Security property is an ORACLEspecific property which requires the ORACLE data dictionary views: ALL_OBJECTS, TABLE_PRIVILEGES, ALL_SYNONYMS, and COLUMN_PRIVILEGES.
14 8
Open Unlike ORACLE, some nonORACLE databases do not allow the database state of cursors to be maintained across transactions. Setting Cursor Mode to Close specifies that cursors are closed at commit time by the data source. Updateable The Key Mode block property determines how Oracle Forms uniquely identifies rows in the database. ORACLE uses unique ROWID values to identify each row. NonOracle databases do not include the ROWID construct, but instead rely solely on unique primary key values to identify unique rows. Delayed Specifies when Oracle Forms should attempt to obtain database locks on rows that correspond to queried records in the form. By default, Oracle Forms attempts to lock the corresponding row immediately after an operator modifies an item value in a queried record. When you set Locking Mode to Delayed, the record is locked only while the transaction is being posted to the database, not while the operator is editing the record.
True Setting the Primary Key property to True for a block and item indicates that the item is a base table item in a base table block and that it corresponds to a primary key column in the base table. Oracle Forms requires values in primary key items to be unique. False Setting Savepoint Mode to False specifies that Oracle Forms should not issue savepoints during a session.
14 9
(1) Either Updateable or NonUpdateable modes. (2) Client must override the ONROLLBACK trigger to avoid a SQL rollback error. (3) DECLARE, BEGIN, END, COMMIT WORK, ROLLBACK, OPEN, CURSOR, FETCH, CLOSE, GOTO, SELECT INTO, UPDATE, INSERT, DELETE, NULL . (4) DECLARE, OPEN, CLOSE, explicit/implicit attributes (%FOUND, %NOTFOUND, %ROWCOUNT, %ISOPEN), cursor in loop constructs, and FOR UPDATE OF...WHERE CURRENT OF.
14 10
(5) Refer to the section, SQL Server Restrictions later in this chapter. (6) In Microsoft Access, names can be up to 64 characters long and can include any combination of letters, numbers, spaces and special characters except a period (.), an exclamation mark (!), brackets ([]), leading spaces, or control characters (ASCII 0 through 32). (7) SUM, AVG, MAX, MIN, COUNT. ABS, FLOOR, SIGN, SQRT, ROUND, ASCII, LOWER, UPPER, LTRIM, RTRIM, and SOUNDEX. (8) SUM, AVG, MAX, MIN, COUNT, LTRIM, and RTRIM. (9) Either mode should work. Microsoft Access does not support locking mechanisms through SQL. The only possible modes read only and exclusive are specified when the database is opened in the Open Database dialog box or ODBC Access Setup dialog box. Multiuser locking modes such as No Locks, All Records, and Edited Record are specified on a pertable basis, and there is no support to do this using SQL at runtime on an ODBC connection. (10) Native datatypes are usable through PL/SQL, but mapping or conversion problems may exist, as well as certain restrictions on operations and length (e.g., MEMO (32k max) should map to LONG). Note: With PL/SQL(Version1.1.43.x.x), you cannot do select <memo col> into <a long var> from <tabname> because PL/SQL reports improper INTO var type. Also for OLE (128M max) Access datatypes, the same restriction applies; LONG RAW is limited to 32k. (11) SUM, AVG, MAX, MIN, COUNT, UPPER, and LOWER. Rdb 6.x supports external functions. Users can execute external functions in SQL statements. (12) If Rdb is being used with multischema naming, you must use the MULTISCHEMA IS OFF syntax to attach a file. For example, ATTACH FILENAME DISK$VDEV9:[ORACLE]RDBTEST.Rdb MULTISCHEMA IS OFF. If a table is created in a different schema with the same name, Rdb will uniquely identify each schema object by appending numeric digits. For more information, refer to your Rdb documentation. (13) Rdb supports the GRANT and REVOKE commands. Rdb does not support roles, privileges, or users. As a result, Developer/2000 tools cannot use this information in RdbVMS$PRIVILEGES for security features in this release. (14) ODBC requires that the buffer for character data include space for the null termination byte. When selecting a character column into a PL/SQL variable, the PL/SQL buffer must have an additional byte to
14 11
store the null terminator, else data truncation occurs. For the same reason CURSOR%ROWTYPE will not work if the row contains columns of type CHAR or VARCHAR.
Generic Restrictions
This section describes the generic restrictions which apply to each Developer/2000 application when running with Oracle Open Client Adapter. Case Sensitivity ORACLE converts names of all database objects to uppercase. Some databases, like SQL Server, are case sensitive. For example, ABC, abc, AbC are treated as different identifiers. Suggestion: Install SQL Server with the Case Insensitive option. Scalar Functions Most databases do not support the set of scalar functions provided by ORACLE, such as TO_CHAR() and DECODE(). Since PL/SQL only parses for ORACLE functions, the only functions that will work with nonOracle databases are the SQL common to ORACLE and nonOracle databases. For a complete listing of Oracle scalar functions, refer to the SQL Language Reference Manual. Suggestion: In general, DECODE() functionality can be replaced by the use of one or more relational views which contain joins that perform the scalar column value mapping normally performed by the DECODE(). It may also be possible to replace simple DECODE() functions with arithmetic functions, which may be more efficient than joins. Data Dictionary Objects Oracle tools assume certain specific data dictionary views with specific column names and types. In particular, Oracle Forms requires the following views: ALL_OBJECTS, ALL_TABLES, ALL_VIEWS, ALL_TAB_COLUMNS, ALL_USERS, DUAL, TABLE_PRIVILEGES, ALL_SYNONYMS, and COLUMN_PRIVILEGES.
14 12
These ORACLEspecific views do not exist in nonORACLE databases. Suggestion: Currently, for SQL Server and Rdb, Oracle provides a limited set of views to map the native dictionary objects into the necessary ORACLE data dictionary views. When using these views, users should restrict their usage to the columns provided. Note: The Tables/Columns feature in the Oracle Forms Designer will not work unless these views are present in the target data dictionary. Column/Table Name Oracle Forms does not support spaces as part of a column or table name. For example, EMPNO and EMP_NO are valid column names, but EMP NO is not. Column and table name identifiers must not include spaces. List of Values Oracle Open Client Adapter does not support V2 style LOVs. Comments within SQL Statements Although SQL Server supports embedded SQL /*hint*/ style comments, not all ODBC databases drivers have the same support. Suggestion: Avoid embedding optimizer hint comments within SQL statements. NOWAIT Clause for Locks Oracle tools allow the NOWAIT clause to be appended to SELECT statements. The NOWAIT option tells ORACLE not to wait if the table has been locked by another user. For example, when Oracle Forms updates a record, it issues the following statement in order to lock the record for update.:
SELECT ... FOR UPDATE ... NOWAIT
If Oracle Forms cannot acquire the lock, the NOWAIT clause causes the database to issue an error stating that the record has been locked by another user. Control is then immediately returned to your application so that it can do other work before trying again to acquire the lock. Suggestion: The NOWAIT option is ORACLEspecific. Do not use the NOWAIT parameter with the ENTER_QUERY or EXECUTE_QUERY builtins. When the NOWAIT parameter is not specified, Oracle Forms behaves as if it is in delayed locking mode; Oracle Forms waits to lock the corresponding row in the database until the transaction is about to be committed. With this setting, the record is locked only while the transaction is being posted to the database, not while the operator is editing the record.
14 13
If another user has a lock and, as a result, Oracle Forms is unable to obtain a requested lock, Oracle Forms will request (via the lock dialog) whether it should retry. The operator can respond Yes and wait for Oracle Forms to acquire the lock or terminate the locking procedure by pressing CTRLC (or its equivalent). Sequences A sequence is an Oraclespecific database object that generates sequential numbers. An Oracle Forms application can reference sequence values for default item values by setting the Default item property to SEQUENCE.my_seq.NEXTVAL. Suggestion:Avoid the use of sequences. Most databases do not support this functionality. Commit/Rollback Some databases allow only one cursor per connection. As a result, any additional cursors must be allocated through separate connections. Oracle Forms controls masterdetail relations through multiple cursors. Since SQL Server only allows one active cursor per connection, another connection must be established for each detail. Because each cursor has an individual connection, committing a masterdetail block application requires coordinating the various cursors. Consequently, a problem could arise if only a subset of the multiple required connections commit their work and a form could be inconsistently updated if a remaining subset of the connections fail to commit or roll back. Suggestion: Use a driver that coordinates twophase commits between connections. Selecting LONG Columns Some databases do not permit revisiting columns to fetch LONG data piecemeal once data for the next column has been fetched. For example, assume that you issue the following statement:
SELECT A, B, C FROM TEST
If column B is a LONG, data for column B cannot be fetched piecemeal, once data for column C is fetched. In order to fetch data piecemeal from a LONG, the query must be rearranged so that the LONG column appears last.
SELECT A, C, B FROM TEST
The same restriction prohibits the inclusion of more than one LONG column in a query executed against such databases.
14 14
Suggestion: Modify your SELECT statements so that the LONG column appears last. Programmatic OffsetBased Fetching of LONG Columns Incremental offsetbased fetching of LONG field data is not supported by ODBC. The ODBC specification permits only sequential fetching of data. Unsupported PL/SQL Statements The Oracle Open Client Adapter does not support the following PL/SQL statements: ROLLBACK TO SAVEPOINT LOCK TABLE SET TRANSACTION
DriverSpecific Restrictions
This section describes driverspecific restrictions which apply when running with Oracle Open Client Adapter.
14 15
CREATE DATABASE, CREATE TABLE, CREATE INDEX, CREATE VIEW, all DROP statements, SELECT INTO (because it creates a table),GRANT, REVOKE, ALTER DATABASE, TRUNCATE TABLE, UPDATE STATISTICS, RECONFIGURE, LOAD DATABASE, LOAD TRANSACTION, and DISK INIT. When issuing these DDL statements (via the FORMS_DDL builtin subprogram), you must not issue any subsequent DML statements until you commit or roll back your transaction. For example, issuing the following will result in an error:
SELECT ... CREATE ...
ORDER BY in SQL Server Within ORDER BY clauses, SQL Server permits positional references to columns only if the columns are explicitly listed. For example,
SELECT * FROM TABLE .. ORDER BY <column_number>
will raise a SQL Server error. Suggestion: Replace the * with explicit column names, or substitute the <column_number>with a <column_identifier>. In addition, SQL Server does not permit duplicate column references in the ORDER BY clause, such as:
SELECT C1, C2, C3 FROM TABLE .. ORDER BY C2, 2
FLOAT Datatype An Oracle Forms item defined as a NUMBER cannot accept values greater than 2,147,483,647 if the corresponding SQL Server column is a FLOAT datatype. In addition, entering a floating point number as an integer may cause an error. For example, entering 12345 into a float field will result in an error. However, entering the floating point number as a decimal (e.g.,12345.0) is valid as it indicates to the Oracle Open Client Adapter that the number is a floating point number. Suggestion: Floating point numbers should be entered as decimals. Oracle PL/SQL % Predicate Because SQL Server does not support the TO_CHAR datatype, the Oracle PL/SQL % predicate cannot be used at runtime to query date or numeric datatypes. Stored Procedure Support Currently, SQL Server stored procedures are not supported by Oracle Forms or PL/SQL.
14 16
Suggestion: To use a stored procedure which returns a result set, your stored procedure must deposit its results in a temporary table. Oracle Forms can then select from the temporary table. For more information, refer to the sprocbild.sql and sprocrun.sql example scripts. Global Variables SQL Server global variables cannot be used with Oracle Forms or PL/SQL. Transact SQL Statements Use of the following Transact SQL statements is restricted:
The PRINT statement cannot be used with PL/SQL, although I/O routines can be called from within user exits. The WAIT FOR {DELAY time | TIME time | ERROREXIT |PROCESSEXIT | MIRROR EXIT statement cannot be used with PL/SQL. The FOR UPDATE ... WHERE CURRENT OF statement does not work with SQL Server.
SQL Functions As a rule, SQL functions that exist in ORACLE and SQL Server work with OCA. This includes the following:
aggregates or SQL functions: ALL, DISTINCT, SUM, AVG, MAX, MIN, and COUNT date functions: none mathematical functions: ABS, FLOOR, SIGN, SQRT, and ROUND string functions: ASCII, LOWER, UPPER, LTRIM, RTRIM, and SOUNDEX system functions: none text image functions: none type conversion: none
Multiple Inserts in a PL/SQL Block If multiple insert statements on a table refer to the same database page for the table in a PL/SQL block, the application will deadlock. This situation exists because the ODBC driver executes the insert statements through separate connections, and they lock each other out. Suggestion: To perform multiple commits in the same PL/SQL block, you could commit between inserts, or execute them in a PL/SQL LOOP, or put the insert statements in a stored procedure and pass the values as arguments to the procedure.
14 17
14 18
Rdb Restrictions
This section describes the Rdb restrictions which apply when running with Oracle Open Client Adapter. For information about additional restrictions, refer to your Rdb Driver documentation. SQL Statements Rdb SQL does not support the following ORACLEspecific features: sequences, synonyms, database links, security roles, pseudocolumns such as ROWID and ROWNUM, SQL functions, row comparisons, set difference operators (MINUS and INTERSECT), recursive queries, order by expressions, savepoints, and disabled constraints. Rdbspecific SQL statements can be executed using the FORMS_DDL builtin function. Datatypes Rdb and ORACLE datatypes can be mapped as follows: Rdb
CHAR VARCHAR TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DATE LIST OF BYTE VARYING
ORACLE
CHAR VARCHAR NUMBER NUMBER (SMALLINT) NUMBER (INTEGER) NUMBER NUMBER (REAL) NUMBER (FLOAT) DATE RAW, LONG RAW
PL/SQL All PL/SQL programming constructs and datatypes can be used with Rdb. Note: Currently, a stored procedure in Rdb cannot be invoked from PL/SQL unless it is parameterless or contains only input parameters. Rdb stored procedures that do not contain parameters or contain only input parameters can be called from a PL/SQL procedure by using the FORMS_DDL builtin function.
14 19
Using UBT
UBT is an interactive command driver for testing and exercising the Oracle Open Client Adapter. UBT enables you to issue SQL commands within the interpreter or through command files. You can perform data migration by using the database tabletotable COPY command.
with a semicolon (;). This indicates that you want to run the command. Type the semicolon at the end of the last line of the command. with a blank line. The command is ignored and the prompt appears.
14 20
UBT Commands
The following section provides a description of each UBT command.
CONNECT
Description: Syntax: Parameters:
username [/password] database_ specification
Represents the username and password with which you wish to connect to the database. Consists of a SQL*Net or ODBC connection string.
COPY
Description: Syntax: Copies the data from a query to a table in a local or remote database.
COPY {FROM username[/password]@database_specification | TO username[/password]@database_specification | FROM username[/password]@database_specification TO username[/password]@database_specification} {APPEND/CREATE/INSERT/REPLACE} destination_table [(column, column, column ...)] USING query
Represents the username/password you wish to COPY FROM and TO. In the FROM clause, username/password identifies the source of the data; in the TO clause, username/password identifies the destination. Consists of a SQL*Net or ODBC connection string. In the FROM clause, database_specification represents the database at the source; in the TO clause, database_specification represents the database at the destination. The exact syntax for SQL*Net depends on the communications protocol your ORACLE installation uses. The syntax for an ODBC connection is ODBC:data_source where the
database_ specification
14 21
ODBC keyword is followed by a colon and the name of the installed data source.
destination_table
Represents the table you want to create or to which you want to add data. Specifies the names of the columns in destination_table. If you specify columns, the number of columns must equal the number of columns selected by the query. If you do not specify any columns, the copied columns will have the same names in the destination table as they had in the source, if COPY creates destination_table. Specifies a SQL SELECT statement that determines which rows and columns COPY copies. Specifies the username, password, and database that contains the data to be copied. If you omit the FROM clause, the source defaults to the database UBT is connected to (the database that other commands address). You must include a FROM clause to specify a source database other than the default. Specifies the database containing the destination table. If you omit the TO clause, the destination defaults to the database UBT is connected to. You must include a TO clause to specify a destination database other than the default. Inserts the rows from query into destination_table if the table exists. If destination_table does not exist, COPY creates it. Inserts the rows from query into destination_table after creating the table first. If destination_table already exists, COPY returns an error. Inserts the rows from query into destination_table if the table exists. Replaces destination_table and its contents with the rows from query. If destination_table does not exist, COPY creates it. If destination_table exists, COPY drops the existing table and replaces it with a table containing the copied data.
USING query
APPEND
CREATE
INSERT
REPLACE
14 22
Example:
The following command copies the entire EMP table to a table named WESTEMP. Note that the tables are located in two different databases. If WESTEMP already exists, both the table and its contents are replaced. The columns in WESTEMP have the same names as the columns in the source table, EMP.
COPY FROM scott/tiger@ODBC:INFO TO jack/smith@ODBC:HQ REPLACE westemp USING SELECT * FROM EMP
The following command copies selected records from EMP to the database to which UBT is connected. Table SALESMEN is created during the copy. UBT copes only the columns EMPNO and ENAME and at the destination names them EMPNO and SALESMAN.
COPY FROM scott/tiger@ODBC:INFO CREATE salesmen (empno,salesman) USING SELECT empno, ename FROM emp WHERE job=SALESMAN
@
Description: Syntax: Runs the specified UBT command file.
@file_name.ext
DISCONNECT
Description: Syntax: Commits pending changes to the database and logs the user off the database, but does not exit UBT.
DISCONNECT
QUIT/EXIT
Description: Syntax: Commits all pending database changes, terminates UBT, and returns control to the operating system.
QUIT | EXIT
SET AUTOCOMMIT
Description: Toggles Autocommit to On or Off. Some databases allow certain types of SQL statements only when Autocommit is On. For example, SQL Server only allows DDL statements when Autocommit is On. Syntax:
SET AUTOCOMMIT {ON | OFF}
14 23
SPOOL
Description: Syntax: Parameters:
file_name
Represents the name for the file to which you wish to spool. Stops spooling
OFF
Example:
14 24
APPENDIX
About Oracle Forms Resource Files A 2 Using Oracle Terminal to Remap Oracle Forms Key Mappings A 2 Oracle Forms Runtime Key Bindings A 8 Oracle Forms Logical Attributes A 13 Using Oracle Terminal to modify Oracle Forms Logical Attributes A 16 Edit Attribute Node Options A 18 Logical Attribute Descriptions A 20
A1
associate a key sequence with an application function by defining a key binding associate a key sequence with an Oracle Forms key trigger by defining a key binding modify the visual appearance (face, pattern, color, etc.) of an Oracle Formsspecific element
Note: Resource file names are platformspecific. On MS Windows, the look and feel of an Oracle Forms application is defined by the resource file, FMRUSW.RES. For more information about platform specific resource files, refer to the Oracle Forms documentation for your operating system.
A2
Note: On some platforms, the [Help] key binding cannot be remapped. For example, on MS Windows, [Help] is mapped to the F1 key and cannot be remapped. To remap an Oracle Forms key binding: 1. Start Oracle Terminal. The Open dialog appears. 2. Open the appropriate Oracle Forms resource file (on MS Windows, open FMRUSW.RES). For more information about platformspecific resource files, refer to the Oracle Forms documentation for your operating system. Oracle Terminal appears.
Note: Before modifying an Oracle Forms resource file, you should create a backup copy.
A3
3.
Choose Functions>Edit Keys. The Key Binding Editor appears and lists Oracle Forms key bindings (Designer and Runform) by category: windowssqlforms, runform, help, editor, listvalues, logon, aflotus, normal, debugger, databaseerror, etc.
For more information about Runform key binding groups, refer to Oracle Forms Runform Key Bindings later in this chapter. 4. Doubleclick on a category and modify the desired Action and Binding.
A4
For example, to modify the key mapping for [Show Keys], doubleclick on windowssqlforms, specify the desired key binding for Show Keys, then click OK. Note: Key bindings must be unique. When you define a key binding, verify it against each bind category to ensure uniqueness. In addition, there are functions which have multiple key bindings. For example, [Accept] is mapped to both F10 and the Return key, depending on the context. As a result, in order to consistently bind a sequence of keys with a function, you must modify the key binding for each instance. 5. 6. Choose File>Save to save your modifications. Choose Functions>Generate to generate your modifications and to create a new resource file, which incorporates the changes you made to the key binding. An alert appears, informing you that your resource file has been successfully generated. Accept the alert. Note: If you receive an error message instead, consult your Oracle Terminal Users Guide. 7. 8. Choose File>Save to save your changes to the new resource file. Run Oracle Forms to use your new key binding.
A5
Using Oracle Terminal to Define Key Bindings for KeyFn and KeyOther Triggers
When you create a KeyFn or KeyOther Triggers, you must use Oracle Terminal to associate a key with your KeyFn or KeyOther function. Creating a key binding for your trigger allows it to fire when the operator presses the key sequence associated with your trigger. 1. 2. In the Oracle Forms Designer, create your KeyFn or KeyOther trigger. Using Oracle Terminal, open the appropriate Oracle Forms resource file (on MS Windows, open FMRUSW.RES). For more information about platform specific resource files, refer to the Oracle Forms documentation for your operating system. Oracle Terminal appears. 3. 4. 5. Choose Functions>Edit Keys to invoke the Key Binding Editor. In the Key Binding Editor, doubleclick on windowssqlforms to invoke the Key Binding Definition window. Click on the Insert Row button and then enter the action that corresponds to your KeyFn or KeyOther trigger. (The chart below applies only to MS Windows.)
KeyFn Trigger KEYF0 KEYF1 KEYF2 KEYF3 KEYF4 KEYF5 KEYF6 KEYF7 KEYF8 KEYF9 MSW Action User Defined Key 0 User Defined Key 1 User Defined Key 2 User Defined Key 3 User Defined Key 4 User Defined Key 5 User Defined Key 6 User Defined Key 7 User Defined Key 8 User Defined Key 9 MSW Code 82 83 84 85 86 87 88 89 90 91
A6
6.
Specify a key binding for your KeyFn trigger, then click OK. For example, you could enter:
Action User Defined Key 3 Binding Control+F2
Note: Key bindings must be unique. When you define a key binding, verify it against each bind category to ensure uniqueness. 7. 8. Click the Product Actions button to invoke the Product Actions Editor. Doubleclick on the sqlforms category. The Product Action Definition window appears. 9. Click on the Insert Row button, enter the Action, Code, and Description for your KeyFn trigger, then click OK. For example, if you create a KEYF3 trigger that invokes a help system, enter the following on MS Windows:
Action User Defined Key 3 Code 85 Description [Help System]
10. Dismiss the Product Action and Key Binding Editors by clicking on the OK buttons, then choose File>Save. 11. Choose Functions>Generate to generate your modifications and to create a new resource file, which incorporates the additions you made. 12. Choose File>Save to save your changes to the new resource file. 13. (Optional) Within the Forms Designer, set the Show Keys property for your key trigger to True if you want the key binding for your trigger to appear in the Show Keys window.
A7
windowssqlforms Show Keys Help Accept Cancel Exit Refresh help: Accept Up Down Scroll Up Scroll Down Scroll Left Scroll Right editor: Clear Item Search/Replace Search Next Occurrence Toggle Insert/Replace 3 1200 1201 1203 Control+End 1000 1306 1307 1302 1303 1304 1305 Return UpArrow DownArrow PageUp PageDown LeftArrow RightArrow 1003 1004 1000 1001 1002 1005 Control+F1 F1 F10 Escape Control+q
A8
Action/Function
MSW Code
listvalues: Delete Backward Pop Criteria Accept Page Up Page Down Scroll Left Scroll Right Scroll Up Scroll Down Change Focus logon: Next Item Previous Item aflotus: Accept Accept Accept Cancel Exit Previous Item Previous Item Next Item Next Item Up Delete Backward normal Commit Next Item Previous Item 1000 1 2 Tab Shift+Tab 1000 1000 1000 1001 1002 1403 1403 1404 1404 1405 1406 DownArrow Return F10 Escape Control+q LeftArrow Shift+Tab RightArrow Tab UpArrow Backspace 1400 1401 1303 1301 1000 1302 1303 1304 1305 1306 1307 1308 Backspace F9 Return PageUp PageDown LeftArrow RightArrow UpArrow DownArrow Tab
A9
Action/Function Clear Item Up Down Scroll Up Scroll Down Edit Search Toggle Insert/Replace Select Delete Backward Return List of Values Next Primary Key Clear Record Delete Record Duplicate Record Insert Record Next Set of Records Next Record Previous Record Clear Block Block Menu Next Block Previous Block Duplicate Item Clear Form Enter Query Execute Query Display Error Print Count Query Hits Update Record User Defined Key0 User Defined Key1
MSW Code 3 6 7 12 13 22 24 25 26 16 27 29 61 62 63 64 65 66 67 68 69 70 71 72 73 74 76 77 78 79 80 81 82 83
MSW Key Binding Control+u UpArrow DownArrow DownArrow DownArrow Control+e Control+s Return Backspace Return F9 Shift+F3 Shift+F4 Shift+F6 F4 F6 Control+> Shift+DownArrow Shift+UpArrow Shift+F5 F5 Control+PageDown Control+PageUp Shift+F7 F7 F8 Shift+F1 Shift+F8 Shift+F2
A 10
Action/Function User Defined Key2 User Defined Key3 User Defined Key4 User Defined Key5 User Defined Key6 User Defined Key7 User Defined Key8 User Defined Key9 Clear EndofLine Debug Toggle Query Mode Redefine Username/ Password Where Display Debug Mode Application Menu Previous Menu Main Menu Enter>1 OS Command Enter>2 OS Command Background Menu 1 Background Menu 2 Background Menu 3 Background Menu 4 Background Menu 5 Background Menu 6 Background Menu 7 Background Menu 8 Background Menu 9 Background Menu 10 Enter Application Parameters Enter Menu Parameters
MSW Code 84 85 86 87 88 89 90 91 92 93 94 11001 11002 11003 11004 11005 11006 11007 11008
Show Background Menu 11009 1101 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021
Control+/ Control+1 Control+2 Control+3 Control+4 Control+5 Control+6 Control+7 Control+8 Control+9 Control+0 Control+F6 Control+F5
A 11
Action/Function Accelerator1 Accelerator2 Accelerator3 Accelerator4 Accelerator5 Display Full Screen Menu
A 12
accept Oracle Forms default attributes define custom visual attributes define logical attributes using Oracle Terminal define display attributes using your window manager
In many cases, depending on the method chosen, you can create an attribute that overrides an attribute defined at a higher level. When defining object attributes, consider the following rules regarding attribute precedence: 1. Window manager (lowest level) Window manager definitions take precedence over Oracle Terminal definitions, visual attributes defined in the Oracle Forms Designer, local environment variable definitions (ORACLE.INI, CONFIG.ORA, etc.), and default Oracle Forms attributes.
A 13
For example, on MS Windows, color attributes for buttons are handled exclusively by Windows. Any color attributes that you create and apply to buttons in the Oracle Forms Designer have no effect on buttons. To change the color attributes of a button in a Microsoft Windows environment, use the MSW Control Panel facility. 2. Oracle Terminal definitions Oracle Terminal definitions take precedence over visual attributes defined in the Oracle Forms Designer, local environment variable definitions, and default Oracle Forms attributes. For example, assume that you create a custom visual attribute for the text items in your form so that text items appear gray. Assume also that you use Oracle Terminal to define all queryable items as cyan. When you run your form, all text items appear gray, but when you invoke Enter Query mode, text items appear cyan. In this example, the Oracle Terminal definition takes precedence and overrides the higher level attribute (the custom visual attribute created at design time). 3. Visual attributes created within the Oracle Forms Designer Designercreated visual attributes take precedence over local environment variable definitions (ORACLE.INI, CONFIG.ORA, etc.) and default Oracle Forms attributes. For example, assume that you create and apply a named visual attribute to the text items in your form. Assume also that you define the FORMS45_DEFAULTFONT local environment variable in CONFIG.INI so that item labels are displayed with 10 point Courier. At runtime, your named visual attribute takes precedence, and Oracle Forms displays all text items according to the properties defined by your named visual attribute. 4. Local environment variable definitions Local environment variable definitions (ORACLE.INI, CONFIG.ORA, etc.) take precedence over default Oracle Forms attributes.
A 14
For example, if you edit your ORACLE.INI file and define the default font (FORMS45_DEFAULTFONT) as 10 point Courier, Oracle Forms displays item labels as 10 point Courier. In this example, the default font in ORACLE.INI takes precedence and overrides the default font attributes for items. 5. Oracle Forms default attributes (highest level) Oracle Forms applies default attributes to every object. At runtime, Oracle Forms looks up the specific color, pattern, and font characteristics for a particular object and then displays it with its default attributes.
A 15
3.
4.
Select cm_logicals or form_logicals from the Attribute List pop list field. Oracle Terminal displays the logical attributes associated with your selection.
A 16
5.
Select the desired attribute from the Attribute field, then click on the Edit button. Oracle Terminal displays the Logical Attribute Editor.
6.
Select the desired node and then click on the Edit Attributes button. The Edit Attribute Node window appears.
A 17
7.
Define the desired attributes. For example, you can define the pattern, color, size, style, and weight of the desired logical attribute. For more information about options in the Edit Attribute Node window, see Edit Attribute Node Descriptions later in this chapter.
8. 9.
After making the desired modifications, click on the Apply Font button. Save your modifications by choosing File>Save.
For more information on changing visual attributes, see the Oracle Terminal Users Guide.
Font Attributes
Font Attributes include:
At runtime, Oracle Forms passes these settings to the window manager. If the font that you specify is unavailable in the runtime operating system, Oracle Forms uses the font that most nearly matches the characteristics of the font specified.
A 18
Foreground and Background Color Color is applied to objects in two layersa foreground layer and a background layer. You specify the color of each layer by setting the Foreground Color and Background Color attributes. Pattern You can set the Pattern attribute to any of the predefined patterns available on your system. Patterns are identified by name. For example, the pattern named 45thinline is a pattern of thin, diagonal lines on a solid background. How Fill Pattern Affects Color Attributes Oracle Forms renders the selected pattern in the foreground and background colors applied to an object. The current pattern selection determines how color is applied:
When the current pattern is Solid (the black square in the pattern palette), the object displays in the color specified by the Foreground Color attribute. When the current pattern is Transparent (the white square in the Layout Editor pattern palette), the object displays in the color specified by the Background Color attribute. When the current pattern is Clear, the object is transparent, and neither the foreground color or background color is applied. Note: The Clear pattern is not valid for items. For best results, use the Transparent pattern for items (the solid white square in the Layout Editor pattern palette).
When the current pattern is any other pattern, the black elements of the pattern are displayed in the current foreground color and the white elements of the pattern are displayed in the current background color.
A 19
Cm_Logicals
Use Oracle Terminal to change the defaults for the Oracle Formsspecific visual attributes for charactermode terminals, which are listed below.
Attribute Name ToolkitDisabled ToolkitEnabled ToolkitCurrent ToolkitDisabledMnemonic ToolkitEnabledMnemonic ToolkitCurrentMnemonic NormalAttribute Normal Bold Boldtext Boldinverse Underline Boilerplate WindowTitleCurrent Menu Submenu Fullscreentitle Menutitle Menusubtitle Menubottomtitle MenuItemEnable MenuItemDisabled MenuItemSelect MenuItemEnableMnemonic MenuItemDisableMnemonic Context Where Attribute Is Used Generic attribute Generic attribute Generic attribute Generic attribute Generic attribute Generic attribute Normal background for windows Text item Bold for all items (including check boxes) Boilerplate Inverse bold for all items Underline for all items Constant text Title of active window Selected menu Selected submenu Screen title Current menu title Current menu subtitle Current title at bottom of menu Enabled, noncurrent menu item Disabled menu item Current menu item Mnemonic of an enabled menu item Mnemonic of a disabled menu item
A 20
Attribute Name MenuItemSelectMnemonic TextControlCurrent Fieldcurrent TextControlNonCurrent Fieldnoncurrent TextControlSelect Fieldselectedcurrent Fieldselectednoncurrent Fieldqueryable PushButtonDefault PushButtonNonDefault Buttonnoncurrent Buttoncurrent Alert AlertIcon AlertMessage AlertBackground Listtitle ListItemSelect ListItemNonSelect ListPrefix ScrollThumb
Context Where Attribute Is Used Mnemonic of the current menu item Current field or text editor Color for current text item Disabled or noncurrent field or text editor Color for text item that is not currently selected Selected text in an enabled field or text editor Currently selected text item Text item that is not currently selected Field that operator can query Default or current button Button that is not default Noncurrent button Current button Alert text Icon in an alert window Message text in an alert window Alert background List of Values (LOV) title Selected item in a text list Unselected item in a text list List prefix Elevator box on scrollbar
Forms_Logicals
Use Oracle Terminal to change the GUI defaults for the Oracle Formsspecific visual attributes, which are listed below.
Attribute Name TextControlFailValidation ItemQueryDisabled Context Where Attribute Is Used Text item that fails validation Text item that is explicitly disabled by the operator, so it cannot be included as query criteria Message appearing on status line
StatusMessage
A 21
Attribute Name StatusHint StatusEmpty StatusItems Scrollbarfill, Inverse, Inverse underline, Boldunderline, Bold inverseunderline
Context Where Attribute Is Used Hint appearing on status line Status line with no text Indicators (lamps) on status line These logical attributes are not unique to Oracle Forms. As a result, these logical attributes can be overridden by the visual attributes defined by the window manager.
A 22
APPENDIX
About National Language Support B 2 Character Encoding Schemes B 4 Language and Territory Default Format Masks B 10 Oracle Forms Interface Translation B 14 Using the Oracle Translation Manager Approach B 15 Using the Runtime Language Switching Approach B 16 Using PL/SQL Libraries for Strings in Code B 17 Using Bidirectional Support B 18
B1
Support for national language character encoding schemes Support for language and territory conventions Interface translation
This combination of support at the character level, the data display level, and the interface level ensures that your forms will be usable in most European, Middle Eastern, and Asian languages, including multibyte character encoding schemes and bidirectionality. Designing and deploying multilingual Oracle Forms applications requires a twopart strategy:
translating the Oracle Forms user interface translating the applicationspecific messages
In general, there are two types of applicationspecific data youll need to translate:
translatable text, such as form menus, boilerplate text, item labels, messages, and hints defined on item property sheets strings in triggers and procedures, including alerts and messages defined in triggers
The Oracle Translation Manager product helps you translate the translatable text strings in the Oracle Forms user interface into multiple languages. (Translatable text appears as a hexadecimal representation in the .FMT file in order to support multibyte character sets, so you cannot translate it directly). You can use Oracle Translation Manager to assist with translation for almost all multilingual forms applications. Unless your application requires operators to toggle between languages at runtime, you can use Oracle Translation Manager and then generate separate executable files for each language. While the Oracle Translation Manager helps you find and translate strings in the user interface, the tools cannot pull out string constants in PL/SQL triggers and procedures. Manual translation is required for constant text within PL/SQL block, because that text is not clearly delimited, but is often built up from variables and pieces of strings.
B2
For a complete description of the Oracle Translation Manager and its translation tools, refer to the Oracle Translation Manager Users Guide.
NLS Architecture
National Language Support for Oracle Forms leverages off Oracles NLS architecture, which has two main parts:
Oracle Forms uses languageindependent features to handle manipulation of string data in an appropriate manner, depending on the language and territory of the runtime operator, and automatically format that data according to local dateandtime conventions. Isolating the languagedependent data allows your application to deal only with translating the strings that are unique to your application.
Error messages from the database Runtime error messages produced by Oracle Forms Messages and boilerplate text defined as part of the application
Oracles NLS handles translation for the first two categories. You, as the application developer, are responsible for translating the messages in the third category. This rest of this appendix outlines several approaches to producing multilingual Oracle Forms applications.
B3
B4
where: language territory Specifies the language and its conventions for displaying messages and day and month names. Specifies the territory and its conventions for default date format, decimal character used for numbers, currency symbol, and calculation of week and day numbers. Specifies the character set used for the UPPER, LOWER, and INITCAP functions. This argument also controls the character set used for displaying messages.
char_set
Examples:
B5
In most cases, setting a single value for NLS_LANG will meet your needs. However, if you need to use two sets of resource and message files on the same machine at the same time, two other environment variables are available:
DEVELOPER_NLS_LANG USER_NLS_LANG
Use these two variables, instead of the single NLS_LANG, in these circumstances:
If you are a developer who prefers to use the Designer in English, but you are developing an application for another language, the two variables allow you to use different language settings for the Designer and Runform. If you are a developer creating an application to run in a language for which a locallanguage version of the Designer is not currently available.
Note: If these environment variables are not specifically set, they take their default values from NLS_LANG, so for the rest of this discussion, the language environment variable will refer to the current language environment variable, whether its set using NLS_LANG or one of the other variables.
B6
NLS_SORT NLS_NUMERIC_CHARACTERS
SWEDISH
decimal ., character and (specify both group separator characters) for numeric characters local currency symbol (L) ISO currency symbol (C) $ FRANCE (territory name)
decimal ., character and (specify both group separator characters) for monetary characters separator for a list of items (if comma is used within items) debit amounts credit amounts :
*NLS_LIST_SEPARATOR
DB CR
*These environment variables are supported for Oracle7.2 only. For example, to specify the NLS_DATE_FORMAT in a Windows environment, add this setting to your ORACLE.INI file:
NLS_DATE_FORMAT=MM/DD/YYYY
For more information about NLS environment variables, see the Oracle7 Server Reference, Chapter 3, National Language Support.
B7
Because both USER_NLS_LANG and DEVELOPER_NLS_LANG default to the value of NLS_LANG, the Oracle Forms NLS parameters will hold the value of NLS_LANG if either variable is not specifically set. Both Oracle Forms NLS parameters have four variations, to allow you to retrieve either the complete environment variable or a specific portion of it. This table shows the four parameters of the GET_APPLICATION_PROPERTY builtin that return the USER_NLS_LANG environment variable:
Parameter USER_NLS_LANG USER_NLS_LANGUAGE USER_NLS_TERRITORY USER_NLS_CHARACTER_SET Returns Entire USER_NLS_LANG variable Language portion only Territory portion only Character set portion only
To retrieve the DEVELOPER_NLS_LANG environment variable, call GET_FORM_PROPERTY, using the MODULE_NLS_LANG parameter. For more information on the GET_APPLICATION_PROPERTY and GET_FORM_PROPERTY builtins, see the Oracle Forms Reference Manual, Vol. 1, Chapter 3, Builtins.
B8
Determine the character set most widely used at runtime. Generate with the NLS environment variable set to that character set.
Tip: If you want to use a font that belongs to a character set other than the font set in the NLS environment variable, set it through the Layout Editor Format>Font dialog, rather than the Properties window.
B9
day and month names number formatting date formatting currency formatting sorting sequence for character data
The language environment variable establishes not only the language used for the Oracle Forms interface (both Designer and Runtime), but also the set of default format masks used to display that data, unless explicit format masks override the default. As a form developer, you also have additional NLSrelated format mask characters available if you choose to override the default display masks.
in the Designer: When Oracle Forms displays default values for items, ranges, or parameters at runtime: If a user enters data into a text item whose type is territoryspecific, such as DATE or NUMBER
B 10
For example, suppose that you create an item of type DATE in the Designer, and then enter a default value of 20DEC93, using the NLS_LANG default of American_America. If you then change NLS_LANG to Norwegian, the default value for the item will automatically change to 20.12.1993. Tip: For implicit datatype conversions, PL/SQL always expects items in the American_America default format (such as DDMONYY), so if you use an item whose type is territoryspecific in PL/SQL, you will need to specify the correct format masks. Oracle recommends that you use TO_DATE to translate territoryspecific items in PL/SQL. Examples: For NLScompliant applications, avoid hardcoding a string containing a month name. However, if a hardcoded month name is essential, avoid using the COPY builtin: If you use COPY, the month name may be incorrect, depending on which language is specified. (To specify a date in a library, use a variable for the date and COPY will work.) Languagedependent example (not recommended):
:emp.hiredate := 30DEC93; copy (30DEC90,emp.hiredate);
Instead, use TO_DATE, as shown in the following example. Languageindependent example (recommended):
:emp.hiredate := to_date(30121990,DDMMYYYY);
B 11
While working with date and currency fields for multilingual applications, you will want to consider:
Whether to make all screen items (boilerplate, text items, interface objects such as buttons and lists of values) longer to accommodate text translation and languagespecific conventions for numeric display. For example, if you develop an application in USEnglish with a 9character DDMONYY date, and plan to run the application in Norwegian, youll want to increase the size of the field to allow for the NLS translation to a 10character Norwegian date: DD.MM.YYYY. By default, Oracle Forms increases the maximum length but not the display length for dates. You must explicitly increase the display length, if necessary.
Whether you need to use the NLSrelated format mask characters to create special format masks, or if the default format masks invoked by NLS_LANG are sufficient.
For more information about NLSrelated format mask characters, see the Format Mask property description in the Oracle Forms Reference Manual, Vol. 2, Chapter 5, Properties.
B 12
Prompt on left of field: Allow 30% expansion room to left of prompt. Prompt above field: Allow 30% expansion room to right of prompt. Buttons, checkboxes, radio groups and poplists: Allow for 30% expansion. Form titles: Size any bounding box so the title can expand to right by 30%. Displayonly fields: Size 30% wider than needed for base language. All widgets: Make widgets large enough to accommodate translation. For example, buttons need to be large enough to hold translated labels. (Check button height as well as length, to be sure the height of the button will accommodate the tallest character you need to use. For example, calculate pixels needed to render Kanji characters.)
B 13
messages menus and menu items dialog boxes prompts and hints alerts
When you start the Designer in a different language, youll see prompts in that language. Note: It is not necessary to translate numbers or dates in default values, ranges, and parameters, because Oracle Forms translates them automatically, based on the value of the language environment variable.
Message Files
When you change languages, Forms searches for the correct message file, based on the NLS_LANG variable. If Forms does not find a corresponding message file, it defaults to the US message file. Message file names specify both the Oracle Forms component and the language used. For example:
FMDUS.MSB contains default (American) Designer messages FMGUS.MSB contains default (American) Generate messages FMFUS.MSB contains default (American) Runform messages FMFI.MSB contains Italian Runform messages FMFD.MSB contains German Runform messages
For more information about message file names, see the Installation and User Guide for your platform.
B 14
Create one basic form definition (.FMB, .MMB) in the source language. Use the Oracle Translation Manager to extract strings for translation, allow translation into one or several languages, and then store the strings back into the form definition. Manually translate standard messages in PL/SQL libraries. Use the Oracle Forms Generate component to generate an executable version of the form for each target language.
At runtime, the form is displayed in the appropriate language, depending on which translated .FMX file is first in the search path you set in the ORACLE.INI parameter, FORMS45_PATH. Advantages: This is the simplest way to implement multiple language applications quickly. With this approach, you can use the Oracle Translation Manager translation tools for maximum efficiency. If you have a stable application, this approach will work well for you. For example, if you created an application in four languages and then needed to change the text of a button label, you would make the change in the Designer, save the change in the .FMB file, return to the Oracle Translation Manager translation tools to translate the new button label, then insert the new messages into the .FMB file and regenerate to create an .FMX file containing the new button. Disadvantages: If your applications must support multiple languages simultaneously, you must use the runtime language switching approach, instead.
B 15
Develop the entire form for one language, including libraries. Manually translate each library. Design boilerplate labels as appropriatelysized display items that are dynamically populated at runtime.
Oracle Forms supports attaching multiple libraries, so you can use one library specifically for messages that will be translated, and other libraries for other purposes. Advantages: The main advantage of this approach is it allows you to support sophisticated applications in which the forms may be highly dynamic. In these cases, this approach avoids some maintenance problems, because you do not have to generate separate files for each language each time the form changes. Disadvantages: This approach is more complicated, because it involves considerable effort to create the languagespecific message storage, population, and maintenance involved and to perform the translation manually. For example, you would set up a WHENNEWFORMINSTANCE trigger to set the labels for each button, pulling the correct labels from an attached library, based on the value of the NLS environment variable.
B 16
A routine like this could be used anywhere a character expression would normally be valid: for example, to display an alert with the appropriately translated application message you might include the following code in your form:
Change_Alert_Message(My_Error_Alert, nls_appl_mesg(1001)); n := Show_Alert(My_Error_Alert);
To change the application to another language, simply replace the PL/SQL library containing the nls_appl_mesg function with a library of the same name containing the nls_appl_mesg function with translated text.
B 17
If the application needs to support multiple languages simultaneously, the function above could accept an additional parameter indicating the desired language and the code would then contain an additional level of IF...THEN...ELSIF...ELSE...END IF to handle the various languages.
layout direction, which includes displaying items with labels at the right of the item and correct placement of check boxes and radio buttons reading order, which includes righttoleft or lefttoright text direction alignment, which includes switching pointoforigin from upper left to upper right initial keyboard state, which controls whether Local or Roman characters will be produced automatically when the operator begins data entry (the operator can override this setting)
In addition to the NLS_LANG environment variable, bidirectional applications may use two additional NLS_LANG environment variables:
DEVELOPER_NLS_LANG USER_NLS_LANG
For more information, refer to About the NLS_LANG Environment Variables, earlier in this chapter. Four properties are used to specify the appearance of objects in bidirectional applications:
B 18
Direction is an umbrella property that provides as much functionality for each object as possible. For all objects except text items and display items, the Direction property is the only bidirectional property, and its setting controls the other aspects of bidirectional function. (List items, however, include an Initial Keyboard State property.) Text items and display items do not have a Direction property; instead, you can specifically set Alignment, Reading Order, and Initial Keyboard State properties for these items. When the bidirectional properties are set to Default, those properties inherit their values from the natural writing direction specified by the NLS language environment variable. In most cases, this will provide the desired functionality. You only need to specify the bidirectional properties when you want to override the inherited default values. This chart summarizes inheritance for bidirectional properties.
Default Setting Derives Value From This Object Form All objects, such as Alert, Block, LOV, Window, and Canvasview NLS environment variable Form
All items, such as Canvasview Text Item, Display Item, Check Box, Button, Radio Group, and List Item
For more information, see the property descriptions for Direction, Alignment, Reading Order, and Initial Keyboard State in the Oracle Forms Reference Manual, Vol. 2, Chapter 5, Properties. Most properties related to bidirectional function are programmatically gettable and settable. For more information, see the corresponding builtin subprogram descriptions. For example, for information about getting the value of the Direction property for buttons, consult the description for GET_ITEM_PROPERTY in the Oracle Forms Reference Manual, Vol. 1, Chapter 3, Builtins. Oracle Reports and Oracle Graphics also implement bidirectional support, so you can have reports and graphics that include both local and Roman languages.
B 19
B 20
APPENDIX
About PECS C 2 Collecting Performance Data on Oracle Forms Events C 4 Collecting Performance Data on ApplicationSpecific Events C5 Collecting Object Coverage Data C 10 Collecting Line Coverage Data C 10 Using the PECS Assistant C 11 PECS Builtins C 16
C1
About PECS
As an Oracle Forms developer or a system administrator, you may have questions about the performance of both Oracle Forms and your own applications. Oracle Forms Performance Event Collection Services (PECS) will help you answer questions such as these:
How much elapsed time does it take to use LOVs on three fields in my form? How long does it take to execute these triggers? How many invoices per hour can we produce? Have I tested all the triggers in my form? Have I tested all the lines of my PL/SQL code?
PECS builtins, used to define applicationspecific events PECS Assistant, an Oracle Forms application you can use to load and view PECS data PECS reports, which let you view the results of your tests on line or print out hard copy
C2
PECS Measurements
PECS is a lowoverhead performance measurement tool you can use to perform the following tasks:
Measure resource usage for Oracle Forms events The simplest way to use PECS is to measure only Oracle Forms events. If you only want to measure Oracle Forms events, you do not need to add PECS builtins to your PL/SQL code because Oracle Forms includes predefined PECS events to measure the performance of objects such as triggers, windows, canvases, LOVs, and alerts.
Measure resource usage for applicationspecific events (CPU time and elapsed time) If you add calls to PECS builtins to your PL/SQL code, you can measure the performance of applicationspecific events, as well as Oracle Forms events.
Locate performance problems Measure coverage When youre testing an Oracle Forms application, you may be interested in what kind of coverage your test cases provide. The PECS Object Coverage Report gives you information about the coverage provided by your current test suite. The PECS Line Coverage Report provides information about coverage of PL/SQL code.
C3
The performance of the entire application, triggers, and LOVs The coverage of procedures, windows, canvases, editors, and alerts, and linebyline coverage for PL/SQL code
The process has three steps: 1. Run your application with PECS on to collect performance data in a .DAT file, using the following command:
f45run module=myform userid=scott/tiger pecs=on
Or, at the Runform Preferences dialog Collect PECS data? option, select ON. Running Oracle Forms with PECS creates a PECS binary file with a default name of the module name with a .DAT extension:
myform.dat
The data is written to a file rather than directly to the database. 2. Load data from the .DAT file and your form into the database. Use the PECS Assistant to load both your form and the PECS binary (.DAT) file into the database. For information about the PECS Assistant, see Using the PECS Assistant later in this chapter. 3. Analyze the data. Once the PECS database file is created, review the results:
Use the PECS Assistant Data or Summary windows to view the results on line, or Run the Performance, Object Coverage, or Line Coverage Reports and view the results on line or print out hard copy
Although you dont need to use the PECS builtins to collect performance data on Oracle Forms events, you can use the builtins to limit the focus of your PECS experiments. For example, if you are only interested in LOV events, you can use the PECS.DISABLE_CLASS builtin to turn off all events except the LOV events.
C4
Group applicationspecific events. Define the events you want to measure, using PECS builtins. Run your application with PECS. Load the form and the PECS data from the file into the database. Analyze the data.
A Banking class, composed of three events: Deposit event Withdraw event Transfer event
A Customer class, composed of three events: AddCustomer event DeleteCustomer event ChangeCustomer event
C5
Start PECS: At design time, by adding the PECS.COLLECTOR builtin to your application (to collect data on applicationspecific events only), or At runtime, by invoking PECS from the command line (to collect data on Oracle Forms events, as well as on applicationspecific events)
Add any classes and events you need with the PECS.ADD_CLASS and PECS.ADD_EVENT builtins Enable the class or specific event you want to measure using the PECS.ENABLE_CLASS builtin Define the events you want to measure: Bracket them with the PECS.START_EVENT and PECS.END_EVENT builtins, or Mark them with PECS.POINT_EVENT
To invoke PECS from the command line, set PECS=ON for object coverage and PECS=FULL for object and line coverage. Note: You can use PECS builtins wherever you can use other Oracle Forms builtins: triggers, usernamed routines, menu PL/SQL commands, and stored procedures. While you cant directly measure the duration of a PL/SQL procedure, you can define a trigger that calls the procedure and then measure the duration of that trigger. For more information about the PECS builtins, refer to the section PECS Builtins later in this chapter.
C6
If you started PECS from the command line, the name of the PECS binary file defaults to the form name with a .DAT extension: myform.dat. If you started PECS by adding the PECS.COLLECTOR builtin to your application, the name of the PECS binary file defaults to the name of the first class you specified with the PECS.ADD_CLASS builtin: banking.dat.
Load the Form and the PECS Data into the Database
Use the PECS Assistant application to load both your form and the PECS binary file into the database. For more information, see Using the PECS Assistant later in this chapter. Note: Unless you want coverage statistics, PECS does not require that you store your form in the database. However, PECS depends on some of the tables that are created automatically by the Forms 4.5 table scripts that are run during installation when you choose the Create database tables option. If you did not choose that option, you or your DBA must logon as SYSTEM and run those SQL scripts, which are found in the Oracle Forms SQL directory.
Use the Data or Summary windows to view the results on line, or Run the Performance, Object Coverage, or Line Coverage Reports and view the results on line or print out hard copy
C7
Next Steps
Once youve analyzed the data, you may decide to proceed in any of several directions:
If you are debugging, you may want to change the application and run the same tests again. If you are testing performance, you may want to create multiple runs of the same test, average the statistics, and compare results with previous tests. If you are testing coverage, you may want to change the test to add test cases to cover more conditions, then rerun the test and compare results with earlier tests.
For more information about using PECS data files, see Using .DAT Files later in this chapter. Example: Assume that youve decided to measure both internal Oracle Forms events and three applicationspecific events: Deposit, Withdrawal, and Transfer. This example illustrates adding the PECS builtins to define these events to PECS. (Because you want to measure both types of events, you could have started PECS on the command line, but this example includes starting PECS with the PECS.COLLECTOR builtin for purposes of demonstration.)
PACKAGE globals IS /* We will create a package of global variables instead of /* local variables because the pecs.event and pecs.class types /* may be spread across various procedures, triggers, and /* even forms. /* /* Add the classes. /* banking PECS.class := PECS.Add_Class(Banking); myform PECS.class := PECS.Add_Class(PECS.FORMS); /* /* Add the events for the class Banking. /* No need to add events for the class Form /* because they are predefined internal events. withdraw pecs.event := PECS.Add_Event(banking,Withdraw); deposit pecs.event := PECS.Add_Event(banking,Deposit); transfer pecs.event := PECS.Add_Event(banking,Transfer); END globals; */ */ */ */ */ */ */
*/ */ */ */
C8
/* /*
*/ */
BEGIN PECS.Collector(COLLECT_ON); /* /* /* */ */ */
PECS.Enable_Class(GLOBALS.banking); /* /* After the forms class has been enabled, /* internal forms events will be measured. /* NOTE: This line is not needed if you use the /* PECS=on command line option. PECS.Enable_Class(GLOBALS.myform); END; PROCEDURE do_withdraw /* /* /*
*/ */ */ */ */
*/ */ */
PECS.End_Event(GLOBALS.withdraw,withdraw_handle); END;
C9
Generate the form with debug=ON. Run with PECS=FULL. In the PECS Assistant, select the Line Coverage check box. Select the Line Coverage Report.
Note: To collect line coverage data, you must use the PECS command line option (PECS=FULL) rather than invoking PECS with the PECS.ENABLE_CLASS builtin.
C 10
For an overview of each window and detailed information about each field, click on the Help button.
C 11
The PECS Assistant displays the Main window. You can navigate to other windows using the buttons or the commands on the Windows menu. 2. Click Load. The PECS Assistant displays the Load window. 3. Fill in the PECS Data section to select the experiment you want to load into the database. If the file does not exist, an Open error message is displayed. Note: Fill in the Connect String section only if you want to use a connect string that differs from the one you used to start the form. For more information, press Help. 4. Check the appropriate check boxes. The Load PECS data in the database and Summarize data check boxes are checked, as default. If you want to include line coverage data, check the Prepare for Line Coverage check box. Note: Preparing for line coverage is a timeconsuming task, so the busy cursor will be displayed for a while. If you want to delete the detailed data once the summary files are created, check the Delete details after summary check box. 5. Click Start. PECS displays confirmation messages for each check box youve selected. Once youve accepted each confirmation, PECS processes the data, displaying status messages in the Status area during processing, and prepares the results for you to examine. 6. To view the results, choose Navigation>Experiment or Navigation>Class.
C 12
7.
From the Experiment or Class window, query to select the experiment or class you want to review. PECS displays the results of your query.
8. 9.
Highlight the specific experiment or class. Click Zoom In. PECS displays the Summary window, showing the summarized version of the data. The Summary window displays the information in a format similar to the PECS reports.
10. Click Zoom In again to examine the detailed results of a PECS experiment. PECS displays the detailed results in the Data window.
PECS Reports
To run the PECS reports, choose the Reports menu:
Choose the Performance Report to show elapsed time and CPU time. Choose the Object Coverage Report to show that certain events or occurrences have been reached. Choose the Line Coverage Report to show coverage of your PL/SQL code.
By default, the Performance Report displays data in the sequence of columns as displayed in the Data or Summary screen. To change the sequence in the report, change the Order By clause in the Data or Summary Performance Report window.
PECS Maintenance
To review data about classes and experiments you defined, return to the Main window and click Class or Exp (Experiment):
Use the Class window to view data about the classes and events you defined using the PECS builtins. You can perform minimal maintenance on classes using this window. For instance, you can change class names and add version information.
Use the Experiment window to view data about the experiments and runs you defined using PECS builtins.
C 13
You can perform minimal maintenance on experiments using this window. For instance, you can change experiment names and add comment information. (You specified the experiment name earlier, in the Load window or on the command line using the n option.)
Experiment #1, Run #1: Produces the original A.DAT file. You evaluate the coverage results of Run #1, and decide to add more test cases to improve the coverage. Experiment #1, Run #2: Produces a new A.DAT file. When you also load the results of Run #2 to the database, check Summarize on the Load window to summarize the data from all runs of this experiment.
Using PECSLOAD
You can also access the PECS system directly from the command line, without using the PECS Assistant. Invoke the PECSLOAD utility from the command line to load the PECS binary file into the database. During PECSLOAD, both classes and events will also be saved to the database, if they are not already there. The syntax for the PECSLOAD command requires three arguments: the module name, the experiment name or number, and userID/password. Example 1: Using PECSLOAD with an experiment name:
PECSLOAD f mymod.dat n my_experiment scott/tiger
C 14
If the environment variable is not set, PECS uses the current working directory. If you issue the PECSLOAD command and receive an error message similar to Error opening file, probably PECS is searching for the data file and cannot find it. In this case, reissue the PECSLOAD command and provide the full pathname in place of the module name.
C 15
PECS Builtins
The PECS builtins allow you to define applicationspecific events to the PECS system:
To do this: Start and stop PECS Register classes and events Enable and disable classes Define event instances Use this PECS builtin: PECS.COLLECTOR PECS.ADD_CLASS PECS.ADD_EVENT PECS.ENABLE_CLASS PECS.DISABLE_CLASS PECS.START_EVENT PECS.END_EVENT PECS.POINT_EVENT
C 16
PECS.ADD_CLASS
Syntax: Builtin Type: Returns: Description:
PECS.ADD_CLASS(class_name); PECS.ADD_CLASS(class_type);
unrestricted procedure PECS.CLASS PECS.ADD_CLASS creates the class, or group of events, in PECS, and returns the ID for this class. Use this class ID to identify the class in future calls to PECS. The datatype of the class ID is PECS.CLASS. class_type Specifies the type of class to add. Valid numeric constant for this parameter: PECS.FORMS class_name Specifies Oracle Forms.
Parameters:
Specifies the name of the class to add. Specify the CHAR class name for applicationspecific classes that do not use one of the class types listed above.
Usage Notes:
If you started PECS by adding the PECS.COLLECTOR builtin to your application, the name of the PECS binary file defaults to the name of the first class you specified with the PECS.ADD_CLASS builtin: banking.dat. (If you started PECS from the command line, the name of the PECS binary file defaults to the form name with the .DAT extension: myform.dat.)
/* /* This will add the class FORMS /* forms_class pecs.class := PECS.Add_Class(pecs.FORMS); /* /* This will add the class Banking /* banking_class pecs.class := PECS.Add_Class(Banking); */ */
Example:
*/ */ */
C 17
PECS.ADD_EVENT
Syntax: Builtin Type: Returns: Description:
PECS.ADD_EVENT(class_id, event_type); PECS.ADD_EVENT(class_id, event_description);
unrestricted procedure PECS.EVENT PECS.ADD_EVENT adds an event to a specified class. For an Oracle Forms event, specify the event type from the list of Oracle Forms event types. For an applicationspecific event, specify the event using event_description, which must be unique among events in the class.
Parameters:
class_id
Specifies the ID of this class. The class ID is created with a call to PECS.ADD_CLASS, and is of datatype PECS.CLASS. For Oracle Forms events, specifies the event type. Valid numeric constants for this parameter are PECS.LINE, PECS.FORMS_TRIGGER, PECS.FORMS_LOV, PECS.FORMS_20TRIGGER (Oracle Forms V2style trigger event), PECS.FORMS_PROCEDURE, PECS.FORMS_ALERT, PECS.FORMS_CANVAS, PECS.FORMS_WINDOW, PECS.FORMS_EDITOR. For applicationspecific events, specify the event_type from the PECS_EVENTS table, or use the event_description parameter.
event_type
event_description
For applicationspecific events, specifies the event. The description is limited to 32 datatype CHAR characters.
*/ */
Example:
/* /* /*
This will add the event Withdraw. banking_class was previously defined by PECS.ADD_CLASS
C 18
PECS.COLLECTOR
Syntax: Builtin Type: Description:
PECS.COLLECTOR(collector_status);
unrestricted procedure Use PECS.COLLECTOR to turn PECS on or off. This builtin allows you to start PECS later, if you havent invoked PECS from the command line. PECS.COLLECTOR needs to be called only once per session. collector_status A NUMBER parameter that specifies whether PECS is on or off: PECS.COLLECT_ON Turns the collector on.
Parameters:
You dont need to use PECS.COLLECTOR if you turned PECS on using the command line option pecs=on. Although you can toggle the status of PECS.COLLECTOR, doing this may produce mismatched events. For example, if PECS is turned off after a trigger event has started, there may be no corresponding end event. During the loading of the .DAT file, PECS will detect this and issue a warning saying that a start event is missing an end event, or vice versa.
Example:
PECS.COLLECTOR(pecs.collect_on);
C 19
PECS.DISABLE_CLASS
Syntax:
PECS.DISABLE_CLASS(class_id); PECS.DISABLE_CLASS(class_id, event_type); PECS.DISABLE_CLASS(class_id, event_id);
unrestricted procedure To disable all of the events associated with a class, specify only the class_id:
PECS.DISABLE_CLASS(class_id);
To disable only a specific event, supply the class_id and the event_type or event_id:
PECS.DISABLE_CLASS(class_id, event_type); PECS.DISABLE_CLASS(class_id, event_id);
Parameters:
class_id
Specifies the ID of this class. The class ID is created with a call to PECS.ADD_CLASS, and is of datatype PECS.CLASS. For Oracle Forms events, specifies the event type. Valid numeric constants for this parameter are PECS.LINE, PECS.FORMS_TRIGGER, PECS.FORMS_LOV, PECS.FORMS_20TRIGGER (Oracle Forms V2style trigger event), PECS.FORMS_PROCEDURE, PECS.FORMS_ALERT, PECS.FORMS_CANVAS, PECS.FORMS_WINDOW, PECS.FORMS_EDITOR. Specifies the ID of this event name. The event ID is created with a call to PECS.ADD_EVENT, and is of datatype PECS.EVENT.
*/
event_type
event_id
Example:
/*
PECS.Disable_Class(forms_class, PECS.FORMS_LOV); /* /* /* Disable the Withdraw event for Banking_class. */ Banking_class was previously defined with PECS.ADD_CLASS */ Withdraw was previously defined with PECS.ADD_EVENT */
PECS.Disable_Class(banking_class, withdraw);
C 20
PECS.ENABLE_CLASS
Syntax:
PECS.ENABLE_CLASS (class_id); PECS.ENABLE_CLASS(class_id, event_type); PECS.ENABLE_CLASS(class_id, event_id);
unrestricted procedure To enable all of the events associated with a class, specify only the class_id:
PECS.ENABLE_CLASS(class_id);
To enable only a specific event, supply the class_id and the event_type or event_id:
PECS.ENABLE_CLASS(class_id, event_type); PECS.ENABLE_CLASS(class_id, event_id);
Parameters:
class_id
Specifies the ID of this class. The class ID is created with a call to PECS.ADD_CLASS, and is of datatype PECS.CLASS. For Oracle Forms events, specifies the event type. Valid numeric constants for this parameter are PECS.LINE, PECS.FORMS_TRIGGER, PECS.FORMS_LOV, PECS.FORMS_20TRIGGER (Oracle Forms V2style trigger event), PECS.FORMS_PROCEDURE, PECS.FORMS_ALERT, PECS.FORMS_CANVAS, PECS.FORMS_WINDOW, PECS.FORMS_EDITOR. Specifies the ID of this event name. The event ID is created with a call to PECS.ADD_EVENT, and is of datatype PECS.EVENT.
*/
event_type
event_id
Example:
/*
PECS.Enable_Class(forms_class); /* /* /* Enable the Withdraw event for Banking_class. Banking_class was previously defined with PECS.ADD_CLASS Withdraw was previously defined with PECS.ADD_EVENT */ */ */
PECS.Enable_Class(banking_class, withdraw);
C 21
PECS.END_EVENT
Syntax: Builtin Type: Description: Parameters:
PECS.END_EVENT(event_id, event_handle);
unrestricted procedure Marks the end of a PECS event. event_id Specifies the ID of this event name. The event ID is created with a call to PECS.ADD_EVENT, and is of datatype PECS.EVENT. Specifies handle of this event occurrence. The event handle is created with a call to PECS.START_EVENT, and is of datatype NUMBER.
event_handle
Example:
/* /* /*
Measure the performance of the Withdraw event */ Banking_class was previously defined with PECS.ADD_CLASS */ */
C 22
PECS.POINT_EVENT
Syntax: Builtin Type: Description:
PECS.POINT_EVENT(event_id, event_comment);
unrestricted procedure Use PECS.POINT_EVENT to determine whether an event was reached during code execution. event_id Specifies the ID of this event name. The event ID is created with a call to PECS.ADD_EVENT, and is of datatype PECS.EVENT. A CHAR comment to identify the event.
Parameters:
Use PECS.POINT_EVENT when you need to know only that a given applicationspecific event occurred, rather than its duration. You can use PECS.POINT_EVENT to gather coverage data for specific parts of your application where you insert PECS point events.
Start the Withdraw event . */ */
Example:
/* /* ...
... IF (do_withdraw = TRUE) then ... message(Success collecting data for event Withdraw); PECS.Point_Event(GLOBALS.withdraw,Withdraw Success); ELSE ... message(Error collecting data for event Withdraw); PECS.Point_Event(GLOBALS.withdraw,Withdraw Error); END IF;
C 23
PECS.START_EVENT
Syntax: Builtin Type: Returns: Description:
PECS.START_EVENT(event_id,event_ comment);
unrestricted procedure NUMBER Marks the beginning of a PECS event. PECS.START_EVENT returns a unique identifier for this occurrence of this particular event, which is needed to end the event. event_id event_comment Specifies the event ID. Datatype is PECS.EVENT. A CHAR comment to identify the event.
Parameters:
PECS.START_EVENT returns an identifier, or handle, to the event that must be used with PECS.END_EVENT to mark the end of the event.
/* Measure the performance of the Withdraw event */ /* Banking_class was previously defined with PECS.ADD_EVENT */ /* */ withdraw_handle := PECS.Start_Event(withdraw, Withdrawing Cash); . . /do the withdraw/ . PECS.End_Event(withdraw, withdraw_handle);
C 24
Index
B
Background Color, A 18 Beveling on Macintosh, 9 11 Bidirectional applications, B 18 Blocks Locking Mode property, 4 5 Transactional Triggers property, 4 15 Cursor Mode form property, 4 6 Custom item type, 11 3
D
Database constraints, 2 20 Database Trigger Editor, 2 18 error handling, 1 8 triggers, 2 14 Default parameter list, 5 24 Dotherightthing builtins, 4 12 Doublebyte characters, B 4 Doubleclick event, 6 4 Dynamic Data Exchange DDE connect/disconnect functions, 12 3 DDE datatype translation functions, 12 4 DDE support functions, 12 3 DDE transaction functions, 12 3 DDE.APP_BEGIN, 12 4 DDE.APP_END, 12 6 DDE.APP_FOCUS, 12 7 DDE.EXECUTE , 12 8 DDE.GETFORMATNUM, 12 9 DDE.GETFORMATSTR, 12 10 DDE.INITIATE , 12 11 DDE.POKE, 12 12 DDE.REQUEST, 12 13 DDE.TERMINATE, 12 14 exceptions, 12 16 MS Windows predefined formats, 12 15
C
C language foreign functions, 3 4, 13 4 C programs, calling Oracle Forms from, 8 22 CALL_FORM invoking, 5 2 restrictions with OPEN_FORM, 5 13 stack, 5 10 Capacity planning, C 3 Character mode aligning boilerplate text, 9 13 how to run in character mode, 9 12 portability, 9 12 restricted properties, 9 14 Chart items, 8 8 Closing independent form, 5 4 Color in portable applications, 9 7 COMMIT_FORM, 4 29 Coordinate System property, 9 6 Count Query processing, 4 20 Coverage measurement, C 3 CREATE_QUERIED_RECORD, 4 26
Index 1
E
Error handling, 1 8 Exception handling in triggers, 1 2 EXEC ORACLE statement, 3 11 EXEC SQL statement, 3 6 EXEC TOOLS GET CONTEXT statement, 3 10 EXEC TOOLS GET statement, 3 7 EXEC TOOLS MESSAGE statement, 3 9 EXEC TOOLS SET CONTEXT statement, 3 11 EXEC TOOLS SET statement, 3 8
Form Module Cursor Mode property, 4 6 Savepoint Mode property, 4 7 Form parameters, 5 23 FORM_FAILURE function, 1 5 FORM_FATAL function, 1 5 FORM_SUCCESS function, 1 5 FORM_TRIGGER_FAILURE exception, 1 6 FormModule type, 5 8 FORMS45_USEREXIT, 3 21
G F
F45XTB.DEF, 3 19 F45XTB.DLL, 3 17 Fill Pattern, A 18 FIND_FORM, 5 7 FMRUSW.RES resource file, A 3 Font aliasing, 9 9 Font attributes, A 18 Foreground Color, A 18 Foreign functions associating with PL/SQL subprogram, 13 7 building a DLL, 3 20 complex data types, 13 11 creating PL/SQL interface, 13 6 initializing foreign functions, 13 6 invoking foreign functions, 3 14, 13 9 mimicking with PL/SQL, 13 8 multiple DLLs, 3 21 nonORACLE, 3 4, 13 4 obtaining context from Oracle Forms, 3 10 OCI (ORACLE Call Interface), 3 4, 13 4 ORACLE Precompiler, 3 4, 13 4 passing messages to Oracle Forms, 3 9 passing parameter values, 13 10 performing ORACLE commands, 3 11 performing SQL commands, 3 6 PL/SQL interface, 13 2 retrieving values from Oracle Forms, 3 7 returning values, 13 10 saving context to Oracle Forms, 3 11 sending values to Oracle Forms, 3 8 GET, 3 7 GET CONTEXT, 3 10 Global variables in multipleform application, 5 23 quitting from called form, 5 11 GUI standards, 9 5
I
IAPXTB, 3 12 Icons, 9 10 IFZCAL, 8 22 Independent forms, 5 4 Instance identifier, 5 8
K
Key bindings defining key bindings for triggers, A 6 Oracle Forms runform key bindings, A 8 remapping Oracle Forms key bindings, A 2 Key Mode block property, 4 3
L
Locking, 4 36 Logical attributes about attribute precedence, A 13 about logical attributes, A 13
Index 2
M
Methods (VBX), 11 11 Middle Eastern language support, B 18 Mouse events about mouse events, 6 2 in chart items, 8 13 mouse system variables, 6 3 mouse triggers, 6 2 MS Windows SDK, 13 16 Multibyte characters, B 4 Multipleform applications about multipleform applications, 5 2 closing independent forms, 5 4 opening independent forms, 5 4
N
National Language Support bidirectional applications, B 18 format masks, B 10, B 12 language and territory conventions, B 10 message file names, B 14 MODULE_NLS_LANG parameter, B 8 multibyte characters, B 4 NLS_LANG environment variable, B 5 Oracle Translation Manager, B 2 screen design considerations, B 13 USER_NLS_LANG parameter, B 8 using TO_DATE instead of COPY, B 10 NEW_FORM, 5 2, 5 9 NonORACLE data sources, 3 4, 13 4
O
OCI foreign functions, 3 4, 13 4 ODBC, 4 2
OLE about OLE, 10 2 about OLE automation, 10 7 about OLE objects, 10 3 about OLE servers and containers, 10 4 activation properties, 10 9 breaking a link, 10 19 changing a link, 10 19 choosing embedding or linking, 10 7 container properties, 10 9 converting OLE objects, 10 20 creating an OLE container, 10 12 displaying OLE objects, 10 15 editing OLE objects, 10 17 embedding an OLE object, 10 14 external activation, 10 6 inplace activation, 10 5 linking an OLE object, 10 14 OLE object data type, 10 8 opening a linked source file, 10 18 popup menu properties, 10 9 registration database, 10 4 setting OLE properties in the Designer, 10 9 storing OLE objects in the database, 10 8 tenant properties, 10 9 updating a linked object, 10 18 using OLE at runtime, 10 11 OnCheckUnique trigger, 4 30 OnClose trigger, 4 22 OnColumnSecurity trigger, 4 35 OnCommit trigger, 4 30 OnCount trigger, 4 20 OnDelete trigger, 4 29 OnFetch trigger, 4 22 OnInsert trigger, 4 30 OnLock trigger, 4 36 OnLogon trigger, 4 18 OnLogout trigger, 4 18 OnSavepoint trigger, 4 29 OnSelect trigger, 4 22 OnSequenceNumber trigger, 4 36 OnUpdate trigger, 4 30 Open Gateway, 4 2
Index 3
OPEN_FORM, 5 2, 5 4 ORA_FFI, 13 2 Oracle Book, 8 5 ORACLE Call Interface foreign functions, 3 4, 13 4 Oracle Graphics invoking from Oracle Forms, 8 3 OG integration package, 8 15 OG.CLOSE, 8 15 OG.GETCHARPARAM, 8 15 OG.GETNUMPARAM, 8 16 OG.INTERPRET, 8 16 OG.MOUSEDOWN, 8 17 OG.MOUSEUP, 8 18 OG.OPEN, 8 20 OG.PLL integration library, 8 9 OG.REFRESH, 8 21 passing LOGON parameter, 8 4 Oracle Open Client Adapter about OCA and ODBC, 14 2 datasource support, 14 10 ODBC support, 14 1 restrictions, 14 12 setting up applications, 14 8 UBT utility, 14 20 using with Oracle Forms, 14 5 ORACLE Precompiler foreign functions, 3 4, 13 4 Oracle Reports, 8 3 Oracle Terminal about resource files, A 2 using OT to modify logical attributes, A 13 using OT to remap key mappings, A 2 Oracle Translation Manager, B 2 OSSWEP.OBJ, 3 19
P
Parameter lists, 5 23, 8 6 Parameters Form, 5 23 passing to other products, 8 5 Pattern attributes, A 18
PECS about PECS, C 2 example, C 8 experiments, C 11 line coverage, C 10 object coverage, C 10 PECS Assistant, C 11 PECS builtins, C 16 PECS Reports, C 13 PECSLOAD, C 14 performance testing, C 3 PL/SQL access to foreign functions, 13 6 access to OLE objects, 10 7 exception handling, 1 2 interface to foreign functions, 13 2 packages, 2 3 Pointers GET CONTEXT statement, 3 10 SET CONTEXT statement, 3 11 Portability about portability, 9 2 charactermode considerations, 9 12 font aliasing, 9 9 fonts, 9 8 icons, 9 10 porting process outline, 9 4 using color, 9 7 PostDatabaseCommit trigger, 4 30 PostDelete trigger, 4 29 PostFormsCommit trigger, 4 30 PostInsert trigger, 4 30 PostLogon trigger, 4 18 PostLogout trigger, 4 18 Postonly mode, 5 15 PostQuery trigger, 4 22 PostSelect trigger, 4 22 PostUpdate trigger, 4 30 Posting, 5 15 PreCommit trigger, 4 29 PreDelete trigger, 4 29 PreInsert trigger, 4 30 PreLogon trigger, 4 18
Index 4
PreLogout trigger, 4 18 PreQuery trigger, 4 20, 4 22 PreSelect trigger, 4 20, 4 22 PreUpdate trigger, 4 30 Precompiler Statements, 3 5, 13 5 Procedures (stored), 2 2
T
Template forms, 9 5 Testing performance, C 3 Timers creating timers, 7 2 deleting timers, 7 6 programmatic control, 7 5 usage rules, 7 3 Transactional options (Key Mode), 4 3 Transactional Triggers property, 4 15 Translating Oracle Forms applications, B 2 Translation Manager, B 2 Triggers database triggers, 2 14 failure in triggers, 1 3 handling runtime errors in triggers, 1 2 mouse triggers, 6 2 transactional triggers, 4 8
Q
QA testing, C 3 Query Only forms, 5 12
R
Rollback mode, 5 17 ROWID, 4 3 RUN_PRODUCT, 8 3
S
Savepoints about savepoints, 5 16 savepoint and rollback processing, 4 33 Savepoint Mode property, 4 7 Savepoint_Name property, 4 34 Semitic language support, B 18 Sessions (database), 5 6 SET, 3 8 SET CONTEXT, 3 11 Singleclick event, 6 4 SQL statements in foreign functions, 3 6 Standards, 9 5 Stored procedures about stored procedures, 2 2 calling stored procedures, 2 9 creating stored procedures, 2 5 restrictions for stored procedures, 2 3 stored program unit editor, 2 6 System variables (mouse), 6 3
U
UE_SAMP.MAK, 3 18 UE_XTB.C, 3 18 UE_XTBN.C, 3 18 UE_XTBN.MAK, 3 18 UEZ.OBJ, 3 19 uifont.ali file, 9 9 User Exit Interface creating a user exit interface, 3 12 integrating, 3 13 MS Windows SDK Functions, 3 16 nonOracle user exits, 4 11 project files, 3 18 Usernamed routines, 2 2 Usernamed triggers, 1 7
Index 5
V
VBX controls about VBX controls, 11 2 creating VBX controls, 11 12 firing events, 11 8 getting properties, 11 9 invoking methods, 11 11 mapping to Oracle Forms properties, 11 5 responding to events, 11 7
W
WhenCreateRecord trigger, 4 36 White on Black, A 18 Widget mnemonics, 9 12
Index 6
Did you find any errors? Is the information clearly presented? Do you need more information? If so, where? Are the examples correct? Do you need more examples? What features did you like most about this manual?
If you find any errors or have any other suggestions for improvement, please indicate the topic, chapter, and page number below:
Please send your comments to: Forms Documentation Manager Oracle Corporation 500 Oracle Parkway Redwood City, CA 94065 U.S.A. Fax: (415) 5067200 If you would like a reply, please give your name, address, and telephone number below:
*A32506-2* *A32506-2*
A325062
Release 4.5