Variable and Type Declarations
The following sections describe variable and type declarations.
Embedded SQL Variable Declaration Sections
Embedded SQL statements use Fortran variables to transfer data between the database, or a form, and the program. You can also use Fortran constants in those SQL statements transferring data from the program into the database. You must declare Fortran variables, constants and structure definitions to SQL before using them in any Embedded SQL statements. The preprocessor does not allow the declaration of Fortran variables by implication. Fortran variables are declared to SQL in a declaration section. This section has the following syntax:
exec sql begin declare section
Fortran variable declarations
exec sql end declare section
Embedded SQL variable declarations are global to the program file from the point of declaration onward. Multiple declaration sections can be incorporated into a single file, as is the case when a few different Fortran subprograms issue embedded statements using local variables. Each subprogram can have its own declaration section. For more information on the declaration of variables and types that are local to Fortran subprograms see
The Scope of Variables in this chapter.
Reserved Words in Declarations
Fortran keywords are reserved, therefore you cannot declare types or variables with the same name as these keywords:
The Embedded SQL preprocessor does not distinguish between uppercase and lowercase in keywords. In generating Fortran code, it converts any uppercase letters in keywords to lowercase.
Variable and Type Declarations
The preprocessor recognizes numeric variables declared with the following format:
data_type [*default_type_len]
var_name [*type_len] [(array_spec)] [/init_clause/]
{, var_name [*type_len] [(array_spec)] [/init_clause/]}
The preprocessor recognizes character variables declared with the following format:
data_type [*default_type_len[,]]
var_name [(array_spec)] [*type_len] [/init_clause/]
{, var_name [(array_spec)] [*type_len] [/init_clause/]}
Syntax Notes:
• A variable or type name must begin with an alphabetic character, which can be followed by alphanumeric characters. In VMS and Windows, it can also be followed by underscores.
• For information on the allowable
data_types, see
Data Types in this chapter.
• The default_type_len specifies the size of the variable being declared. For variables of numeric type, it must be represented by an integer literal of an acceptable length for the particular data type. For variables of character type, it can be represented by an integer literal or a parenthesized expression followed optionally by a comma. The preprocessor does not parse the length field for variables of type character. Note the default type lengths in the declarations shown below:
C Declares "eage" a 2-byte integer
integer*2 eage
C Declares "stat" a 4-byte integer
integer*4 stat
C Declares "ename" a character string
character*(4+len) ename
• The type_len allows you to declare a variable with a length different from default_type_len. Again, you can use a parenthesized expression only to declare the length of character variable declarations. The type length for a numeric variable must be an integer literal representing an acceptable numeric size. For example:
C Default-sized integer and 2-byte integer
integer length
integer*2 height
character*15 name, socsec*(numlen)
Some UNIX Fortran compilers do not permit the length of a character variable to be redeclared.
• The data type and variable names must be legal Fortran identifiers beginning with an alphabetic character. In VMS, it can also begin with an underscore.
• The array_spec should conform to Fortran syntax rules. The preprocessor simply notes that the declared variable is an array but does not parse the array_spec clause. Note that if you specify both an array and a type length, the order of those two clauses differs depending on whether the variable being declared is of character or numeric type. The following are examples of array declarations:
C Array specification first
character*16 enames(100), edepts(15)*10
C Type length first
real*4 saltab(5,12), real*8 yrtots(12)
• The preprocessor allows you to initialize a variable or array in the declaration statement by means of the init_clause. The preprocessor accepts, but does not examine, any initial data. The Fortran compiler, however, will later detect any errors in the initial data. For example:
real*8 initcash /512.56/
character*4 baseyear /'1950'/
character*4 year /1950/
C Acceptable to preprocessor but not to compiler
Do not continue initial data over multiple lines. If an initialization value is too long for the line, as could be the case with a string constant, instead use the Fortran DATA statement. For UNIX, init_clause is an extension to the F77 standard.
Constant Declarations
UNIX:
You can declare constants to the preprocessor using the Fortran parameter statement using the following syntax:
parameter (const_name = value {, const_name = value})
Syntax Notes:
• The preprocessor derives the data type of const_name from the data type of value. The F77 compiler uses implicit data typing; it derives the data type of value from the first letter of const_name. Be sure that the type of the specified value is the same as the implicit type derived from const_name.
• The value can be a real, integer or character literal. It cannot be an expression or a symbolic name.
The following example declaration illustrates the parameter statement:
C real constant
parameter (pi = 3.14159 )
C integer and real
parameter (bigint = 2147483648, bignum = 999999.99
VMS:
You can declare constants to the preprocessor using the Fortran parameter statement using the following syntax:
parameter const_name = value {, const_name = value}
Syntax Notes:
• The preprocessor and the compiler derive the data type of const_name from the data type of value. Neither the preprocessor nor the compiler make use of implicit data typing. Explicit data type declarations are not allowed in parameter statements.
• The value can be a real, integer or character literal. It cannot be an expression or a symbolic name.
The following example declarations illustrate the parameter statement:
parameter (pi = 3.14159 ) real constant
parameter (bigint = 2147483648,
bignum = 999999.99) !integer and real
Windows:
You can declare constants to the preprocessor using the Fortran parameter statement using the following syntax:
parameter [(]const_name = value {, const_name = value}[)]
• The preprocessor and the compiler derive the data type of const_name by an explicit type declaration statement in the same scoping unit or by the implicit typing rules in effect for the scoping unit. If the named constant is implicitly typed, it can appear in a subsequent type declaration only if that declaration confirms the implicit typing.
• The value can be an expression of any data type.
The following example declarations illustrate the parameter statement:
C real constant
parameter pi = 3.14159
C integer and real
parameter (bigint = 2147483648, bignum = 999999.99)
Data Types
The Embedded SQL preprocessor accepts the following elementary Fortran data types and maps them to corresponding Ingres data types. For a description of exact type mapping, see
Data Type Conversion in this chapter.
Integer Data Type
The Fortran compiler allows the default size of integer variables to be either two or four bytes in length, depending on whether the -i2 compiler flag (UNIX), the noi4 flag (VMS), or the /integer_size:16 or /4I2 (Windows) is set.
This feature is also supported in Embedded SQL/Fortran by means of the preprocessor flag -i2. This flag allows you to change the default size of integer variables to two from the normal default size of four bytes. For detailed information on this flag, see
Preprocessor Operation in this chapter.
You can explicitly override the default size when declaring the Fortran variable to the preprocessor. To do so, you must specify a size indicator (*2 or *4) following the integer keyword, as these examples illustrate:
integer*2 smlint
integer*4 bigint
These declarations create Embedded SQL integer variables of two and four bytes, respectively, regardless of the default setting.
The preprocessor treats byte and logical data type as integer data types. A logical variable has a default size of either 2 or 4 bytes according to whether the -i2 flag has been set. You can override this default size by using a size indicator of 1, 2, or 4. For example:
logical logl*1, log2*2, log4*4
The byte data type has a size of one byte. You cannot override this size.
You can use an integer or byte variable with any numeric-valued object to assign or receive numeric data. For example, you can use such a variable to set a field in a form or to select a column from a database table. It can also specify simple numeric objects, such as table field row numbers. You can use a logical variable to assign or receive integer data, although your program should restrict its value to 1 and 0, which map respectively to the Fortran logical values .TRUE. and .FALSE..
Real Data Type
The preprocessor accepts real and double precision as legal real data types. The preprocessor accepts both 4-byte and 8-byte real variables. It makes no distinction between an 8-byte real variable and a double precision variable. The default size of a real variable is four bytes. However, you can override this size if you use a size indicator (*8) after the real keyword. For example:
C 4-byte real variable
real salary
C 8-byte real variable
real*8 yrtoda
C 8-byte real variable
double precision saltot
You can only use a real variable to assign or receive numeric data (both real, decimal, and integer). You cannot use it to specify numeric objects, such as table field row numbers.
VMS:
The preprocessor expects the internal format of
real and double precision variables to be the standard VAX format. For this reason, you should not compile your program with the g_floating qualifier.
Character Data Type
Variables of type character are compatible with all Ingres character string objects. The preprocessor does not need to know the declared length of a character string variable to use it at runtime. Therefore, it does not check the validity of any expression or symbolic name used to declare the length of the string variable. You should ensure that your string variables are long enough to accommodate any possible runtime values. For example:
character*7 first
character*10 last
character*1 init
character*(bufsiz) msgbuf
For information on the interaction between character string variables and Ingres data at runtime, see
Runtime Character and Varchar Type Conversion in this chapter.
Character strings containing embedded single quotes are legal in SQL, for example:
mary's
User variables may contain embedded single quotes and need no special handling unless the variable represents the entire search condition of a where clause:
where :variable
In this case you must escape the single quote by reconstructing the :variable string so that any embedded single quotes are modified to double single quotes, as in:
mary''s
Otherwise, a runtime error will occur. For more information on escaping single quotes, see
String Literals in this chapter.
Structure and Record Declarations Syntax
The Embedded SQL preprocessor supports the declaration and use of user-defined structure variables. In UNIX, the structure variables are an extension to the F77 standard and may not be available on all Fortran compilers.
The syntax of a structure definition is:
structure [/structdef_name/] [field_namelist]
field_declaration
{field_declaration}
end structure
Syntax Notes:
• The structdef_name is optional only for a nested structure definition.
• The field_namelist is allowed only with a nested structure definition. Each name in the field_namelist constitutes a field in the enclosing structure.
• The field_declaration can be a typed data declaration, a nested structure declaration, a union declaration, a record declaration, or a fill item.
The syntax of a union declaration is:
union
map_declaration
map_declaration
{map_declaration}
end union
where map_declaration is:
map
field_declaration
{field_declaration}
end map
To use a structure with Embedded SQL statements, you must both define the structure and declare the structure's record in the Embedded SQL declaration section of your program. The syntax of the record declaration is:
record /structdef_name/ structurename {,[/structdef_name/]
structurename}
Note: The structdef_name must have been previously defined in a structure statement.
For information on the use of structure variables in Embedded SQL statements, see
Structure Variables in this chapter.
The following example includes a structure definition and a record declaration:
structure /name_map/
union
map
character*30 fullname
end map
map
character*10 firstnm
character*2 init
character*18 lastnm
end map
end union
end structure
record /name_map/ empname
The next example shows the definition of a structure containing an array of nested structures:
structure /class_struct/
character*10 subject
integer*2 year
structure student(100)
C No structure definition name needed
character*12 name
byte grade
end structure
end structure
record /class_struct/ classrec
DCLGEN Utility
DCLGEN (Declaration Generator) is a utility that maps the columns of a database table into a Fortran structure that can be included in a declaration section. The following command invokes DCLGEN from the operating system level:
dclgen language dbname tablename filename structurename [-n] [-q]
language
Defines the embedded SQL host language, in this case, Fortran.
dbname
Defines the name of the database containing the table.
tablename
Defines the name of the database table.
filename
Defines the output file into which the structure declaration is placed.
structurename
Defines the name of the host language structure (COBOL record) that the command generates.
-n
Does not print the DECLARE TABLE statement.
-q
Creates output in QUEL format.
The command generates a structure definition named structurename followed by an underscore character (_). It also generates a RECORD statement for the structure variable of structurename.
The DCLGEN utility creates the declaration file filename, containing a structure or a series of Fortran variables, if the -f77 flag is used, corresponding to the database table. The file also includes a declare table statement that serves as a comment and identifies the database table and columns from which the variables were generated.
UNIX:
DCLGEN has the option to map the columns of a database table into a series of Fortran variables rather than into a Fortran structure. This is useful if your Fortran compiler does not support structures. Specify the -f77 flag to indicate this DCLGEN option as follows:
dclgen -f77 language dbname tablename filename prefixname
The
prefixname is required when
-f77 is used. This prefix is appended to the column names of the table to produce the Fortran variables.
After the file is generated, you can use an Embedded SQL INCLUDE statement to incorporate it into the variable declaration section. The following example demonstrates how to use DCLGEN in a Fortran program.
Assume the "employee" table was created in the "personnel" database as:
exec sql create table employee
(eno smallint not null,
ename char(20) not null,
age integer1,
job smallint,
sal decimal(14,2) not null,
dept smallint)
When the DCLGEN system-level command is:
dclgen fortran personnel employee employee.dcl emprec
the "employee.dcl" file created by this command contains a comment, and three statements. The first statement is the declare table description of "employee," which serves as a comment. The second statement is a declaration of the Fortran structure "emprec_". The last statement is a record statement for "emprec".
The contents of the "employee.dcl" file are:
c Description of table employee from database personnel
exec sql declare employee table
1 (eno smallint not null,
1 ename char(20) not null,
1 age integer1,
1 job smallint,
1 sal decimal(14,2) not null,
1 dept smallint)
structure /emprec_/
integer*2 eno
character*20 ename
integer*2 age
integer*2 job
real*8 sal
integer*2 dept
end structure
record /emprec_/ emprec
UNIX:
For this example the DCLGEN system-level command is:
dclgen -f77 fortran personnel employee employee.dcl emp
The "employee.dcl" file created by this command contains a comment, a DECLARE TABLE statement and the variable declarations. The DECLARE TABLE statement describes the employee table and serves as a comment. The exact contents of the "employee.dcl" file are:
C Description of table employee from database personnel
exec sql declare employee table
1 (eno smallint not null,
1 ename char(20) not null,
1 age integer1,
1 job smallint,
1 sal decimal(14,2) not null,
1 dept smallint)
integer*2 empeno
character*20 empename
integer*2 empage
integer*2 empjob
real*8 empsal
integer*2 empdept
The Ingres integer1 data type is mapped to the Fortran integer*2 data type, rather than to byte.
Include this file, by means of the Embedded SQL INCLUDE statement, in an Embedded SQL declaration section:
exec sql begin declare section
exec sql include 'employee.dcl'
exec sql end declare section
You can then use the variables in data manipulation statements.
The field names of the structure that DCLGEN generates are identical to the column names in the specified table. Therefore, if the column names in the table contain any characters that are illegal for host language variable names you must modify the name of the field before attempting to use the variable in an application.
DCLGEN and Large Objects
When a table contains a large object column, DCLGEN will issue a warning message and map the column to a zero length character string variable. You must modify the length of the generated variable before attempting to use the variable in an application.
For example, assume that the "job_description" table was created in the "personnel" database as:
create table job_description
(job smallint, description long varchar))
and the DCLGEN system-level command is:
dclgen fortran personnel job_description jobs.dcl jobs_rec
The contents of the "jobs.dcl" file would be:
C Description of table job_description from database
C personnel
exec sql declare job_description table
1 (job smallint not null,
description long varchar)
structure /jobs_rec_/
integer*2 job
character*0 description
end structure
record /jobs_rec/ blobs_rec
The table definition when used with the -f77 flag (assuming the prefix of "b_" was specified) results in the following DCLGEN generated output in "jobs.dcl":
exec sql declare job_description table
1 (job smallint,
description long varchar)
character*0 b_description
Indicator Variables
An indicator variable is a 2-byte integer variable. You can use an indicator variable in an application in three ways:
• In a statement that retrieves data from Ingres, you can use an indicator variable to determine if its associated host variable was assigned a null.
• In a statement that sets data to Ingres, you can use an indicator variable to assign a null to the database column, form field, or table field column.
• In a statement that retrieves character (or byte) data from Ingres, you can use the indicator variable as a check that the associated host variable was large enough to hold the full length of the returned string. However, the preferred method is to use SQLSTATE.
The base type for a null indicator variable must be the integer type integer*2. For example:
C Indicator variable
integer*2 indvar
C Array of indicator variables
integer*2 indarr(10)
The word indicator is reserved.
When using an indicator array with a host structure (see
Indicator Variables Usage in this chapter), you must declare the indicator array as an array of integer*2 variables. In the above example, you can use the variable "indarr" as an indicator array with a structure assignment.
How to Declare External Compiled Forms
You can precompile your forms in the Visual Forms Editor (VIFRED). This saves the time otherwise required at runtime to extract the form's definition from the database forms catalogs. For an outline of steps for UNIX, Windows and VMS, see
Link Precompiled Forms in this chapter.
In UNIX, when you compile a form in VIFRED, VIFRED creates a file in your directory describing the form in the C language. VIFRED prompts you for the name of the file. After creating the file, you can compile it into a linkable object module.
In Windows, when you compile a form in VIFRED, VIFRED creates a file in your directory describing the form in the C language. VIFRED prompts you for the name of the file. After creating the file, you can compile it into a linkable object module.
In VMS, when you compile a form in VIFRED, VIFRED creates a file in your directory describing the form in the MACRO language. VIFRED prompts you for the name of the file with the MACRO description. When the file is created, you can assemble it into a linkable object module.
In UNIX, Windows, and VMS, before the Embedded SQL/FORMS statement addform can refer to this object, the object must be declared in an Embedded SQL declaration section, with the following syntax:
integer formname
Next, in order for the program to access the external form definition, you must declare the formname as an external symbol:
external formname
This second declaration must take place outside the Embedded SQL declaration section. (Note, however, that the previous declaration of formname as an integer must occur inside the declaration section, so that you can use formname with the addform statement.)
Syntax Notes:
• The formname is the actual name of the form. VIFRED gives this name to the address of the global object. The formname is also used as the title of the form in other Embedded SQL/FORMS statements.
• The external statement associates the object with the external form definition.
The following example shows a typical form declaration and illustrates the difference between using the form's object definition and the form's name:
Example: Form declaration
exec sql begin declare section
integer empfrm
...
exec sql end declare section
external empfrm
...
C The global object
exec frs addform :empfrm
C The name of the form
exec frs display empfrm
...
Embedded SQL/Fortran Declarations Example
The following example demonstrates some simple Embedded SQL/Fortran declarations:
C Include error handling
exec sql include sqlca
exec sql begin declare section
C Variables of each data type
byte dbyte
logical*1 dlog1
logical*2 dlog2
logical*4 dlog4
logical dlog
integer*2 dint2
integer*4 dint4
integer dint
real*4 dreal4
real*8 dreal8
real dreal
double precision ddoub
parameter (max = 1000)
character*12 dbname
character*12 fname, tname, cname
C Structure with a union
structure /person/
byte age
integer flags
union
map
character*30 fullnm
end map
map
character*12 first
character*18 last
end map
end union
end structure
record /person/ person, ptable(MAX)
C From DCLGEN
exec sql include 'employee.dcl'
C Compiled forms
integer empfrm, dptfrm
exec sql end declare section
external empfrm, dptfrm