Using program variables in static SQL
Static SQL syntax supports the usage of program variables as SQL parameters.
Understanding SQL host variables
MAIN
  DEFINE c_num INTEGER
  DEFINE c_name CHAR(10)
  DATABASE stock 
  SELECT cust_name INTO c_name FROM customer WHERE cust_num = c_num
END MAINUsing the $ prefix for host variables
The purpose of the $ prefix for program variables is to make the code more
readable, and force compilation errors whenever a variable is not defined. This feature was inspired
from ESQL/C. It applies only to static SQL statements (parsed by the compiler).
$ in static SQL statements, the compiler treats the identifier
following the $ as a program variable:SCHEMA stores
MAIN
    DEFINE rec RECORD LIKE customer.*
    DEFINE cust_id INTEGER
    SELECT * INTO rec.* FROM customer
        WHERE customer_num = $cust_id
END MAIN$ sign will not figure in the resulting SQL statement stored in the
.42m compiled module.In a static SELECT statement, the INTO
var-list clause is not part of the final SQL statement. There is no need
for a $ dollar sign before variables that appear after the INTO
keyword.
When not marking program variables with $, the compiler performs a fuzzy look up
for each symbol that can be a potential program variable: If a variable exists for a given symbol,
the compiler uses that variable. Otherwise, the compiler assumes that the symbol is a column
name.
$ dollar signs before program variables in SQL statements prevents
spelling
errors:DEFINE cid INTEGER
SELECT ... WHERE cust_id = cid     -- ok, cid is a program variable
SELECT ... WHERE cust_id = $cid    -- ok, cid is a (marked) program variable
SELECT ... WHERE cust_id = c_id    -- fglcomp assumes column => gives SQL error at runtime!
SELECT ... WHERE cust_id = cust_id -- fglcomp assumes column => wrong SQL results at runtime!
SELECT ... WHERE cust_id = $c_id   -- fglcomp assumes variable => error -4369 (undefined)Using the @ prefix for database object names
@ prefix, the compiler treats the identifier following the
@ as an SQL object name (this syntax is supported for backward compatibility with
Informix
4GL):MAIN
  DEFINE cust_name CHAR(10)
  DEFINE cnt INTEGER
  DATABASE stock 
  SELECT COUNT(*) INTO cnt FROM customer WHERE @cust_name = cust_name 
END MAIN@ sign will not figure in the resulting SQL statement stored in the
.42m compiled module.A database object name may also conflict with another symbol of the program code, such as a
module name. In this case, you can also use the @ sign before the conflicting
database object name to solve the issue.
IMPORT FGL account
MAIN
    DEFINE rec RECORD
               pkey INTEGER,
               name VARCHAR(50)
           END RECORD
    SELECT * INTO rec.* FROM account
      WHERE @account.pkey = rec.pkey
END MAIN@ sign, the compiler would produce the following error, expecting
that account.pkey is a public variable of the imported account
module:IMPORT FGL account
MAIN
    DEFINE rec RECORD
               pkey INTEGER,
               name VARCHAR(50)
           END RECORD
    SELECT * INTO rec.* FROM account
      WHERE account.pkey = rec.pkey
| The symbol 'pkey' does not represent a defined variable.
| See error number -4369.
END MAINChecking for invalid column names
The fglcomp compiler provides the -W colname option, to check for SQL column names in static SQL statements,
based on the SQL table definitions of the current schema file.
customer" table with "fname" and "lname"
columns, the following code will produce a warning when using the -W colname
option:SCHEMA stores
MAIN
    DEFINE cnt INTEGER
    SELECT COUNT(*) INTO cnt FROM customer
       WHERE xfname IS NULL
END MAIN-W colname option:$ fglcomp -W colname main.4gl
main.4gl:5:14:5:19:warning:(-4322) The symbol 'xfname' is not the name of a column
   in the specified database.