Preprocessor Input and Output [ HP SQL/V PASCAL Application Programming Guide ]

HP SQL/V PASCAL Application Programming Guide
Preprocessor Input and Output
Regardless of the mode you use, the following files must be available
when you invoke the Pascal preprocessor, as shown in Figure 2-3:
* SQLIN: a file containing the Pascal HP SQL program or subprogram with
embedded SQL commands for one DBEnvironment. The formal file
designator for this input file is:
SQLIN
* HPSQLCAT: the HP SQL message catalog, which contains preprocessor
messages and HP SQL error and warning messages. The formal file
designator for the message catalog is:
HPSQLCAT.PUB.SYS
When you run the preprocessor in full preprocessing mode, also ensure
that the DBEnvironment accessed by the program is available. As Figure
2-3 points out, the Pascal preprocessor creates the following temporary
output files:
* SQLOUT: a file containing a modified version of the source code in
SQLIN. The formal file designator for this file is:
SQLOUT
After you use the preprocessor in full preprocessing mode, you use
SQLOUT and the following include files as input files for the Pascal
compiler, as shown in Figure 2-4.
* SQLCONST=, SQLTYPE, SQLVAR, and SQLEXTN: include files containing
definitions of constants, types, variables, and external procedures
used by Pascal constructs the preprocessor inserts into SQLOUT. The
formal file designators for these files are, respectively:
SQLCONST
SQLTYPE
SQLVAR (or SQLVARn for subprograms)
SQLEXTN
* SQLMSG: a file containing the preprocessor banner, error and warning
messages, and other messages. The formal file designator for this
file is:
SQLMSG
* SQLMOD: a file containing a copy of the module created by the
preprocessor. The formal file designator for this file is:
SQLMOD
When you run the preprocessor in full preprocessing mode, the
preprocessor also stores a module in the DBEnvironment accessed by your
program. The module is used at run time to execute DBEnvironment
operations.
Click here to view figure.
Figure 2-3. Pascal Preprocessor Input and Output
Click here to view figure.
Figure 2-4. Compiling Preprocessor Output
If you want to preprocess several HP SQL application programs in the same
group and account and compile and link the programs later, or you plan to
compile a preprocessed program during a future session, you should do the
following for each program:
* Before running the preprocessor, equate SQLIN to the name of the file
containing the application you want to preprocess:
:FILE SQLIN = InFile
* After running the preprocessor, save and rename the output files if
you do not want them overwritten. For example:
:SAVE SQLOUT
:RENAME SQLOUT, OutFile
:SAVE SQLMOD
:RENAME SQLMOD, ModFile
:SAVE SQLVAR
:RENAME SQLVAR, VarFile
:SAVE SQLTYPE
:RENAME SQLTYPE, TypeFile
:SAVE SQLEXTN
:RENAME SQLEXTN, ExtnFile
:SAVE SQLCONST
:RENAME SQLCONST, ConstFile
When you are ready to compile the program, you must equate the include
file names to their standard HP SQL names. See "Preprocessor-Generated
Include Files" in this section for more information.
SQLIN
SQLIN must be an ASCII file (numbered or unnumbered) that contains at a
minimum the following constructs:
(* PROGRAM HEADING *)
Program ProgramName(input, output);
begin
AnyStatement;
end.
When parsing SQLIN, the Pascal preprocessor ignores Pascal statements and
most Pascal compiler directives in SQLIN. Only the following information
is parsed by the Pascal preprocessor:
* The Pascal compiler directives $skip_text_ON$, $skip_text_OFF$, $set,
$if, $else, $endif, and $include.
* The program name. Unless you specify a module name in the
preprocessor invocation line, the preprocessor uses the program name
as the name for the module it stores. A module name can contain as
many as 20 characters and must follow the rules governing HP SQL
basic names (given in the SQL Reference Manual).
* Constructs found between the prefix EXEC SQL and the suffix ;. These
constructs follow the rules given in Chapter 3 for how and where to
embed these constructs.
* Constructs found between the BEGIN DECLARE SECTION and END DECLARE
SECTION commands. These commands delimit a declare section which
contains Pascal data declarations for the host variables used in the
program. Host variables are described in Chapter 4.
Figure 2-6 illustrates an SQLIN file containing a sample program using
the following SQL commands highlighted in boldface in the figure:
INCLUDE SQLCA
BEGIN DECLARE SECTION
END DECLARE SECTION
WHENEVER
CONNECT
BEGIN WORK
COMMIT WORK
SELECT
SQLEXPLAIN
As the sample dialog in Figure 2-5 illustrates, the program begins a DBE
session for PartsDBE, the sample DBEnvironment. It prompts the user for
a part number, then displays information about the part from the table
PurchDB.Parts. Warning and error conditions are handled with WHENEVER
and SQLEXPLAIN commands with the exception of explicit error checking
after the SELECT command. The program continues to prompt for a part
number until a serious error is encountered or until the user enters a
slash (/).
_____________________________________________________________________
| |
| :RUN PASEX2P |
| Program to SELECT specified rows from the Parts Table - PASEX2|
| |
| Event List: |
| Connect to PartsDBE |
| Begin Work |
| SELECT specified row from Parts Table |
| until user enters "/" |
| Commit Work |
| Disconnect from PartsDBE |
| |
| Connect to PartsDBE |
| |
| Enter Part Number within Parts Table or "/" to STOP> 1243-P-01|
| |
| Begin Work |
| SELECT PartNumber, PartName, SalesPrice |
| |
| Row not found! |
| Commit Work |
| |
| Enter Part Number within Parts Table or "/" to STOP> 1323-D-01|
| |
| Begin Work |
| SELECT PartNumber, PartName, SalesPrice |
| |
| Part Number: 1323-D-01 |
| Part Name: Floppy Diskette Drive |
| Sales Price: 200.00 |
| Commit Work |
| |
| Enter Part Number within Parts Table or "/" to STOP> 1199-M-01|
| |
| Begin Work |
| SELECT PartNumber, PartName, SalesPrice |
| |
| Part Number: 1199-M-01 |
| Part Name: Modem |
| Sales Price is NULL |
| Commit Work |
| |
| Enter Part Number within Parts Table or "/" to STOP> / |
| |
| Release PartsDBE |
| |
| Terminating Program |
_____________________________________________________________________
Figure 2-5. Execution of Program PASEX2
____________________________________________________________________________
| |
| (* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)|
| (* This program illustrates the use of SQL's SELECT command to *)|
| (* retrieve one row or tuple at a time. *)|
| (* BEGIN WORK is executed before the SELECT and a COMMIT WORK *)|
| (* after the SELECT. An indicator variable is also used for *)|
| (* SalesPrice. *)|
| (* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)|
| |
| Program PASEX2(input, output); |
| |
| label |
| 1000, |
| 9999; |
| |
| const |
| OK = 0; |
| NotFound = 100; |
| DeadLock = -14024; |
| |
| var |
| |
| EXEC SQL INCLUDE SQLCA; (* SQL Communication Area *) |
| |
| (* Begin Host Variable Declarations *) |
| EXEC SQL BEGIN DECLARE SECTION; |
| PartNumber : packed array[1..16] of char; |
| PartName : packed array[1..30] of char; |
| SalesPrice : longreal; |
| SalesPriceInd : SQLIND; |
| SQLMessage : packed array[1..132] of char; |
| EXEC SQL END DECLARE SECTION; |
| (* End Host Variable Declarations *) |
| |
| Abort : boolean; |
| |
| procedure SQLStatusCheck; (* Procedure to Display Error Messages *) |
| Forward; |
| |
| $PAGE $ |
| |
| (* Directive to set SQL Whenever error checking *) |
| EXEC SQL WHENEVER SQLERROR GOTO 1000; |
____________________________________________________________________________
Figure 2-6. Program PASEX2: Using Simple Select (Page 1 of 5)
________________________________________________________________________
| |
| procedure ConnectDBE; (* Procedure to Connect to PartsDBE *) |
| begin |
| |
| writeln('Connect to PartsDBE'); |
| EXEC SQL CONNECT TO 'PartsDBE'; |
| |
| end; (* End of ConnectDBE Procedure *) |
| |
| |
| procedure BeginTransaction; (* Procedure to Begin Work *) |
| begin |
| |
| writeln; |
| writeln('Begin Work'); |
| EXEC SQL BEGIN WORK; |
| |
| end; (* End BeginTransaction Procedure *) |
| |
| |
| procedure EndTransaction; (* Procedure to Commit Work *) |
| begin |
| |
| |
| writeln('Commit Work'); |
| EXEC SQL COMMIT WORK; |
| |
| end; (* End EndTransaction Procedure *) |
| |
| |
| (* Directive to reset SQL Whenever error checking *) |
| EXEC SQL WHENEVER SQLERROR CONTINUE; |
| |
| |
| procedure TerminateProgram; (* Procedure to Release PartsDBE *)|
| begin |
| |
| writeln('Release PartsDBE'); |
| EXEC SQL COMMIT WORK RELEASE; |
| |
| writeln; |
| writeln('Terminating Program'); |
| Goto 9999; (* Goto exit point of main program *) |
| |
| end; (* End TerminateProgram Procedure *) |
| $PAGE $ |
________________________________________________________________________
Figure 2-6. Program PASEX2: Using Simple Select (page 2 of 5)
__________________________________________________________________________
| |
| procedure DisplayRow; (* Procedure to Display Parts Table Rows *)|
| begin |
| writeln; |
| writeln('Part Number: ', PartNumber); |
| writeln('Part Name: ', PartName); |
| if SalesPriceInd < 0 then |
| writeln('Sales Price is NULL') |
| else |
| writeln('Sales Price: ', SalesPrice:10:2); |
| |
| end; (* End of DisplayRow *) |
| $PAGE $ |
| |
| procedure SelectData; (* Procedure to Query Parts Table *) |
| begin |
| |
| repeat |
| |
| writeln; |
| prompt('Enter Part Number within Parts Table or "/" to STOP> '); |
| readln(PartNumber); |
| writeln; |
| |
| if PartNumber[1] <> '/' then |
| begin |
| |
| BeginTransaction; |
| |
| writeln('SELECT PartNumber, PartName, SalesPrice'); |
| EXEC SQL SELECT PartNumber, PartName, SalesPrice |
| INTO :PartNumber, |
| :PartName, |
| :SalesPrice :SalesPriceInd |
| FROM PurchDB.Parts |
| WHERE PartNumber = :PartNumber; |
| |
| if SQLCA.SQLWARN[0] in ['W','w'] then |
| begin |
| write('SQL WARNING has occurred. The following row'); |
| writeln('of data may not be valid.'); |
| end; |
__________________________________________________________________________
Figure 2-6.Program PASEX2: Using Simple Select (page 3 of 5)
___________________________________________________________________________
| |
| case SQLCA.SQLCODE of |
| OK : DisplayRow; |
| NotFound : begin |
| writeln; |
| writeln('Row not found!'); |
| end; |
| otherwise begin |
| SQLStatusCheck; |
| end; |
| |
| end; (* case *) |
| |
| EndTransaction; |
| |
| end; (* End if *) |
| until PartNumber[1] = '/'; |
| |
| end; (* End of SelectData Procedure *) |
| |
| procedure SQLStatusCheck; (* Procedure to Display Error Messages *)|
| begin |
| |
| Abort := FALSE; |
| if SQLCA.SQLCODE < DeadLock then Abort := TRUE; |
| |
| repeat |
| EXEC SQL SQLEXPLAIN :SQLMessage; |
| writeln(SQLMessage); |
| until SQLCA.SQLCODE = 0; |
| |
| if Abort then |
| begin |
| |
| TerminateProgram; |
| |
| end; |
| |
| end; (* End SQLStatusCheck Procedure *) |
| $PAGE $ |
___________________________________________________________________________
Figure 6-2. Program PASEX2: Using Simple Select (page 4 of 5)
__________________________________________________________
| |
| begin (* Beginning of Program *) |
| |
| write('Program to SELECT specified rows from '); |
| writeln('the Parts Table - PASEX2'); |
| writeln; |
| writeln('Event List:'); |
| writeln(' Connect to PartsDBE'); |
| writeln(' Begin Work'); |
| writeln(' SELECT specified row from Parts Table');|
| writeln(' until user enters "/" '); |
| writeln(' Commit Work'); |
| writeln(' Disconnect from PartsDBE'); |
| writeln; |
| |
| ConnectDBE; |
| SelectData; |
| TerminateProgram; |
| |
| (* Whenever Routine - Serious DBE Error *) |
| (* SQL Whenever SQLError Entry Point *) |
| 1000: |
| |
| (* Begin *) |
| SQLStatusCheck; |
| TerminateProgram; |
| (* End *) |
| |
| (* Exit Point for the main program *) |
| 9999: |
| |
| end. (* End of Program *) |
__________________________________________________________
Figure 6-2. Program PASEX2: Using Simple Select (page 5 of 5)
Output File Attributes
The Pascal preprocessor output files are temporary files. When the SQLIN
illustrated in Figure 2-6 is preprocessed, the attributes of the output
files created are as follows:
:listftemp,2
TEMPORARY FILES FOR SOMEUSER.SOMEACCT,SOMEGRP
ACCOUNT= SOMEACCT GROUP= SOMEGRP
FILENAME CODE ------------LOGICAL RECORD----------- ----SPACE----
SIZE TYP EOF LIMIT R/B SECTORS #X MX
SQLCONST 254B VA 3 1023 1 256 1 8 (TEMP)
SQLEXTN 254B VA 79 1023 1 256 1 8 (TEMP)
SQLMOD 270W FB 3 1023 1 384 1 8 (TEMP)
SQLMSG 254B VA 13 1023 1 256 1 8 (TEMP)
SQLOUT 254B VA 313 1023 1 256 1 8 (TEMP)
SQLTYPE 254B VA 56 1023 1 256 1 8 (TEMP)
SQLVAR 254B VA 7 1023 1 256 1 8 (TEMP)
When you invoke the preprocessor using the UDCs provided with HP SQL, the
output file attributes are slightly different:
:pppas pasex2,PartsDBE,pasex2p,msg
.
.
.
:listftemp,2
TEMPORARY FILES FOR SOMEUSER.SOMEACCT,SOMEGRP
ACCOUNT= SOMEACCT GROUP= SOMEGRP
FILENAME CODE -----------LOGICAL RECORD----------- ----SPACE----
SIZE TYP EOF LIMIT R/B SECTORS #X MX
SQLCONST 80B FA 3 1000 16 40 1 8 (TEMP)
SQLEXTN 80B FA 79 1000 16 40 1 8 (TEMP)
SQLMOD 270W FB 3 500 1 189 1 8 (TEMP)
SQLOUT 80B FA 313 10000 16 200 2 32 (TEMP)
SQLTYPE 80B FA 56 1000 16 40 1 8 (TEMP)
SQLVAR 80B FA 7 1000 16 40 1 8 (TEMP)
The UDCs are described later in this chapter under "Invoking the Pascal
Preprocessor". The UDCs have the following effects on the attributes of
all the preprocessor output files:
* The files are 80-byte fixed-length files, which can be accessed by
most editors.
* Disc space is efficiently utilized by the files.
Modified Source File
As the Pascal preprocessor parses SQLIN, it copies lines from SQLIN and
any file(s) included from SQLIN into SQLOUT, comments out embedded SQL
commands, and inserts information around each embedded SQL command.
Figure 2-7 illustrates the SQLOUT generated for the SQLIN pictured in
Figure 2-6. The boldface lines contain information generated by the
Pascal preprocessor. In both preprocessing modes, the Pascal
preprocessor:
* Inserts a $Skip_Text ON$ and a $Skip_Text OFF$ compiler directive
around the embedded SQL command to comment out the SQL command.
* Inserts $INCLUDE Pascal compiler directives within the Declaration
part. These directives reference the four preprocessor-generated
include files: SQLCONST, SQLTYPE, SQLVAR, and SQLEXTN. SQLCONST and
SQLTYPE are included after the program header. SQLVAR and SQLEXTN
are included at the end of the global declaration part of a main
program.
* Keeps comments that follow an embedded command. These comments
appear after the preprocessor generated code associated with the
command. Note, for example, that the comment following the INCLUDE
SQLCA command in SQLIN is in the same column, but on a different
line, in SQLOUT.
In full preprocessing mode, the preprocessor also:
* Generates a Pascal declaration for the SQLCA and the SQLDA in the
SQLTYPE include file.
* Generates Pascal statements providing conditional instructions.
These statements follow any SQL commands encountered after one of the
following SQL commands: WHENEVER SQLERROR, WHENEVER SQLWARNING, and
WHENEVER NOT FOUND.
* Generates Pascal statements that call HP SQL external procedures at
run time. These calls reference the module stored by the
preprocessor in the DBEnvironment for execution at run time.
Parameters used by these external calls are defined in SQLVAR,
SQLCONST, and SQLTYPE.
CAUTION Although you can access SQLOUT, SQLVAR, SQLVARn, SQLTYPE,
SQLCONST, and SQLEXTN files with an editor, you should
never change the information generated by the Pascal
preprocessor. Your DBEnvironment could be damaged at run time
if preprocessor-generated constructs are altered.
If you need to change non-preprocessor-generated constructs in SQLOUT,
make the changes to SQLIN, re-preprocess SQLIN, and re-compile the output
files before putting the application program into production.
____________________________________________________________________________
| |
| (* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)|
| (* This program illustrates the use of SQL's SELECT command to *)|
| (* retrieve one row or tuple at a time. *)|
| (* BEGIN WORK is executed before the SELECT and a COMMIT WORK *)|
| (* after the SELECT. An indicator variable is also used for *)|
| (* SalesPrice. *)|
| (* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)|
| |
| Program pasex2(input, output); |
| |
| label |
| 1000, |
| 9999; |
| $Include 'sqlconst'$ |
| $Include 'sqltype'$ |
| const |
| OK = 0; |
| NotFound = 100; |
| DeadLock = -14024; |
| |
| var |
| |
| $Skip_Text ON$ |
| EXEC SQL INCLUDE SQLCA; |
| $Skip_Text OFF$ |
| sqlca: Sqlca_Type; |
| |
| (* Begin Host Variable Declarations *) |
| $Skip_Text ON$ |
| EXEC SQL Begin Declare Section; |
| $Skip_Text OFF$ |
| |
| PartNumber : packed array[1..16] of char; |
| PartName : packed array[1..30] of char; |
| SalesPrice : longreal; |
| SalesPriceInd : SQLIND; |
| SQLMessage : packed array[1..132] of char; |
| |
| $Skip_Text ON$ |
| EXEC SQL End Declare Section; |
| $Skip_Text OFF$ |
| |
| (* End Host Variable Declarations *) |
| |
| Abort : boolean; |
____________________________________________________________________________
Figure 2-7. Sample Modified Source File (page 1 of 6)
____________________________________________________________________________
| |
| $Include 'sqlvar'$ |
| $Include 'sqlextn'$ |
| procedure SQLStatusCheck; (* Procedure to Display Error Messages *) |
| Forward; |
| |
| $PAGE $ |
| |
| (* Directive to set SQL Whenever error checking *) |
| |
| $Skip_Text ON$ |
| EXEC SQL Whenever SqlError goto 1000; |
| $Skip_Text OFF$ |
| |
| Procedure ConnectDBE; (* Procedure to Connect to PartsDBE *) |
| begin |
| |
| writeln('Connect to PartsDBE'); |
| $Skip_Text ON$ |
| EXEC SQL CONNECT TO 'PartsDBE'; |
| $Skip_Text OFF$ |
| Begin |
| SQLvar1 :='00AB0180506172747344424520202020202020202020202020202020'+|
| '20202020202020202020202020202020202020202020202020202020'+ |
| '20202020202020202020202020202020202020202020202020202020'+ |
| '20202020202020202020202020202020202020202020202020202020'+ |
| '2020202020202020202020202020202020202020'; |
| SQLXCON(Waddress(SQLCA), Sqlvar1); |
| if Sqlca.Sqlcode < 0 then |
| goto 1000; |
| End; |
| |
| |
| end; (* End of ConnectDBE Procedure *) |
| |
| Procedure BeginTransaction; (* Procedure to Begin Work *) |
| begin |
| |
| writeln; |
| writeln('Begin Work'); |
| |
| $Skip_Text ON$ |
| EXEC SQL BEGIN WORK; |
| $Skip_Text OFF$ |
| Begin |
| SQLvar2 := '00A0007F00117274'; |
| SQLXCON(Waddress(SQLCA), Sqlvar2); |
____________________________________________________________________________
Figure 2-7. Sample Modified Source File (page 2 of 6)
________________________________________________________________________
| |
| if Sqlca.SqlCode < 0 then |
| goto 1000; |
| End; |
| |
| end; (* End BeginTransaction Procedure *) |
| |
| procedure EndTransaction; (* Procedure to Commit Work *) |
| begin |
| |
| |
| writeln('Commit Work'); |
| |
| $Skip_Text ON$ |
| EXEC SQL COMMIT WORK; |
| $Skip_Text OFF$ |
| Begin |
| SQLvar3 := '00A1007F'; |
| SQLXCON(Waddress(SQLCA), Sqlvar3); |
| if Sqlca.SqlCode < 0 then |
| goto 1000; |
| End; |
| |
| end; (* End EndTransaction Procedure *) |
| |
| (* Directive to reset SQL Whenever error checking *) |
| |
| $Skip_Text ON$ |
| EXEC SQL WHENEVER SQLERROR CONTINUE; |
| $Skip_Text OFF$ |
| |
| procedure TerminateProgram; (* Procedure to Release PartsDBE *)|
| begin |
| |
| writeln('Release PartsDBE'); |
| |
| $Skip_Text ON$ |
| EXEC SQL COMMIT WORK RELEASE; |
| $Skip_Text OFF$ |
| Begin |
| SQLvar4 := '00A1007F'; |
| SQLXCON(Waddress(SQLCA), Sqlvar4); |
| End; |
| Begin |
| SQLvar5 :='00AC007F2020202020202020202020202020202020202020'; |
| SQLXCON(Waddress(SQLCA), Sqlvar5); |
| End; |
________________________________________________________________________
Figure 2-7. Sample Modified Source File (page 3 of 6)
__________________________________________________________________________
| |
| writeln; |
| writeln('Terminating Program'); |
| Goto 9999; (* Goto exit point of main program *) |
| |
| end; (* End TerminateProgram Procedure *) |
| $PAGE $ |
| |
| procedure DisplayRow; (* Procedure to Display Parts Table Rows *)|
| begin |
| |
| writeln; |
| writeln('Part Number: ', PartNumber); |
| writeln('Part Name: ', PartName); |
| if SalesPriceInd < 0 then |
| writeln('Sales Price is NULL') |
| else |
| writeln('Sales Price: ', SalesPrice:10:2); |
| |
| end; (* End of DisplayRow *) |
| $PAGE $ |
| |
| procedure SelectData; (* Procedure to Query Parts Table *) |
| begin |
| |
| repeat |
| |
| writeln; |
| prompt('Enter Part Number within Parts Table or "/" to STOP> '); |
| readln(PartNumber); |
| writeln; |
| |
| if PartNumber[1] <> '/' then |
| begin |
| |
| BeginTransaction; |
| |
| writeln('SELECT PartNumber, PartName, SalesPrice'); |
| |
| $Skip_Text ON$ |
| EXEC SQL SELECT PartNumber, PartName, SalesPrice |
| INTO :PartNumber, |
| :PartName, |
| :SalesPrice :SalesPriceInd |
| FROM PurchDB.Parts |
| WHERE PartNumber = :PartNumber; |
| $Skip_Text OFF$ |
__________________________________________________________________________
Figure 2-7. Sample Modified Source File (page 4 of 6)
___________________________________________________________________________
| |
| Begin |
| SQLTEMPV.REC1.PARTNUMBER1:= PARTNUMBER; |
| SQLXFET(Waddress(SQLCA),SQLOWNER,SQLMODNAME,1,Waddress(SQLTEMPV), |
| if Sqlca.SqlCode = 0 then begin |
| PARTNUMBER:= SQLTEMPV.REC2.PARTNUMBER1; |
| PARTNAME:= SQLTEMPV.REC2.PARTNAME2; |
| if SQLTEMPV.REC2.SALESPRICEIND4 >= 0 then |
| SALESPRICE:= SQLTEMPV.REC2.SALESPRICE3; |
| SALESPRICEIND:= SQLTEMPV.REC2.SALESPRICEIND4; |
| end |
| ; |
| End; |
| |
| if SQLCA.SQLWARN[0] in ['W','w'] then |
| begin |
| write('SQL WARNING has occurred. The following row '); |
| writeln('of data may not be valid.'); |
| end; |
| |
| case SQLCA.SQLCODE of |
| OK : DisplayRow; |
| NotFound : begin |
| writeln; |
| writeln('Row not found!'); |
| end; |
| otherwise begin |
| SQLStatusCheck; |
| end; |
| |
| end; (* case *) |
| |
| EndTransaction; |
| |
| end; (* End if *) |
| until PartNumber[1] = '/'; |
| |
| end; (* End of SelectData Procedure *) |
| |
| procedure SQLStatusCheck; (* Procedure to Display Error Messages *)|
| begin |
| |
| Abort := FALSE; |
| if SQLCA.SQLCODE < DeadLock then Abort := TRUE; |
___________________________________________________________________________
Figure 2-7. Sample Modified Source File (page 5 of 6)
______________________________________________________________
| |
| repeat |
| |
| $Skip_Text ON$ |
| EXEC SQL SQLEXPLAIN :SQLMessage; |
| $Skip_Text OFF$ |
| Begin |
| SQLXPLN(Waddress(SQLCA),Waddress(SQLTEMPV.REC4),132,0);|
| SQLMESSAGE:="; |
| StrMove(132,SQLTEMPV.REC4,1,SQLMessage,1); |
| End; |
| |
| writeln(SQLMessage); |
| until SQLCA.SQLCODE = 0; |
| |
| if Abort then |
| begin |
| TerminateProgram; |
| end; |
| |
| end; (* End SQLStatusCheck Procedure *) |
| $PAGE $ |
| begin (* Beginning of Program *) |
| write('Program to SELECT specified rows from '); |
| writeln('the Parts Table - PASEX2'); |
| writeln; |
| writeln('Event List:'); |
| writeln(' Connect to PartsDBE'); |
| writeln(' Begin Work'); |
| writeln(' SELECT specified row from Parts Table'); |
| writeln(' until user enters "/" '); |
| writeln(' Commit Work'); |
| writeln(' Release from PartsDBE'); |
| writeln; |
| |
| ConnectDBE; |
| SelectData; |
| TerminateProgram; |
| |
| (* Whenever Routine - Serious DBE Error *) |
| (* SQL Whenever SQLError Entry Point *) |
| 1000: |
| (* Begin *) |
| SQLStatusCheck; |
| TerminateProgram; |
| (* End *) |
| (* Exit Point for the main program *) |
| 9999: |
| end. (* End of Program *) |
______________________________________________________________
Figure 2-7. Sample Modified Source File (page 6 of 6)
Preprocessor-Generated Include Files
SQLCONST, SQLTYPE, SQLVAR, SQLVARn, and SQLEXTN are preprocessor-created
include files which contain declarations for constants, types, variables,
and external procedures for the preprocessor-generated statements in
SQLOUT. Figure 2-8 through Figure 2-11 illustrate, respectively, the
SQLCONST, SQLTYPE, SQLVAR, and SQLEXTN files that correspond to the
SQLOUT file in Figure 2-7. Note that the preprocessor inserts the
following four Pascal compiler directives to reference SQLCONST, SQLTYPE,
SQLVAR, and SQLEXTN:
$INCLUDE 'sqlconst'$
$INCLUDE 'sqltype'$
.
.
$INCLUDE 'sqlvar'$
$INCLUDE 'sqlextn'$
These four directives are always inserted into the global declaration
part of a main program. For each declare section in a subprogram, an
SQLVARn include file is generated and the compiler directive $INCLUDE
'sqlvarn'$ is inserted in the local declaration part. The value of n is
from 01 through 99.
Even if you use file equations to redirect the include files, the
preprocessor still inserts the same $INCLUDE directives. Therefore when
you compile preprocessor output, ensure that the preprocess-time file
equations are in effect so the correct include files are compiled:
:FILE SQLCONST=MYCONST
:FILE SQLTYPE=MYTYPE
:FILE SQLVAR=MYVAR
:FILE SQLEXTN=MYEXTN
:FILE SQLIN=MYPROG
:FILE SQLOUT=MYSQLPRG
. Then the Pascal preprocessor is invoked
. in full preprocessing mode. Later, when the
. Pascal compiler is invoked, the following
file equations must be in effect:
:FILE SQLCONST=MYCONST
:FILE SQLTYPE=MYTYPE
:FILE SQLVAR=MYVAR
:FILE SQLEXTN=MYEXTN
:PASCAL MYSQLPRG, $NEWPASS, $NULL
For each SQLVARn file of a subprogram specify:
:FILE SQLVARn=MYVARn
and the reverse after preprocessing.
_____________________________________________
| |
| const |
| SQLOWNER = 'SOMEUSER@SOMEACCT ';|
| SQLMODNAME = 'PASEX2 ';|
_____________________________________________
Figure 2-8. Sample SQLCONST
_____________________________________________________
| |
| type |
| OwnerName_Type = String[20]; |
| ModuleName_Type = String[20]; |
| SmallInt = -32768..32767; |
| SqlInd = -32768..23767; |
| SQLREC1 = record |
| PARTNUMBER1: packed array [1..16] of char;|
| end; |
| SQLREC2 = record |
| PARTNUMBER1: packed array [1..16] of char;|
| PARTNAME2: packed array [1..30] of char; |
| SALESPRICE3: longreal; |
| SALESPRICEIND4: sqlind; |
| end; |
| SQLREC3 = record |
| DUMMY1, DUMMY2 : SQLREC2 |
| end; |
| SQLREC4 = packed array[1..132] of char; |
| SQLCASES = 0..4; |
| Sqlca_Type = Record |
| SqlcaId: Packed Array[1..8] of Char; |
| Sqlcabc, SqlCode: Integer; |
| LEN : SmallInt |
| MSG : Packed Array[1..254] of Char; |
| SqlErrP: Packed Array[1..8] of Char; |
| SqlErrD: Array [1..6] of Integer; |
| SqlWarn: Packed Array [0..7] of Char; |
| SqlExt1: SmallInt; |
| SqlExt2: SmallInt; |
| end; |
_____________________________________________________
Figure 2-9. Sample SQLTYPE (page 1 of 2)
_______________________________________________________
| |
| SqlFormat_Type = Packed Record |
| SqLnty, SqlType, SqlPrec, SqlScale : SmallInt;|
| SqlTotalLen, SqlValLen, SqlIndLen : integer; |
| SqlVof, SqlNof: integer; |
| SqlName: Packed Array [1..20] of Char; |
| end; |
| Sqlda_Type = Record |
| SqldaId : Packed Array[1..8] of Char; |
| Sqldabc : Integer; |
| Sqln : Integer; |
| Sqld : Integer; |
| SqlFmtArr: SmallInt; |
| SqlNRow : Integer; |
| SqlRRow : Integer; |
| SqlRowLen: Integer; |
| SqlBufLen: Integer; |
| SqlRowBuf: SmallInt; |
| end; |
| SQLTEMPV_TYPE_P = @SQLTEMPV_TYPE; |
| SqlTempV_Type = Record case SqlCases of |
| 0: (dummy: Integer); |
| 1: (REC1 : SQLREC1); |
| 2: (REC2 : SQLREC2); |
| 3: (REC3 : SQLREC3); |
| 4: (REC4 : SQLREC4); |
| end; |
_______________________________________________________
Figure 2-9. Sample SQLTYPE (page 2 of 2)
_____________________________________
| |
| Var |
| SQLvar1 : String[264]; |
| SQLvar2 : String[16]; |
| SQLvar3 : String[8]; |
| SQLvar4 : String[8]; |
| SQLvar5 : String[48]; |
| sqlTempV : SqlTempV_Type; |
_____________________________________
Figure 2-10. Sample SQLVAR
_________________________________________________________________
| |
| procedure SQLXCON( sqlcap : SmallInt; |
| var stmt : String); external; |
| procedure SQLXSTP( sqlcap : SmallInt); external;|
| procedure SQLXFET( sqlcap : SmallInt; |
| owner : OwnerName_Type; |
| xmodule : ModuleName_Type; |
| section : Integer; |
| parms : SmallInt; |
| inParms : Integer; |
| outParms : Integer; |
| isSelect : boolean); external; |
| procedure SQLXOPN( sqlcap : SmallInt; |
| owner : OwnerName_Type; |
| xmodule : ModuleName_Type; |
| section : Integer; |
| parms : SmallInt; |
| inParms : Integer); external; |
| procedure SQLXIDU( sqlcap : SmallInt; |
| owner : OwnerName_Type; |
| xmodule : ModuleName_Type; |
| section : Integer; |
| parms : SmallInt; |
| inParms : Integer; |
| isBulk : boolean); external; |
| procedure SQLXPRE( sqlcap : SmallInt; |
| queryPtr : SMallInt; |
| querySize : Integer; |
| xmodule : ModuleName_Type; |
| section : Integer); external; |
| procedure SQLXEXS( sqlcap : SmallInt; |
| xmodule : ModuleName_Type; |
| section : Integer); external; |
| procedure SQLXEXI( sqlcap : SmallInt; |
| queryPtr : SmallInt; |
| querySize : Integer); external; |
| procedure SQLXDES( sqlcap : SmallInt; |
| sqldap : SmallInt; |
| xmodule : ModuleName_Type; |
| section : Integer); external; |
| procedure SQLXDFE( sqlcap : SmallInt; |
| sqldap : SmallInt; |
| xmodule : ModuleName_Type; |
| section : Integer); external; |
_________________________________________________________________
Figure 2-11. Sample SQLEXTN (page 1 of 2)
_________________________________________________________________
| |
| procedure SQLXBFE( sqlcap : SmallInt; |
| owner : OwnerName_Type; |
| xmodule : ModuleName_Type; |
| section : Integer; |
| parms : SmallInt; |
| inParms : Integer; |
| outArray : SmallInt; |
| entrySize : Integer; |
| nEntry : Integer; |
| firstRow : Integer; |
| nRow : Integer); external; |
| procedure SQLXBIN( sqlcap : SmallInt; |
| owner : OwnerName_Type; |
| xmodule : ModuleName_Type; |
| section : Integer; |
| inArray : SmallInt; |
| entrySize : Integer; |
| nEntry : Integer; |
| firstRow : Integer; |
| nRow : Integer); external; |
| Procedure SQLXPLN( sqlcap : SmallInt; |
| MsgStrp : SmallInt; |
| xStrLen : integer; |
| IsVarChar : integer);External; |
| procedure SQLXSECT( sqlca : SmallInt; |
| owner : OwnerName_Type; |
| modul : ModuleName_Type; |
| section : integer); external; |
| procedure SQLXSVPT( sqlca : SmallInt; |
| xstrLen : integer; |
| var hexStr : string; |
| svptrec : SmallInt); external;|
| procedure SQLXCNH( sqlcap : SmallInt; |
| MsgStrp : SmallInt; |
| xStrLen : integer; |
| IsVarChar : integer); external; |
_________________________________________________________________
Figure 2-11. Sample SQLEXTN (page 2 of 2)
SQLMSG
Messages placed in SQLMSG come from the HP SQL message catalog, named
HPSQLCAT.PUB.SYS by default. Ensure that the message catalog is
available when you invoke the Pascal preprocessor. SQLMSG messages
contain four parts: 1. A banner:
WED, JUL 22, 1987, 1:38 PM
HP36215B.01.00 PASCAL Preprocessor/3000 HP SQL/V
(C) COPYRIGHT HEWLETT-PACKARD CO., 1982,1983,1984,1985,1986,1987
2. A summary of the preprocessor invocation conditions:
SQLIN = PASEX2.SomeGrp.SomeAcct
DBEnvironment = PartsDBE
Module Name = PASEX2
3. Warnings and errors encountered during preprocessing:
30 SalesPriceInd : SQLID;
|
****** Unsupported type syntax for host variable. (DBERR 10933)
.
.
.
There are errors. No sections stored.
4. A summary of the results of preprocessing:
2 ERRORS 0 WARNINGS
END OF PREPROCESSING.
PROGRAM TERMINATED IN AN ERROR STATE. (CIERR 976)
:
When you equate SQLMSG to $STDLIST, all these messages appear at the
terminal during a session or in the job stream listing. When SQLMSG is
not equated to $STDLIST, parts 1 and 4 are still sent to $STDLIST, and
all parts appear in the file equated to SQLMSG:
:FILE SQLMSG=MyMsg;Rec=-80,16,f,Ascii
:FILE SQLIN=PASEX2
:RUN PSQLPAS.PUB.SYS;INFO="PartsDBE"
WED, JUL 22, 1987, 1:38 PM
HP36215B.01.00 PASCAL Preprocessor/3000 HP SQL/V
(C) COPYRIGHT HEWLETT-PACKARD CO., 1982,1983,1984,1985,1986,1987
2 ERRORS 0 WARNINGS
END OF PREPROCESSING.
PROGRAM TERMINATED IN AN ERROR STATE. (CIERR 976)
If you want to keep the message file, you should save the file you equate
to SQLMSG. It is created as a temporary file.
As illustrated in Figure 2-12, a line number is often provided in SQLMSG.
This line number references the line in SQLIN containing the command in
question. A message accompanied by a number may also appear. You can
refer to the HP SQL Message Manual for additional information on the
exception condition when these numbered messages appear.
________________________________________________________________________
| |
| :EDITOR |
| HP32201A.07.17 EDIT/3000 FRI, JUL 24, 1987, 10:20 AM |
| (C) HEWLETT-PACKARD CO. 1985 |
| /T MyMsg;L ALL UNN |
| FILE UNNUMBERED |
| . |
| . |
| |
| |
| 29 SalesPriceInd : SQLID; |
| | |
| ****** Unsupported type syntax for host variable. (DBERR 10933)|
| There are errors. No sections stored. |
| . |
| . |
| 2 ERRORS 0 WARNINGS |
| END OF PREPROCESSING |
________________________________________________________________________
Figure 2-12. Sample SQLMSG Showing Errors
As Figure 2-13 illustrates, the preprocessor can terminate with a warning
message. Although a section is stored for the semantically incorrect
command, the section is marked as invalid and will not execute at run
time if it cannot be validated.
_____________________________________________________________________________
| |
| :RUN PSQLPAS.PUB.SYS;INFO="PartsDBE" |
| |
| FRI, JUL 24, 1987, 10:15 AM |
| HP36216-02A.01.00 PASCAL Preprocessor/3000 HP SQL/V |
| (C) COPYRIGHT HEWLETT-PACKARD CO., 1982,1983,1984,1985,1086,1987 |
| |
| SQLIN = PASEX2.SOMEGRP.SOMEACCT |
| DBEnvironment = PartsDBE |
| |
| Module Name = PASEX2 |
| |
| 0 ERRORS 1 WARNINGS |
| END OF PREPROCESSING |
| |
| :EDITOR |
| HP32201A.07.17 EDIT/3000 FRI, JUL 24 1987, 10:20 AM |
| (C) HEWLETT-PACKARD CO. 1985 |
| /T SQLMSG;L ALL UNN |
| FILE UNNUMBERED |
| . |
| . |
| SELECT PartNumber, PartName, SalesPrice INTO :Partnumber, :PartName,|
| :SalesPrice :SalesPriceInd FROM PurchDB.Parts WHERE ParNumber = |
| :PartNumber; |
| | |
| ****** HP SQL warnings (DBWARN 10602 ) |
| ****** in SQL statement ending in line 125 |
| *** Column PARNUMBER not found. (DBERR 2211) |
| 1 Sections stored in DBEnvironment. |
| 0 ERRORS 1 WARNINGS |
| END OF PREPROCESSING. |
_____________________________________________________________________________
Figure 2-13. Sample SQLMSG Showing Warning
SQLMOD
When the Pascal preprocessor stores a module in the system catalog of a
DBEnvironment at preprocessing time, it places a copy of the module in
SQLMOD. The module in this file can be installed into a DBEnvironment
different from the DBEnvironment accessed at preprocessing time by using
the INSTALL command in ISQL:
If you want to preserve SQLMOD after preprocessing,
you must keep it as a permanent file. Rename SQLMOD
after making it permanent:
:SAVE SQLMOD
:RENAME SQLMOD,MYMOD
Before invoking ISQL to install the module contained
in SQLMOD, you may have to transport it and its related
program file to the machine containing the target
DBEnvironment. You invoke ISQL on the machine containing
the target DBEnvironment:
:ISQL
In order to install the module, you need CONNECT
or DBA authority in the target DBEnvironment:
isql=> CONNECT TO 'PARTSDBE.SomeGrp.SomeAcct';
isql=> INSTALL;
File name> MYMOD.SOMEGRP.SOMEACCT;
Name of module in this file: SomeUser@SomeAcct.PASEX2
Number of sections installed: 1
COMMIT WORK to save to DBEnvironment.
isql=> COMMIT WORK;
isql=>
Stored Sections
In full preprocessing mode, the preprocessor stores a section for each
embedded command except:
BEGIN DECLARE SECTION OPEN CURSOR
BEGIN WORK PREPARE
CLOSE CURSOR RELEASE
COMMIT WORK ROLLBACK WORK
CONNECT SAVEPOINT
END DECLARE SECTION START DBE
EXECUTE STOP DBE
EXECUTE IMMEDIATE TERMINATE USER
INCLUDE WHENEVER
The commands listed above either require no authorization to execute or
are executed based on information contained in the compilable
preprocessor output files.
When the preprocessor stores a section, it actually stores what is known
as an input tree and a run tree. The input tree consists of an
uncompiled command. The run tree is the compiled, executable form of the
command.
If at run time a section is valid, HP SQL executes the appropriate run
tree when the SQL command is encountered in the application program. If
a section is invalid, HP SQL determines whether the objects referenced in
the sections exist and whether current authorization criteria are
satisfied. When an invalid section can be validated, HP SQL dynamically
recompiles the input tree to create an executable run tree and executes
the command. When a section cannot be validated, the command is not
executed, and an error condition is returned to the program.
There are three types of sections:
1. Sections for executing the SELECT command associated with a
DECLARE CURSOR command
2. Sections for executing the SELECT command associated with a CREATE
VIEW command
3. Sections for all other commands for which the preprocessor stores
a section.
Figure 2-14 illustrates the kind of information in the system catalog
that describes each type of stored section. The query result illustrated
was extracted from the system view named SYSTEM.SECTION by using ISQL.
The columns in Figure 2-14 have the following meanings:
* NAME: This column contains the name of the module to which a section
belongs. You specify a module name when you invoke the preprocessor;
the module name is by default the program name from the Pascal
program.
* OWNER: This column identifies the owner of the module. You specify
an owner name when you invoke the preprocessor; the owner name is by
default the log-on UserName@AccountName associated with the
preprocessing session.
* DBEFILESET: This column indicates the DBEFileSet with which DBEFiles
housing the section are associated.
* SECTION: This column gives the section number. Each section
associated with a module is assigned a number by the preprocessor as
it parses the related SQL command at preprocessing time.
* TYPE: This column identifies the type of section:
1 = SELECT associated with a cursor
2 = SELECT defining a view
0 = All other sections
* VALID: This column identifies whether a section is valid or invalid:
0 = invalid
1 = valid
____________________________________________________________________________________
| |
| isql=>SELECT NAME,OWNER,DBEFILESET,SECTION,TYPE,VALID FROM SYSTEM.SECTION; |
| SELECT NAME,OWNER,DBEFILESET,SECTION,TYPE,VALID FROM SYSTEM.SECTION; |
| -----------------------------------------------------------------------------|
| NAME |OWNER |DBEFILESET |SECTION |TYPE |VALID |
| -----------------------------------------------------------------------------|
| TABLE |SYSTEM |SYSTEM | 0| 2| 0 |
| COLUMN |SYSTEM |SYSTEM | 0| 2| 0 |
| INDEX |SYSTEM |SYSTEM | 0| 2| 0 |
| SECTION |SYSTEM |SYSTEM | 0| 2| 0 |
| DBEFILESET |SYSTEM |SYSTEM | 0| 2| 0 |
| DBEFILE |SYSTEM |SYSTEM | 0| 2| 0 |
| SPECAUTH |SYSTEM |SYSTEM | 0| 2| 0 |
| TABAUTH |SYSTEM |SYSTEM | 0| 2| 0 |
| COLAUTH |SYSTEM |SYSTEM | 0| 2| 0 |
| MODAUTH |SYSTEM |SYSTEM | 0| 2| 0 |
| GROUP |SYSTEM |SYSTEM | 0| 2| 0 |
| PARTINFO |PURCHDB |SYSTEM | 0| 2| 0 |
| VENDORSTATISTICS |PURCHDB |SYSTEM | 0| 2| 0 |
| PASEX2 |KAREN@THOMAS |SYSTEM | 1| 0| 1 |
| EXP11 |KAREN@THOMAS |SYSTEM | 1| 1| 1 |
| EXP11 |KAREN@THOMAS |SYSTEM | 2| 0| 1 |
| -----------------------------------------------------------------------------|
| Number of rows selected is 16. |
| U[p], d[own], l[eft], r[ight], t[op], b[ottom], pr[int] <n>,or e[nd]> |
____________________________________________________________________________________
Figure 2-14. Information in SYSTEM.SECTION on Stored Sections
The first eleven rows in this query result describe the sections stored
for the system views. The next two rows describe the two views in the
sample database: PurchDB.PartInfo and PurchDB.VendorStatistics. Views
are always stored as invalid sections, because the run tree is always
generated at run time.
The remaining rows describe sections associated with two preprocessed
programs. PASEX2 contains only one section, for executing the SELECT
command in the program illustrated in Figure 2-6. EXP11 contains two
sections, one for executing the SELECT command associated with a DECLARE
CURSOR command and one for executing a FETCH command.
Stored sections remain in the system catalog until they are deleted with
the DROP MODULE command or by invoking the preprocessor with the DROP
option:
isql=> DROP MODULE PASEX2;
or
:RUN PSQLPAS.PUB.SYS;INFO="PartsDBE (MODULE(PASEX2) DROP)"
Stored sections are marked invalid when:
* The UPDATE STATISTICS command is executed.
* Tables accessed in the program are dropped, altered, or assigned new
owners.
* Indexes or DBEFileSets related to tables accessed in the program are
changed.
* Module owner authorization changes occur that affect the execution of
embedded commands.
When an invalid section is validated at run time, the validated section
is committed when the program issues a COMMIT WORK command. If a COMMIT
WORK command is not executed, HP SQL must revalidate the section again
the next time the program is executed. For this reason, you should embed
COMMIT WORK commands even following SELECT commands, since the COMMIT
WORK command may be needed even when data is not changed by a program.