253
SQR User's Guide Version 4 Part number 06-M-409-000-01 1080 Marsh Rd. Menlo Park, CA 94025 USA (800) 505-4399

SQR User's Guide

Embed Size (px)

Citation preview

Page 1: SQR User's Guide

SQR

User's Guide

Version 4

Part number 06-M-409-000-01

1080 Marsh Rd.

Menlo Park, CA 94025 USA

(800) 505-4399

Page 2: SQR User's Guide

SQR User's Guide, Version 4

Part Number: 06-M-409-000-01

Copyright © 1996 MITI

All rights reserved. Printed in the USA.

This publication pertains to SQR 4.0 and to any subsequent release until otherwiseindicated in new editions or technical notes. Information in this document issubject to change without notice. The software described herein is furnished undera license agreement, and it may be used or copied only in accordance with theterms of the agreement.

LIMITED WARRANTY

THE SQR PROGRAM AND LANGUAGE TUTORIAL ARE SOLD "AS IS," WITHOUTWARRANT AS TO THEIR PERFORMANCE, MERCHANTABILITY, OR FITNESS FORANY PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE RESULTS ANDPERFORMANCE OF THIS PROGRAM IS ASSUMED BY YOU.

HOWEVER, TO THE ORIGINAL PURCHASER ONLY, THE PUBLISHER WARRANTS THEMAGNETIC MEDIUM ON WHICH THE PROGRAM IS RECORDED TO BE FREE FROMDEFECTS IN MATERIALS AND FAULTY WORKMANSHIP UNDER NORMAL USE FORA PERIOD OF NINETY DAYS FROM THE DATE OF PURCHASE. IF DURING THENINETY-DAY PERIOD THE MEDIUM SHOULD BECOME DEFECTIVE, IT MAY BERETURNED TO THE PUBLISHER FOR A REPLACEMENT WITHOUT CHARGE,PROVIDED YOU HAVE PREVIOUSLY EXECUTED A SOFTWARE LICENSEAGREEMENT.

MITI, SQR, SQR Workbench, SQR3, SQR3 Workbench, Easy SQR, SQR Developer'sKit, SQR Execute, SQR Viewer, and SQR ReportMate are trademarks or registeredtrademarks of MITI.

All other company and product names used herein may be the trademarks orregistered trademarks of their respective companies.

Page 3: SQR User's Guide

SQR User's Guide iii

Contents

Introduction .......................................................................................................................... ixAudience.............................................................................................................................. xHow to Use the SQR User's Guide................................................................................... xRelated Documents ........................................................................................................... xiSyntax Conventions ......................................................................................................... xiiSetting up the Sample Database..................................................................................... xiiIf You Need Help ............................................................................................................xiii

Part 1—SQR Basics

1 A Simple SQR Program .................................................................................................... 1Creating and Running an SQR Program......................................................................... 1SQR Output......................................................................................................................... 2

2 Headings and Footings ..................................................................................................... 5

3 Selecting Data from the Database................................................................................... 9The SQR SELECT Statement........................................................................................... 11

Syntax of the SELECT Statement.......................................................................... 11Positioning Data ..................................................................................................... 12

4 Column Variables ............................................................................................................ 15

5 Break Logic........................................................................................................................ 19Using ON-BREAK............................................................................................................ 21Skipping Lines Between Groups .................................................................................... 22Arranging Multiple Break Columns.............................................................................. 23Break Processing with Enhancements ........................................................................... 25

Handling Page Breaks............................................................................................ 29Printing the Date..................................................................................................... 29Obtaining Totals ..................................................................................................... 30Hyphens and Underscores.................................................................................... 31

Setting Break Procedures with BEFORE and AFTER.................................................. 31Understanding the Order of Events..................................................................... 32

Controlling Page Breaks with Multiple ON-BREAK Columns.................................. 38Saving a Value When a Break Occurs ........................................................................... 38Using ON-BREAK on a Hidden Column...................................................................... 39Restrictions and Limitations of ON-BREAK................................................................. 41

6 The SETUP Section.......................................................................................................... 45Using DECLARE-LAYOUT ............................................................................................ 46

Part 2—SQR Reports

7 Master/Detail Reports ..................................................................................................... 49

Page 4: SQR User's Guide

Contents SQR 4.0

iv SQR User's Guide

Correlating Subqueries .................................................................................................... 51

8 Cross-Tabular Reports..................................................................................................... 55Arrays......................................................................................................................... ........ 56Creating the Array............................................................................................................ 59Grouping by Category ..................................................................................................... 60Using Multiple Arrays ..................................................................................................... 63

9 Printing Mailing Labels .................................................................................................. 69Defining Columns and Rows .......................................................................................... 70Running the Program....................................................................................................... 72

10 Creating Form Letters .................................................................................................... 75Laying Out the Letter....................................................................................................... 75

11 Exporting Data to Other Applications......................................................................... 79

Part 3—Fonts and Graphics

12 Using Graphics ............................................................................................................... 83Adding Graphics .............................................................................................................. 84Sharing Images among Reports...................................................................................... 88Printing Bar Codes ........................................................................................................... 92

13 Business Charts............................................................................................................... 95Creating a Chart................................................................................................................ 95Defining the Chart ............................................................................................................ 99Printing the Chart ........................................................................................................... 100Running the Program..................................................................................................... 100Passing Data to the Chart .............................................................................................. 102

14 Changing Fonts............................................................................................................. 105Positioning Text .............................................................................................................. 105Using WRAP ................................................................................................................... 108

15 Writing Printer-Independent Reports ...................................................................... 111Guidelines for Printer-Independent Reports .............................................................. 111

Part 4—Advanced SQR Programming

16 Dynamic SQL and Error Checking............................................................................ 115Using Variables in SQL.................................................................................................. 115Dynamic SQL .................................................................................................................. 117SQL Error Checking ....................................................................................................... 119SQL and Substitution Variables.................................................................................... 120

17 Procedures, Argument Passing, and Local Variables ............................................ 123Procedures ....................................................................................................................... 123

Local Variables...................................................................................................... 124

Page 5: SQR User's Guide

SQR 4.0 Contents

SQR User's Guide v

Argument Passing.................................................................................................124

18 Multiple Reports ...........................................................................................................1 31

19 Using DML and DDL SQL Statements......................................................................137Using BEGIN-SQL ..........................................................................................................137

20 Working with Dates .....................................................................................................141Date Arithmetic ...............................................................................................................141Date Formats....................................................................................................................144

String to Date Conversions ..................................................................................144Date to String Conversions ..................................................................................145

Using Dates with the INPUT Command .....................................................................145Date Edit Masks ..............................................................................................................146Declaring Date Variables................................................................................................148

21 National Language Support........................................................................................151Locales ........................................................................................................................ ......151

Available Locales ..................................................................................................151The Default Locale ..........................................................................................................152Switching Locales............................................................................................................153Modifying Locale Preferences .......................................................................................154Keywords—NUMBER, MONEY, and DATE..............................................................154

22 Interoperability ............................................................................................................ .157Calling SQR from Another Application.......................................................................158Using the SQR API..........................................................................................................158Extending SQR—UFUNC.C ..........................................................................................161Adding a User Function .................................................................................................162

Step 1. Add Function Prototype .........................................................................162Step 2. Add Entry to USERFUNCS Table .........................................................163Step 3. Add Implementation Code ....................................................................164Step 4. Relink SQR................................................................................................165

ufunc on Windows NT ...................................................................................................165Implementing New User Functions on Windows NT................................................166

23 Testing and Debugging ...............................................................................................167Using the Test Feature....................................................................................................167Using the #DEBUG Command......................................................................................168Using Compiler Directives for Debugging ..................................................................169Common Programming Errors......................................................................................169

24 Performance and Tuning .............................................................................................171SQR Performance and SQL Statements........................................................................171Simplifying a Complex SELECT ...................................................................................172Using LOAD-LOOKUP to Simplify Joins ....................................................................172Improving SQL Performance with Dynamic SQL ......................................................174

Page 6: SQR User's Guide

Contents SQR 4.0

vi SQR User's Guide

Examining SQL Cursor Status ...................................................................................... 175Avoiding Temporary Database Tables ........................................................................ 176

Using and Sorting Arrays.................................................................................... 176Using and Sorting Flat Files ................................................................................ 182

Creating Multiple Reports in One Pass ....................................................................... 184Tuning SQR Numerics ................................................................................................... 185Compiling SQR Programs and Using SQR Execute................................................... 186Processing Limits............................................................................................................ 186Buffering Fetched Rows................................................................................................. 187Executing Programs on the Database Server .............................................................. 187

Part 5—Running and Printing

25 Compiling Programs and Using SQR Execute........................................................ 189

26 Printing Issues .............................................................................................................. 191

27 Using the SQR Command Line ................................................................................. 197Command-Line Flags..................................................................................................... 198Specifying Command-Line Arguments....................................................................... 198

How SQR Retrieves the Arguments................................................................... 199Specifying Arguments and Argument Files...................................................... 199Using an Argument File....................................................................................... 200Passing Command-Line Arguments—Other Approaches.............................. 200Reserved Characters............................................................................................. 201Creating an Argument File from a Report ........................................................ 201

Using Batch Mode .......................................................................................................... 202VAX/VMS ............................................................................................................. 202UNIX, Windows NT, Windows 95, OS/2, and MS-DOS ................................ 202

28 Working with HTML................................................................................................... 205SQR Capabilities Available with HTML ..................................................................... 205

Producing HTML Output.................................................................................... 206HTML Output ....................................................................................................... 206Using -PRINTER:HT ............................................................................................ 207Setting Web Page Title and Body Attributes .................................................... 208Using Additional HTML Procedures................................................................. 209Output File Types ................................................................................................. 209Testing.................................................................................................................... 209

Using HTML Procedures in an SQR Program............................................................ 210How to Use HTML Procedures .......................................................................... 210Positioning Objects ............................................................................................... 211Table Procedures .................................................................................................. 212Headings................................................................................................................ 214Highlighting .......................................................................................................... 215Hypertext Links .................................................................................................... 215

Page 7: SQR User's Guide

SQR 4.0 Contents

SQR User's Guide vii

Images.....................................................................................................................216Lists .........................................................................................................................217Paragraph Formatting ..........................................................................................218User-Defined HTML.............................................................................................219

Modifying an Existing SQR Program ...........................................................................219Publishing the Report .....................................................................................................221

Viewing the Published Report.............................................................................222Publishing Using an Automated Process...........................................................222Publishing Using a CGI Script.............................................................................223Creating the Fill-Out Form...................................................................................224Creating the CGI Script ........................................................................................225Passing Arguments to the SQR Program ...........................................................227

Glossary ...............................................................................................................................229

Index.....................................................................................................................................235

Sample Programsex1a.sqr A Simple Program.................................................................................................1ex2a.sqr Printing a Heading and Footing ............................................................................6ex3a.sqr Selecting Data from the Database .........................................................................9ex5a.sqr A Simple Tabular Report ....................................................................................19ex5b.sqr A Report with Break Logic .................................................................................21ex5c.sqr Program with Multiple ON-BREAK Columns....................................................24ex5d.sqr Program with Break Logic and Enhancements ...................................................25ex5e.sqr Order of Events in Break Processing ..................................................................33ex5f.sqr Using Break Logic on a Hidden Column ............................................................39ex7a.sqr Master/Detail Report...........................................................................................50ex8a.sqr Cross-Tabular Report..........................................................................................57ex8b.sqr Cross-Tabular Report with Grouping by Category .............................................61ex8c.sqr Cross-Tabular Report with Grouping by Two Categories...................................63ex9a.sqr Mailing Labels Program......................................................................................69ex9b.sqr Mailing Labels Program (Alternate Layout) .......................................................73ex10a.sqr Form Letter Program...........................................................................................76ex11a.sqr Program to Create Tab-Delimited File................................................................79ex12a.sqr Tabular Report without Graphics........................................................................83ex12b.sqr Tabular Report with Graphics.............................................................................85

acme.inc ..............................................................................................................88ex12c.sqr Form Letter with Graphics ..................................................................................89ex13a.sqr Business Chart ....................................................................................................96ex14a.sqr Report with Multiple Fonts ...............................................................................107ex16a.sqr Using Variables in SQL ....................................................................................116ex16b.sqr Dynamic SQL ...................................................................................................118ex16c.sqr SQL and Substitution Variables........................................................................121spell.inc spell_number procedure....................................................................................125

Page 8: SQR User's Guide

Contents SQR 4.0

viii SQR User's Guide

ex17a.sqr Check-Writing Program ................................................................................... 128ex18a.sqr Multiple Report Program.................................................................................. 131ex19a.sqr External Files and Database Inserts.................................................................. 138ex24a.sqr QuickSort Procedure ........................................................................................ 178ex24b.sqr Sorting a Flat File ............................................................................................. 183ex28a.sqr Simple Tabular Program with HTML Procedures............................................ 213ex28b.sqr Program ex12a.sqr Modified with HTML Procedures ..................................... 219

Tables

Table 1. Syntax Conventions...................................................................................................xiiTable 2. Commands Available in the SETUP Section ............................................................ 45Table 3. Sample Date Edit Masks ......................................................................................... 146Table 4. The SQR API ..........................................................................................................159Table 5. Error Values Returned by the SQR API.................................................................. 161Table 6. Compile-Time Commands and Run-Time Equivalents........................................... 190Table 7. Command-Line Flags and Output Types................................................................. 191Table 8. Print Commands by Operating System.................................................................... 194Table 9. SQR Command-Line Arguments............................................................................. 197

Page 9: SQR User's Guide

SQR User's Guide ix

Introduction

Welcome to the SQR User's Guide. This guide is designed to help you learnSQR, a specialized language for database processing and reporting. Byworking through code examples, you will learn how to write programsthat select data from the database and present it in a report.

This User's Guide is filled with real examples and sample programs, and weencourage you to copy code from it. It will help you create the kinds ofSQR programs that are important to your organization.

The first three parts of the User's Guide teach basic uses of SQR. You willlearn how to:

• Create a variety of reports, such as tabular, cross-tabular andmaster/detail reports.

• Produce mailing labels, form letters, and envelopes.

• Enhance your reports with typeset-quality fonts and graphics.

• Produce graphs and charts that will help you present data and trends invisual terms.

The next two parts of the User's Guide describe the advanced features anduses of SQR. You will learn how to:

• Create HTML output and publish your reports on the Internet.

• Create reports that can be easily ported between different systems anddatabases and that support different printer and display types.

• Create reports that format dates, numbers, and money according tolocal preferences.

• Integrate SQR with other software packages, such as front-end userinterface tools and spreadsheets.

• Extend SQR with procedures and functions written in C.

• Test and debug your programs.

• Tune your programs for optimum performance.

The tips and techniques you find here will help you take advantage ofSQR's advanced capabilities. Many of these techniques will save you timein developing reports for your organization.

Page 10: SQR User's Guide

Introduction SQR 4.0

x SQR User's Guide

The code examples also demonstrate good SQR programming style. Werecommend that you adopt this standard style because it will make yourcode easier for other SQR programmers to read.

The program examples in this guide can be run without modificationagainst the Oracle, SYBASE, Informix, Ingres, and SQLBase databases. Theexamples may also be run against other databases with minormodifications. If your database is not named here, consult the SQRLanguage Reference or MITI® Technical Support for additional information.

Audience

This guide was written for programmers developing reports for relationaldatabases. To use it effectively, you need a working knowledge of SQLand experience in writing software programs. You also need to be familiarwith your particular database and operating system. This guide focuses onSQR Server as a method for running reports.

How to Use the SQR User's Guide

If this is your first time using SQR, the first three parts (through Chapter15) will give you everything that you need to get started. The rest of theUser's Guide discusses advanced features and more technical issues.

You can use this book by simply reading it and the code examples.However, we encourage you to try these programs for yourself and toexperiment with them. Try making some changes to our examples and seehow they run.

To try the sample programs, you must first install SQR. If you have notalready installed SQR on your system, see the installation instructionsprovided with SQR Server.

If you installed all of the program components, you will find the sampleprograms in the TUTORIAL directory. If you did not include the User'sGuide files in the original installation, you may wish to rerun theinstallation program to install just these files.

You can run the User's Guide programs on any hardware platform, but werecommend the Windows platform because it supports the SQR Viewerand online language reference.

Page 11: SQR User's Guide

SQR 4.0 Introduction

SQR User's Guide xi

¾¾ Note You can set up the sample database and run the sample programs withany user name and password. We recommend, however, that you use anaccount that does not hold important data.

This guide describes the features for SQR Version 4, and the code examplesrequire SQR Version 4.0 or higher.

Related Documents

In addition to this User's Guide, the SQR® product includes the followingdocumentation:

• SQR Language Reference contains a complete reference to SQRcommands, arguments, and command-line flags.

• SQR Workbench for Windows User's Guide explains how to use SQRWorkbench for Windows to quickly create SQR reports.

• SQR Server Installation Guide contains installation instructions andconfiguration information specific to your platform.

• SQR Workbench for Windows Installation Guide contains installationinstructions and configuration information specific to your platform.

• SQR Server Release Notes describes enhancements and new features.

• SQR Workbench for Windows Release Notes describes enhancements andnew features.

Page 12: SQR User's Guide

Introduction SQR 4.0

xii SQR User's Guide

Syntax Conventions

Syntax and code examples use the following conventions:

Symbol Description{ } Braces enclose required items.

[ ] Square brackets enclose optional items.

... An ellipsis shows that the preceding parametercan be repeated.

| A vertical bar separates alternatives withinbrackets, braces, or parentheses.

' A single quote starts and ends a literal textconstant or any argument that has more than oneword.

, A comma separates multiple arguments.

( ) Parentheses must enclose an argument orelement.

BOLD UPPERCASE SQR commands and arguments are specified inbold uppercase.

Italic Information and values that you must supply arespecified in italics.

Table 1. Syntax Conventions

Setting up the Sample Database

To run the sample programs in this guide, you will need to create a sampledatabase. To do so, run the program loadall.sqr.

Change to the SAMPLE directory. On the command line, enter:

sqr loadall username / password

In Windows, you can run loadall.sqr by double-clicking on the Loadall icon.If your system does not display this icon, you will find loadall.sqr in theSAMPLEW directory.

Page 13: SQR User's Guide

SQR 4.0 Introduction

SQR User's Guide xiii

If an individual table already exists, you will be prompted to:

A—Abort the load.

S—Skip the specified table.

R—Reload the specified table.

C—Reload all tables.

You can also run this as a batch program by the preferred option (A, S, R,or C) on the command-line. For example:

sqr loadall username/password a

If You Need Help

Help is available for your SQR software in the form of documentation andTechnical Support.

If you cannot resolve your problem using the manuals and online help,you can contact Technical Support at MITI. Call (800) 437-1663 fromwithin North America or (310) 426-6610 from outside of North Americabetween the hours of 6 AM and 5:30 PM Pacific Time. You may also send anInternet message to [email protected].

Page 14: SQR User's Guide
Page 15: SQR User's Guide

SQR User's Guide 1

1 A Simple SQR Program

In this chapter, you will learn three SQR commands: BEGIN-PROGRAM,END-PROGRAM, and PRINT. You will also learn how to create and runan SQR program.

The first sample program is the simplest SQR program. It prints a textstring.

Program ex1a.sqr

begin-program print 'Hello, World.' (1,1)end-program

ØØ Note For your convenience, all of the program examples and their output filesare included with the installation.

Creating and Running an SQR Program

Open a text editor and enter the code printed above exactly as shown.

The next step is to save your code. SQR programs are normally given a fileextension of .sqr. Save this program with the name ex1a.sqr.

Run the program. Use the command appropriate to your operating systemto change to the directory where you saved the program. Then enter theSQR command at the system command prompt. Include the SQR programname and connectivity string, all on one line. If your connectivity consistsof a user name and password, separate them with a slash (/), as follows:

sqr ex1a username / password

Page 16: SQR User's Guide

A Simple SQR Program SQR 4.0

2 SQR User's Guide

SQR Output

SQR normally creates the output file in the directory from which you runthe program. The output file will have the same file name as the SQR filethat created it, but a different extension.

If you are using SQR Workbench for Windows, the output will appear assoon as your program has finished running. The output file will be in SQRPortable Format, with an .SPF extension. You will learn more about SQRPortable Format in later chapters.

In UNIX, the program will run and produce the output in a file with an.LIS extension. Use the appropriate command to view or print the .LIS file.

No matter what platform you are using, the output will look like this:

Output for ex1a.sqr

Hello, World.

You may also see a character such as ^L, or <FF> at the end of this outputfile. It is the form feed character that ejects the last page. In this guide, wedo not show the form-feed characters.

Take another look at sample program ex1a.sqr. This program consists ofthree lines of code, starting with BEGIN-PROGRAM and ending withEND-PROGRAM. These two commands and the code between themmake up the PROGRAM section, which is used to control the order ofprocessing. The PROGRAM section is required, and you may have onlyone. It is typically placed at or near the top of the program.

The PROGRAM section contains a PRINT command, which in this caseprints the text "Hello, World." This text is enclosed in single quotationmarks ('), which are used in SQR to distinguish literal text from otherprogram elements.

The last element of the PRINT command gives the position on the outputpage. An output page can be thought of as a grid of lines and columns.The "(1,1)" indicates line one, column one, which is the top left corner of thepage.

Page 17: SQR User's Guide

SQR 4.0 A Simple SQR Program

SQR User's Guide 3

ØØ Note In SQR, you must place each command on a new line. You may indentSQR commands.

Summary• The PROGRAM section is where execution of the program begins.

• The PRINT command can be used to print a text string.

• Print position can be expressed by a pair of numbers enclosed inparentheses.

• Enter each command on a new line.

The next chapter explains how to extend your program by printing a titleon the top of the page and a page number on the bottom of the page.

Page 18: SQR User's Guide
Page 19: SQR User's Guide

SQR User's Guide 5

2 Headings and Footings

This chapter explains how to create page headings and footings. You willlearn to use the BEGIN-HEADING and BEGIN-FOOTING commands.

Typically, every page of a report has some information about the reportitself, such as the title, the date, and the page number. In SQR, the pagecan be divided into three logical areas. The top area of the page is theheading. This is where we normally print the report title and the date. Thebottom area of the page is the footing. Here we normally print the pagenumber. The middle part of the page is called the body. This is where weprint the report data.

The following diagram shows the structure of a page with heading, body,and footing:

Heading

Body

Footing

1234123456789

1011

12345

Headinglines

Body lines

Footinglines

The diagram also shows that the heading, body, and footing each haveindependent line numbers. You can print in each of these page areas usingline numbers that are relative to the top corner of that area without beingconcerned about the size of the other areas. In other words, you can printto the first line of the body using line number 1, independent of the size ofthe heading.

The program you wrote in the last chapter can be expanded by adding apage heading and footing. Here is the code:

Page 20: SQR User's Guide

Headings and Footings SQR 4.0

6 SQR User's Guide

Program ex2a.sqr

begin-program print 'Hello, World.' (1,1)end-program

begin-heading 1 print 'Tutorial Report' (1) centerend-heading

begin-footing 1 ! print "Page n of m" in the footing page-number (1,1) 'Page ' last-page () ' of 'end-footing

Output for ex2a.sqr

Tutorial ReportHello, World.

Page 1 of 1

The page heading is defined in the HEADING section. The section startswith BEGIN-HEADING and ends with END-HEADING. TheBEGIN-HEADING command is followed by a number, which is thenumber of lines reserved for the heading. In our example, the heading willtake exactly one line and will consist of the text "Tutorial Report." TheCENTER argument ensures that the text is centered on the line.

The page footing is defined in the FOOTING section, which starts withBEGIN-FOOTING and ends with END-FOOTING. The commandBEGIN-FOOTING is followed by the number 1, which means that thefooting will take one line. This line will consist of the text "Page 1 of 1."

Note that any space reserved for the heading and footing is taken awayfrom the body. With one line each in the heading and footing, themaximum possible size of the body of our report is reduced by two lines.Note also that line 1 of the body is actually the first line after the heading.

Page 21: SQR User's Guide

SQR 4.0 Headings and Footings

SQR User's Guide 7

The first line in the FOOTING section is a comment. Comments arepreceded by an exclamation mark, and they extend from the exclamationmark to the end of the line. If you want to print an exclamation mark, youmust type it twice to tell SQR not to take it as the beginning of a comment.For example:

print 'Hello, World!!' (1,1)

The PAGE-NUMBER command prints the text "Page " and the currentpage number. The LAST-PAGE command prints the number of the lastpage, preceded by the word "of," which is bracketed by spaces. In ourexample, SQR prints "Page 1 of 1" because there is only one page.

Note the parentheses in the PRINT, PAGE-NUMBER, and LAST-PAGEcommands. Numbers in these parentheses give the position for printing.A position in SQR is expressed as three numbers in parentheses—(line,column,width)—where line is the line number, column is the column(character position) and width is the width of the text.

In many cases, a position consists only of the line and column numbers.The width is normally omitted because it defaults to the width of the textbeing printed. If you also omit the line and column numbers, the printposition defaults to the current position, the position following the lastitem printed. In the example, the LAST-PAGE command has the position"()" so the current position here is the position following the page number.

Print position is a point within the area of the page, or more precisely,within the heading, body, or footing. The position (1,1) in the heading isnot the same as the position (1,1) in the body. Line 1 of the body is the firstline below the heading. In the program, the heading has only one line, soline 1 of the body is actually the second line of the page. Similarly, line 1 ofthe footing is at the bottom of the page. It is the first line following thebody.

What is the order of execution? The PRINT command actually places textin memory, not on paper. SQR always prepares a page in memory beforeprinting it to paper, performing the body first, then the HEADING andFOOTING sections. In this case, "Hello, World" is executed first, then"Tutorial Report" and "Page 1 of 1."

Page 22: SQR User's Guide

Headings and Footings SQR 4.0

8 SQR User's Guide

Summary• An SQR program can have HEADING and FOOTING sections which

create the heading and footing of a report page.

• The CENTER option of the PRINT command centers text on a line.

• Exclamation marks are used to precede comments.

• Page numbers can be printed in a "Page n of m" format with thePAGE-NUMBER and LAST-PAGE commands.

• Print positions are expressed by numbers enclosed in parentheses.

The next chapter explains how to write a program that retrieves data fromthe database and prints it in a report.

Page 23: SQR User's Guide

SQR User's Guide 9

3 Selecting Data from the Database

This chapter describes how to write a program that lists data from thedatabase and prints it in columns. You will learn the BEGIN-SELECTcommand, which is the principal means of retrieving data from thedatabase and printing it in a report.

Because the BEGIN-SELECT command is used in a procedure, you willalso learn how to use procedures.

Here is the code. An explanation of it follows.

Program ex3a.sqr

begin-program do list_customersend-program

begin-heading 4 print 'Customer Listing' (1) center print 'Name' (3,1) print 'City' (,32) print 'State' (,49) print 'Phone' (,55)end-heading

begin-footing 1 ! Print "Page n of m" in the footing page-number (1,1) 'Page ' last-page () ' of 'end-footing

begin-procedure list_customersbegin-selectname (,1)city (,32)state (,49)phone (,55) position (+1) ! Advance to the next linefrom customersend-selectend-procedure ! list_customers

Page 24: SQR User's Guide

Selecting Data from the Database SQR 4.0

10 SQR User's Guide

Output for ex3a.sqr

Customer Listing

Name City State Phone

Gregory Stonehaven Everretsville OH 2165553109Alfred E Newman & Company New York NY 2125552311Eliot Richards Queens NY 2125554285Isaiah J Schwartz and Company Zanesville OH 5185559813Harold Alexander Fink Davenport IN 3015553645Harriet Bailey Mamaroneck NY 9145550144Clair Butterfield Teaneck NJ 2015559901Quentin Fields Cleveland OH 2165553341Jerry's Junkyard Specialties Frogline NH 6125552877Kate's Out of Date Dress Shop New York NY 2125559000Sam Johnson Bell Harbor MI 3135556732Joe Smith and Company Big Falls NM 8085552124Corks and Bottles, Inc. New York NY 2125550021Harry's Landmark Diner Miningville IN 3175550948

Page 1 of 1

The PROGRAM section consists of a single DO command, which invokesthe procedure list_customers.

In SQR, a procedure is a group of commands that are performed one afterthe other, like a procedure (or subroutine) in other programminglanguages. A procedure is invoked with a DO command.

We recommend that you break your program logic into procedures andkeep the PROGRAM section small. It should normally consist of a few DOcommands for the main components of your report.

The HEADING section (shown again below) creates headings for thereport columns. Four lines are reserved for the heading.

begin-heading 4 print 'Customer Listing' (1) center print 'Name' (3,1) print 'City' (,32) print 'State' (,49) print 'Phone' (,55)end-heading

Page 25: SQR User's Guide

SQR 4.0 Selecting Data from the Database

SQR User's Guide 11

The title "Customer Listing" is printed on line 1. Line 2 is left blank. Thefirst column heading, "Name," is positioned at line 3 of the heading,character position 1. The rest of the column-heading commands omit theline numbers in their positions and default to the current line. Line 4 of theheading is left blank.

The SQR SELECT Statement

Look again at the list_customers procedure, which starts withBEGIN-PROCEDURE and ends with END-PROCEDURE. Note thecomment following the END-PROCEDURE command. It tells you whichprocedure is being ended, which is helpful when you have a program withmany procedures. (You can also omit the exclamation point:END-PROCEDURE main.)

The procedure itself contains a SELECT paragraph, which starts withBEGIN-SELECT and ends with END-SELECT.

The SELECT paragraph is unique. It combines a SQL SELECT statementwith SQR processing in a seamless way. The actual SQL statement is:

SELECT NAME, CITY, STATE, PHONEFROM CUSTOMERS

Syntax of the SELECT Statement

In an SQR SELECT paragraph, the word SELECT is omitted, and there areno commas between the column names. Instead, each column is on itsown line. You can also place SQR commands between the column names,and these commands will be executed for every record that the SELECTfetches.

ØØ Note You must name each individual column in a table—the SELECT * FROMstatement is not allowed in SQR.

Page 26: SQR User's Guide

Selecting Data from the Database SQR 4.0

12 SQR User's Guide

SQR distinguishes column names from SQR commands in a SELECTparagraph by their indentation. Column names must be placed at thebeginning of a line. SQR commands must be indented at least one space—in the example below, the POSITION command is indented to prevent itfrom being taken as a column name. The word FROM must be the firstword in a line. The rest of the SQR SELECT statement is then writtenfreely, following SQL syntax.

You can think of the SELECT paragraph as a loop. The SQR commands,including printing of columns, are executed in a loop, once for each recordthat is returned by the SELECT. The loop ends after the last record isreturned.

Positioning Data

In SELECT statement (repeated below), you see positioning after eachcolumn name. This positioning implies a PRINT command for thatcolumn. As before, omitting the line number in the position lets it defaultto the current line.

begin-selectname (,1)city (,32)state (,49)phone (,55) position (+1) ! Advance to the next linefrom customersend-select

The implied PRINT command is a special SQR feature designed to saveyou coding time. It only works inside a SELECT paragraph.

After the last column, there is a POSITION command: POSITION(+1) .The plus sign (or minus sign) indicates relative positioning in SQR. A plussign moves the print position forward from the current position, and aminus sign moves it back. The "+1" in our program means one line downfrom the current line. This command will advance the current printposition to the next line.

When you indicate print positions using plus or minus signs, be sure yournumbers don't specify a position outside the page boundaries.

Page 27: SQR User's Guide

SQR 4.0 Selecting Data from the Database

SQR User's Guide 13

Summary• The DO command is used to invoke a procedure.

• A procedure begins with BEGIN-PROCEDURE and ends withEND-PROCEDURE.

• A SELECT paragraph begins with BEGIN-SELECT and ends withEND-SELECT.

• SQR commands in a SELECT paragraph must be indented at least onespace to prevent them from being taken for column names.

• In a SELECT statement, you can print a column by entering it at thebeginning of a line with a position qualifier. This is called an impliedPRINT command.

• The POSITION command is used to give a position.

The next chapter describes a special kind of SQR variable called a columnvariable. These variables hold the results from a SELECT paragraph.

Page 28: SQR User's Guide
Page 29: SQR User's Guide

SQR User's Guide 15

4 Column Variables

This chapter explains how to name database columns with variables andhow to use their values in conditions and commands.

When you select columns from the database in a SELECT paragraph, youcan immediately print them using a position. For example:

begin-selectphone (,1) position (+1)from customersend-select

But what if you want to use the value of phone for another purpose, forexample, in a condition? The following example shows you how to do this.

begin-program do list_customersend-program

begin-procedure list_customersbegin-selectphone if &phone = '' print 'No phone' (,1) else print &phone (,1) end-if position (+1)from customersend-selectend-procedure ! list_customers

The phone column is considered an SQR column variable. Column variablesare preceded with an ampersand (&).

Unlike other program variables, column variables are read-only. You canuse their existing value, but you cannot assign a new value to a columnvariable.

Page 30: SQR User's Guide

Column Variables SQR 4.0

16 SQR User's Guide

In the sample program, &phone is a column variable that you can use inSQR commands as if it were a string, date, or numeric variable, dependingon its contents. In the condition, &phone is compared to ' ', an empty string.If &phone is an empty string, the program prints "No phone" instead.

Note that the column variable &phone inherited its name from the phonecolumn. This is the default, but you can change it, as the followingexample demonstrates.

begin-selectphone &cust_phone if &cust_phone = '' print 'No phone' (,1) else print &cust_phone (,1)end-if position (+1)from customersend-select

Why would you want to change the name of the column variable? Onereason is that you may want to use a selected column in an expression thathas no name. For example:

begin-selectcount(name) &cust_cnt (,1) if &cust_cnt < 100 print 'Less than 100 customers' end-if position (+1)from customersgroup by city, stateend-select

In this example, the expression count(name) is selected. In the program,you store this expression in the column variable &cust_cnt and refer to itafterwards by that name.

Page 31: SQR User's Guide

SQR 4.0 Column Variables

SQR User's Guide 17

Summary• In SQR, we can refer to database columns as variables. Column

variables are preceded with an ampersand (&).

• Column variables can be used in commands and conditions. We canrename column variables to receive the value of expressions.

The next chapter introduces the concept of a report break. It will alsoexplain how to print database records across multiple lines in a report.

Page 32: SQR User's Guide
Page 33: SQR User's Guide

SQR User's Guide 19

5 Break Logic

This chapter describes techniques for using break logic in your SQRprograms. It also presents some additional techniques to enhance theappearance of reports that use break logic.

A break is a change in the value of a column or variable. Records with thesame value—for example, records with the same value for state—logicallybelong to a group. When a break occurs, a new group begins.

There are a number of reasons to use break logic in a report. It allows youto:

• Add white space to your reports

• Avoid printing redundant data

• Perform conditional processing on variables that change

• Print subtotals

For example, you may want to prepare a sales report with records groupedby product, region, or salesperson (or all three). Break logic will allow youto do all that and more—you can print column headings, count records,subtotal a column, and perform additional processing on the count orsubtotal.

To see how a break works, you can write a program similar to the one inthe Chapter 3 and then add break logic to it. The break logic will make thegrouping more apparent.

Here is the program without break logic:

Program ex5a.sqr

begin-program do list_customersend-program

Program continues on the following page.

Page 34: SQR User's Guide

Break Logic SQR 4.0

20 SQR User's Guide

Program ex5a.sqr (continued)

begin-heading 2 print 'State' (1,1) print 'City' (1,7) print 'Name' (1,24) print 'Phone' (1,55)end-heading

begin-procedure list_customersbegin-selectstate (,1)city (,7)name (,24)phone (,55) position (+1) ! Advance to the next linefrom customersorder by state, city, nameend-selectend-procedure ! list_customers

Output for ex5a.sqr

State City Name Phone

IN Davenport Harold Alexander Fink 3015553645IN Miningville Harry's Landmark Diner 3175550948MI Bell Harbor Sam Johnson 3135556732NH Frogline Jerry's Junkyard Specialties 6125552877NJ Teaneck Clair Butterfield 2015559901NM Big Falls Joe Smith and Company 8085552124NY Mamaroneck Harriet Bailey 9145550144NY New York Alfred E Newman & Company 2125552311NY New York Corks and Bottles, Inc. 2125550021NY New York Kate's Out of Date Dress Shop 2125559000NY Queens Eliot Richards 2125554285OH Cleveland Quentin Fields 2165553341OH Everretsville Gregory Stonehaven 2165553109OH Zanesville Isaiah J Schwartz and Company 5185559813

When the output is sorted by state, city, and name (note the ORDER BYclause in the BEGIN-SELECT), the records are grouped by state. To makethe grouping more apparent, you can add a break.

Page 35: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 21

Using ON-BREAK

In the program below, the ON-BREAK option of the PRINT commandaccomplishes two related tasks—it starts a new group each time the valueof state changes, and prints state only when its value changes. Note thatON-BREAK works as well for implicit as for explicit PRINT commands,such as in the example below, where state, city, name, and phone areimplicitly printed as part of the SELECT paragraph.

The program below is identical to ex5a.sqr with the exception of the linethat prints the state column. This line is shown in bold.

Program ex5b.sqr

begin-program do list_customersend-program

begin-heading 2 print 'State' (1,1) print 'City' (1,7) print 'Name' (1,24) print 'Phone' (1,55)end-headingbegin-procedure list_customersbegin-selectstate (,1) on-breakcity (,7)name (,24)phone (,55) position (+1) ! Advance to the next linefrom customersorder by state, city, nameend-selectend-procedure ! list_customers

The output is shown on the following page.

Page 36: SQR User's Guide

Break Logic SQR 4.0

22 SQR User's Guide

Output for ex5b.sqr

State City Name Phone

IN Davenport Harold Alexander Fink 3015553645 Miningville Harry's Landmark Diner 3175550948MI Bell Harbor Sam Johnson 3135556732NH Frogline Jerry's Junkyard Specialties 6125552877NJ Teaneck Clair Butterfield 2015559901NM Big Falls Joe Smith and Company 8085552124NY Mamaroneck Harriet Bailey 9145550144 New York Alfred E Newman & Company 2125552311 New York Corks and Bottles, Inc. 2125550021 New York Kate's Out of Date Dress Shop 2125559000 Queens Eliot Richards 2125554285OH Cleveland Quentin Fields 2165553341 Everretsville Gregory Stonehaven 2165553109 Zanesville Isaiah J Schwartz and Company 5185559813

With break processing, the state abbreviation is printed only once for eachgroup.

Skipping Lines Between Groups

You can further enhance the visual effect of break processing by insertingone or more lines between groups. To do so, use the SKIPLINES qualifierwith ON-BREAK. Here is the list_customers procedure from ex5b.sqr, withthe modified line shown in bold:

begin-selectstate (,1) on-break skiplines=1city (,7)name (,24)phone (,55) position (+1) ! Advance to the next linefrom customersorder by state, city, nameend-select

The output is shown below.

Page 37: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 23

State City Name Phone

IN Davenport Harold Alexander Fink 3015553645Miningville Harry's Landmark Diner 3175550948

MI Bell Harbor Sam Johnson 3135556732

NH Frogline Jerry's Junkyard Specialties 6125552877

NJ Teaneck Clair Butterfield 2015559901

NM Big Falls Joe Smith and Company 8085552124

NY Mamaroneck Harriet Bailey 9145550144New York Alfred E Newman & Company 2125552311New York Corks and Bottles, Inc. 2125550021New York Kate's Out of Date Dress Shop 2125559000Queens Eliot Richards 2125554285

OH Cleveland Quentin Fields 2165553341Everretsville Gregory Stonehaven 2165553109Zanesville Isaiah J Schwartz and Company 5185559813

Arranging Multiple Break Columns

As you can see in the previous example, you can also have multiplecustomers within a city. You can apply the same break concept to the citycolumn to make this grouping of customers more apparent. Add anotherON-BREAK to the program so that city will also be printed only when itsvalue changes.

When you have multiple breaks, you must arrange them in a hierarchy. Inthe sample program, the breaks concern geographical units, so it is logicalto arrange them according to size—first state, then city. This sort ofarrangement is called nesting, and the breaks are said to be nested.

To ensure that the breaks are properly nested, use the LEVEL keyword.This argument numbers breaks by level and specifies that the columns areprinted in order of increasing break levels, from left to right. Number yourbreaks in the same order in which they are sorted in the ORDER BY clause.For more information on LEVEL, see "Understanding the Order of Events,"on page 32.

The LEVEL qualifier allows you to control the order in which you callbreak procedures. You will learn more about this technique in the section"Setting Break Procedures with BEFORE and AFTER," on page 31.

Page 38: SQR User's Guide

Break Logic SQR 4.0

24 SQR User's Guide

The next example is identical to ex5a.sqr with the exception of the two linesthat print the state and city columns. These two lines are shown in bold.

Program ex5c.sqr

begin-program do list_customersend-program

begin-heading 2 print 'State' (1,1) print 'City' (1,7) print 'Name' (1,24) print 'Phone' (1,55)end-heading

begin-procedure list_customersbegin-selectstate (,1) on-break level=1city (,7) on-break level=2name (,24)phone (,55) position (+1) ! Advance to the next linefrom customersorder by state, city, nameend-selectend-procedure ! list_customers

Output for ex5c.sqr

State City Name Phone

IN Davenport Harold Alexander Fink 3015553645 Miningville Harry's Landmark Diner 3175550948MI Bell Harbor Sam Johnson 3135556732NH Frogline Jerry's Junkyard Specialties 6125552877NJ Teaneck Clair Butterfield 2015559901NM Big Falls Joe Smith and Company 8085552124NY Mamaroneck Harriet Bailey 9145550144 New York Alfred E Newman & Company 2125552311 Corks and Bottles, Inc. 2125550021 Kate's Out of Date Dress Shop 2125559000 Queens Eliot Richards 2125554285OH Cleveland Quentin Fields 2165553341 Everretsville Gregory Stonehaven 2165553109 Zanesville Isaiah J Schwartz and Company 5185559813

As you can see, there are three customers in New York, so the city namefor the second and third customers is left blank.

Page 39: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 25

Break Processing with Enhancements

When you use break logic, you may want to enhance your report bycontrolling page breaks or calculating counts and totals for theON-BREAK column. The following example illustrates these techniques.

The program selects the customer's name, address, and telephone numberfrom the database. The break processing is performed on the state column.Here is the code:

Program ex5d.sqr

begin-program do list_customersend-program

begin-heading 4 print 'Customers Listed by State' (1) center print $current-date (1,1) Edit 'DD-Mon-YYYY' print 'State' (3,1) print 'Customer Name, Address and Phone Number' (,11) print '-' (4,1,9) fill print '-' (4,11,40) fillend-heading

begin-footing 2 ! print "Page n of m" page-number (1,1) 'Page ' last-page () ' of 'end-footing

begin-procedure state_tot print ' Total Customers for State: ' (+1,1) print #state_total () edit 999,999 position (+3,1) ! Leave 2 blank lines. let #cust_total = #cust_total + #state_total let #state_total = 0end-procedure ! state_tot

Program continues on the following page.

Page 40: SQR User's Guide

Break Logic SQR 4.0

26 SQR User's Guide

Program ex5d.sqr (continued)

begin-procedure list_customerslet #state_total = 0let #cust_total = 0begin-select! The 'state' field will only be printed when it! changes. The procedure 'state_tot' will also be! executed only when the value of 'state' changes.state (,1) on-break print=change/top-page after=state_totname (,11)addr1 (+1,11) ! continue on second lineaddr2 (+1,11) ! continue on third linecity (+1,11) ! continue on fourth linephone (,+2) edit (xxx)bxxx-xxxx ! Edit for easy reading. ! Skip 1 line between listings. ! Since each listing takes 4 lines, we specify 'need=4' to ! prevent a customer's data from being broken across two pages. next-listing skiplines=1 need=4 let #state_total = #state_total + 1from customersorder by state, nameend-selectif #cust_total > 0 print ' Total Customers: ' (+3,1) print #cust_total () edit 999,999 ! Total customers printed.else print 'No customers.' (1,1)end-ifend-procedure ! list_customers

The output is shown on the following pages.

Page 41: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 27

Output for ex5d.sqr

29-Apr-1996 Customers Listed by State

State Customer Name, Address and Phone Number--------- ----------------------------------------IN Harold Alexander Fink 32077 Cedar Street West End Davenport (301) 555-3645

Harry's Landmark Diner 17043 Silverfish Road South Park Miningville (317) 555-0948

Total Customers for State: 2

MI Sam Johnson 37 Cleaver Street Sandy Acres Bell Harbor (313) 555-6732

Total Customers for State: 1

NH Jerry's Junkyard Specialties Crazy Lakes Cottages Rural Delivery #27 Frogline (612) 555-2877

Total Customers for State: 1

NJ Clair Butterfield 371 Youngstown Blvd Quit Woods Teaneck (201) 555-9901

Total Customers for State: 1

NM Joe Smith and Company 1711 Sunset Blvd East River Big Falls (808) 555-2124

Total Customers for State: 1

NY Alfred E Newman & Company 2837 East Third Street Greenwich Village New York (212) 555-2311

Page 1 of 2

Page 42: SQR User's Guide

Break Logic SQR 4.0

28 SQR User's Guide

29-Apr-1996 Customers Listed by State

State Customer Name, Address and Phone Number--------- ----------------------------------------NY Corks and Bottles, Inc. 167 East Blvd. Jamaica New York (212) 555-0021

Eliot Richards 2134 Partridge Ave Jamaica Queens (212) 555-4285

Harriet Bailey 47 Season Street Bellevue Park Mamaroneck (914) 555-0144

Kate's Out of Date Dress Shop 2100 Park Ave East Side City New York (212) 555-9000

Total Customers for State: 5

OH Gregory Stonehaven Middlebrook Road Grey Quarter Everretsville (216) 555-3109

Isaiah J Schwartz and Company 37211 Columbia Blvd Sweet Acres Zanesville (518) 555-9813

Quentin Fields 37021 Cedar Road Beachwood Cleveland (216) 555-3341

Total Customers for State: 3

Total Customers: 14

Page 2 of 2

Page 43: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 29

Take a close look at the code. The data is printed using a SELECTparagraph in the list_customers procedure. The state and the customername are printed on the first line. The customer's address and phonenumber are printed on the next three lines.

The program also uses the argument AFTER=STATE_TOT. Thisargument calls the state_tot procedure after each change in the value ofstate. The order of processing is explained in the section "Setting BreakProcedures with BEFORE and AFTER," on page 31.

Handling Page Breaks

If a page break occurs within a group, you may want to reprint headingsand the value of the break column at the top of the new page.

To control the printing of the value, use PRINT=CHANGE/TOP-PAGE.With this qualifier, the value of the ON-BREAK column will be printedwhen it changes and after every page break. In this example, the value ofstate will be printed not only when it changes, but whenever the reportstarts a new page.

To format records, use the NEXT-LISTING command. This commandserves two purposes. The SKIPLINES=1 argument skips one line betweenrecords, then renumbers the current line as line 1. The NEED=4 argumentprevents a listing from being split over two pages by specifying theminimum number of lines needed to write a new listing on the currentpage. In this case, if there are fewer than four lines left on a page, SQR willstart a new page.

Printing the Date

In the HEADING section, the reserved variable $current-date is used toprint the date and the time. This variable is initialized with the date andtime of the client machine at the start of program execution. SQR providespredefined, or reserved, variables for a variety of uses. For a completelisting of reserved variables, see the SQR Language Reference.

In this example, the complete command is PRINT $current-date (1,1) EDIT'DD/MM/YYYY'. It prints the date and time at position 1,1 of the heading.The EDIT argument specifies an edit mask, or format, for printing the date.SQR provides a large variety of edit masks for use in formatting numbers,dates, and strings. They are fully described in the SQR Language Reference.

Page 44: SQR User's Guide

Break Logic SQR 4.0

30 SQR User's Guide

Note that the PRINT command for the report title precedes the commandfor the $current-date reserved variable, even though the date is on the leftand the title is on the right. SQR always assembles a page in memorybefore printing, so the order of these commands doesn't matter as long asyou use the correct print position qualifiers.

The last two commands in the HEADING section print a string of hyphensunder the column headings. Note the use of the FILL option of the PRINTcommand. It tells SQR to fill the specified width with this pattern. It's agood way to print a line.

In the FOOTING section, we print the "Page n of m" as we did in earlierexamples.

Obtaining Totals

The program ex5d.sqr also prints two totals—a subtotal of customers ineach state and a grand total of all customers. These calculations areperformed with two numeric variables, one for the subtotals and one forthe grand totals. Their names are #state_total and #cust_total, respectively.

SQR has a small set of variable types. The most common types arenumeric variables and the string variables. All numeric variables in SQRare preceded with a pound sign (#) and all string variables are precededwith a dollar sign ($). An additional SQR variable type is the date variable(see Chapter 20).

In SQR, numeric and string variables are not explicitly declared. Instead,they are implicitly defined by their first use. All numeric variables startout as zero and all string variables start out as null, so there is normally noneed to initialize them. The string variables are of varying length and canhold long strings of characters as well as short ones. When a new value isassigned to a string variable, its length is automatically adjusted.

In the list_customers procedure, #state_total and #cust_total are set to zero atthe beginning of the procedure. This initialization is optional and is donefor clarity only. The variable #state_total is incremented by 1 for every rowselected.

When the value of state changes, the program calls the state_tot procedureand prints the value of #state_total. Note the use of the edit mask EDIT999,999, which formats the number.

Page 45: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 31

This procedure also employs the LET command. LET is the assignmentcommand in SQR, and it lets you build complex expressions. Here, LET isused to add the value of #state_total to #cust_total. At the end of theprocedure, #state_total is reset to zero.

The list_customers procedure contains an example of SQR's if-then-elselogic. The condition starts with IF followed by an expression. If theexpression evaluates to true or to a number other than zero, the subsequentcommands are executed. Otherwise, if there is an ELSE part to the IF,those commands are executed. IF commands always end with an END-IF.

In this case, the value of #cust_total is examined. If it is greater than zero,the query has returned rows of data, and the program will print the string"Total Customers: " and the value of #cust_total.

If #cust_total is equal to zero, the query has not returned any data. In thatcase, the program prints the string "No customers."

Hyphens and Underscores

You may have noticed that many SQR commands, such asBEGIN-PROGRAM and BEGIN-SELECT, use a hyphen, whereasprocedure and variable names use an underscore.

Procedure and variable names may contain either a hyphen or underscore,but we strongly recommend you use an underscore. Using underscores inprocedure and variable names will help you distinguish them from SQRcommands. It will also prevent confusion when you mix variable namesand numbers in an expression, where hyphens could be mistaken forminus signs.

Setting Break Procedures with BEFORE and AFTER

When you print variables with ON-BREAK, you can automatically callprocedures before and after each break in a column. The BEFORE andAFTER qualifiers give you this capability. For example:

begin-selectstate (,1) on-break before=state_heading after=state_tot

The BEFORE qualifier automatically calls the state_heading procedure toprint headings before each group of records of the same state. Similarly,the AFTER qualifier automatically calls the state_tot procedure to printtotals after each group of records.

Page 46: SQR User's Guide

Break Logic SQR 4.0

32 SQR User's Guide

All BEFORE procedures are automatically invoked before each break,including the first—in other words, before the SELECT is even processed.Similarly, all AFTER procedures are invoked after each break, includingthe last group—in other words, upon completion of the SELECT.

Understanding the Order of Events

You can define a hierarchy of break columns by using the LEVEL qualifierof ON-BREAK. In ex5c.sqr, for example, state was defined as LEVEL=1and city as LEVEL=2.

When a break occurs at one level, it also forces breaks on variables withhigher LEVEL qualifiers. In the sample program, a break on state alsomeans a break on city.

A break on a variable can trigger many other events. The value may beprinted, lines skipped, procedures automatically called, and the old valuesaved. It is important to know the order of events, particularly where thereare multiple ON-BREAK columns.

The following SELECT statement has breaks on three levels:

begin-selectstate (,1) on-break level=1 after=state_tot skiplines=2city (,7) on-break level=2 after=city_tot skiplines=1zip (,45) on-break level=3 after=zip_totfrom customersorder by state, city, zipend-select

The breaks are processed as follows:

1. When zip breaks, the city_tot procedure is executed.

2. When city breaks, first the zip_tot procedure is executed, then thecity_tot procedure is executed, and one line is skipped (SKIPLINES=1).Both city and zip are printed in the next record.

3. When state breaks, the zip_tot, city_tot, and state_tot procedures areprocessed in that order. One line is skipped after the city_tot procedureis executed, and two lines are skipped after the state_tot procedure isexecuted. All three columns—state, city, and zip—are printed in thenext record.

The following program (ex5e.sqr) demonstrates the order of events in breakprocessing. It has three ON-BREAK columns, each with a LEVELargument and a BEFORE and AFTER procedure. The BEFORE andAFTER procedures print strings to indicate the order of processing.

Page 47: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 33

Program ex5e.sqr

begin-setupdeclare-Layoutdefaultend-declare

end-setup

begin-program do mainend-program

begin-procedure aprint 'AFTER Procedure for state LEVEL 1' (+1,40)end-procedure

begin-procedure bprint 'AFTER Procedure city LEVEL 2' (+1,40)end-procedure

begin-procedure cprint 'AFTER Procedure zip LEVEL 3' (+1,40)end-procedure

begin-procedure aaprint 'BEFORE Procedure state LEVEL 1' (+1,40)end-procedure

begin-procedure bbprint 'BEFORE Procedure city LEVEL 2' (+1,40)end-procedure

begin-procedure ccprint 'BEFORE Procedure zip LEVEL 3' (+1,40)end-procedure

The program continues on the following page.

Page 48: SQR User's Guide

Break Logic SQR 4.0

34 SQR User's Guide

Program ex5e.sqr (continued)

begin-procedure main localbegin-select

add 1 to #countprint 'Retrieved row #' (+1,40)print #count (,+10)Edit 9999position (+1)

state (3,1) On-Break Level=1 after=a before=aacity (3,10) On-Break Level=2 after=b before=bbzip (3,25) On-Break Level=3 after=c before=cc Edit xxxxx next-listing Need=10from customersorder by state,city,zipend-selectend-procedure

begin-heading 3 print $current-date (1,1) edit 'DD-MM-YYYY' page-number (1,60) 'Page ' last-page () ' of ' print 'STATE' (3,1) print 'CITY' (3,10) print 'ZIP' (3,25) print 'Break Processing sequence' (3,40)end-heading

The output is shown on the following pages.

Page 49: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 35

Output for ex5e.sqr

02-05-1996 Page 1 of 3

STATE CITY ZIP Break Processing sequence

BEFORE Procedure state LEVEL 1IN Davenport 62130 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3 Retrieved row # 1

Retrieved row # 2 Miningville 40622 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 3MI Bell Harbor 40674 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 4NH Frogline 04821 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 5NJ Teaneck 00355 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 6NM Big Falls 87893 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Page 50: SQR User's Guide

Break Logic SQR 4.0

36 SQR User's Guide

02-05-1996 Page 2 of 3

STATE CITY ZIP Break Processing sequence

Retrieved row # 7NY Mamaroneck 10833 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 8 New York 10002 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 9 10134 AFTER Procedure zip LEVEL 3 BEFORE Procedure zip LEVEL 3

Retrieved row # 10 10204 AFTER Procedure zip LEVEL 3 BEFORE Procedure zip LEVEL 3

Retrieved row # 11 Queens 10213 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 12OH Cleveland 44121 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1 BEFORE Procedure state LEVEL 1 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Retrieved row # 13 Everretsville 40233 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

Page 51: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 37

02-05-1996 Page 3 of 3

STATE CITY ZIP Break Processing sequence

Retrieved row # 14 Zanesville 44900 AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 BEFORE Procedure city LEVEL 2 BEFORE Procedure zip LEVEL 3

AFTER Procedure zip LEVEL 3 AFTER Procedure city LEVEL 2 AFTER Procedure for state LEVEL 1

The following steps explain the order of processing in detail.

Step 1. Process BEFORE Procedures

BEFORE procedures are processed in ascending order by LEVEL beforethe first row of the query is retrieved. If no data is selected, BEFOREprocedures are not executed.

Step 2. Select First Row of Data

The first row of data is selected.

Step 3. Select Subsequent Rows of Data

Processing of the SELECT continues. When a break occurs on any column,it also triggers breaks on columns at the same or higher levels. Eventsoccur in the following order:

1. AFTER procedures are processed in descending order from the highestlevel to the level of the current ON-BREAK column.

2. SAVE variables are set with the value of the previous ON-BREAKcolumn. See "Saving a Value When a Break Occurs," below, for anexplanation of the SAVE argument.

3. BEFORE procedures are processed in ascending order from the currentlevel to the highest level.

4. If SKIPLINES was specified, the current line position is advanced.

5. The value of the new group is printed (unless PRINT=NEVER isspecified).

Page 52: SQR User's Guide

Break Logic SQR 4.0

38 SQR User's Guide

Step 4. Process AFTER Procedures

After the SELECT is complete, if any rows were selected, AFTERprocedures are processed in descending order by LEVEL.

Controlling Page Breaks with Multiple ON-BREAK Columns

Where there are multiple columns with ON-BREAK, page breaks call forcareful planning. While it may be acceptable to have a page break within agroup, you probably would not want to have one within a record.

You can prevent page breaks within a record by following four simplerules:

• Place ON-BREAK columns ahead of other columns in your SELECTstatement.

• Place the lower-level ON-BREAK columns ahead of the higher-levelON-BREAK columns in your SELECT statement.

• Use the same line positions for all ON-BREAK columns.

• Avoid using WRAP and ON-BREAK together on one column.

Saving a Value When a Break Occurs

In ex5d.sqr, the state_tot procedure prints the total number of customers perstate. Because it is called with the AFTER argument, this procedure isexecuted only after the value of the ON-BREAK column, state, haschanged.

Sometimes, however, you may wish to print the previous value of theON-BREAK column in the AFTER procedure. For example, you maywant to print the state name along with the totals for each state. Simplyprinting the value of state will not work because its value will havechanged by the time the AFTER procedure is called.

The answer is to save the previous break value in a string variable. To dothis, use the SAVE qualifier of ON-BREAK. For example:

begin-selectstate (,1) on-break after=state_tot save=$old_state

You can then print the value of $old_state in the state_tot procedure.

Page 53: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 39

Using ON-BREAK on a Hidden Column

In some reports, you may want to use the features of break processingwithout printing the ON-BREAK variable. For example, you may want toincorporate the ON-BREAK variable into a subheading. This format mightmake your report more readable. It is also useful when you want to leaveroom on the page for additional columns.

The way to create such a report is to "hide" the break variable with thePRINT=NEVER qualifier and print it in a heading procedure called byBEFORE.

The following code is based on the program ex5b.sqr. The key lines areshown in bold.

Program ex5f .sqr

begin-program do list_customersend-program

begin-procedure list_customersbegin-selectstate () on-break before=state_heading print=never level=1city (,1) on-break level=2name (,18)phone (,49) position (+1) ! Advance to the next linefrom customersorder by state, city, nameend-selectend-procedure ! list_customers

begin-procedure state_heading print 'State: ' (+1,1) bold ! Advance a line and print 'State:' print &state (,8) bold ! Print the state column here print 'City' (+1,1) bold ! Advance a line and print 'City' print 'Name' (,18) bold print 'Phone' (,49) bold print '-' (+1,1,58) fill position (+1) ! Advance to the next lineend-procedure ! state_heading

Note that this program has no HEADING section. Instead, a procedureprints column headings for each state rather than at the top of each page.

Page 54: SQR User's Guide

Break Logic SQR 4.0

40 SQR User's Guide

Note also that the &state variable can be referenced throughout theprogram, even though the state column was not printed as part of thebreak.

The most interesting line in the program is this one from the SELECTstatement:

state () on-break before=state_heading print=never level=1

This line defines the break processing for state. The BEFORE qualifierspecifies that the state_heading procedure will be called automaticallybefore each change in state. In this program, this break is set to LEVEL=1.

The PRINT=NEVER qualifier makes the state column a hidden columnand specifies that it won't be printed as part of the SELECT statement.Instead, it is printed in the state_heading procedure. In this procedure, thestate column is referred to as the column variable &state.

The city column is assigned a LEVEL=2 break.

The output is shown below.

Page 55: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 41

Output for ex5f .sqr

State: INCity Name Phone----------------------------------------------------------Davenport Harold Alexander Fink 3015553645Miningville Harry's Landmark Diner 3175550948

State: MICity Name Phone----------------------------------------------------------Bell Harbor Sam Johnson 3135556732

State: NHCity Name Phone----------------------------------------------------------Frogline Jerry's Junkyard Specialties 6125552877

State: NJCity Name Phone----------------------------------------------------------Teaneck Clair Butterfield 2015559901

State: NMCity Name Phone----------------------------------------------------------Big Falls Joe Smith and Company 8085552124

State: NYCity Name Phone----------------------------------------------------------Mamaroneck Harriet Bailey 9145550144New York Alfred E Newman & Company 2125552311 Corks and Bottles, Inc. 2125550021 Kate's Out of Date Dress Shop 2125559000Queens Eliot Richards 2125554285

State: OHCity Name Phone----------------------------------------------------------Cleveland Quentin Fields 2165553341Everretsville Gregory Stonehaven 2165553109Zanesville Isaiah J Schwartz and Company 5185559813

Restrictions and Limitations of ON-BREAK

ON-BREAK can only be set on string and date columns and string anddate variables. If you need to perform break processing on a numericcolumn, you must first move its value to a string variable and setON-BREAK on that. For example:

Page 56: SQR User's Guide

Break Logic SQR 4.0

42 SQR User's Guide

begin-selectamount_received &amount move &amount to $amount $$9,999.99 print $amount (+1,1) on-breakfrom cash_receiptsorder by amount_receivedend-select

The maximum number of ON-BREAK levels is determined by theON-BREAK setting in the [Processing-Limits] section of the SQR.INI file.The default is 30, but you may increase this setting. Its maximum value is64K-1 (65,535). For more information on SQR.INI, see the SQR LanguageReference.

Summary• PRINT ON-BREAK performs special processing when a value changes,

such as the state column in a listing of customer addresses.

• ON-BREAK SKIPLINES inserts space between groups of records.

• ON-BREAK LEVEL arranges breaks hierarchically.

• PRINT=CHANGE/TOP-PAGE prints a column after a page break orafter a change in the column's value.

• NEXT-LISTING keeps a group of lines on the same page.

• The SQR reserved variable $current-date holds the current date andtime.

• SQR provides numeric, string, and date variables. Numeric variablesare preceded with a pound sign (#) and start out as 0. String variablesare preceded with a dollar sign ($) and start out as null. There is noneed to initialize either variable type.

• LET is the SQR assignment command. It allows you to buildexpressions.

• The BEFORE and AFTER arguments set break procedures.

• The SET and LEVEL qualifiers, in conjunction with BEFORE andAFTER, determine the order of events.

• The SAVE qualifier saves the value of a previous group to a variable.

Page 57: SQR User's Guide

SQR 4.0 Break Logic

SQR User's Guide 43

• ON-BREAK can only be set on string variables and string columns. Toperform break processing on a numeric column or variable, you mustfirst move it to a string variable.

• The ON-BREAK setting in the SQR.INI file determines the maximumnumber of ON-BREAK levels in a program.

For more information on the ON-BREAK argument, see the PRINTcommand in the SQR Language Reference.

The next chapter describes the SETUP section of an SQR program.

Page 58: SQR User's Guide
Page 59: SQR User's Guide

SQR User's Guide 45

6 The SETUP Section

This chapter introduces the SQR SETUP section. This section is notrequired in a program, but it is very useful.

The SETUP section holds all the declarations. Declarations define certainreport characteristics and the source and attributes of various reportcomponents, such as charts and images. The SETUP section is evaluatedwhen your program is compiled.

The SETUP section, if present, is typically placed at the top of the programbefore the PROGRAM section. It begins with BEGIN-SETUP and endswith END-SETUP.

The following commands can be issued in the SETUP section. If used, theyare processed at compile time, before the program begins executing.

Command CommentsALTER-LOCALE Can also appear in a procedure.

ASK Allowed only in SETUP section.

BEGIN-SQL Can also appear in a procedure. Executedwhen a run-time file (.SQT) is loaded.

CREATE-ARRAY Can also appear in a procedure.

DECLARE-CHART

DECLARE-IMAGE

DECLARE-LAYOUT

DECLARE-PRINTER

DECLARE-PROCEDURE

DECLARE-REPORT

DECLARE-VARIABLE Can also appear in a local procedure.

LOAD-LOOKUP Can also appear in a procedure.

USE SYBASE only.

Table 2. Commands Available in the SETUP Section

For more information about commands used in the SETUP section, see thecommands listed in the SQR Language Reference.

Page 60: SQR User's Guide

The SETUP Section SQR 4.0

46 SQR User's Guide

Using DECLARE-LAYOUT

One common declaration used in the SETUP section is theDECLARE-LAYOUT command. This command sets the page layout andincludes such important options as the paper size and margins.

Here is a typical SETUP section:

begin-setup ! Declare the default layout for this report declare-layout default paper-size=(8.5,11) left-margin=1 right-margin=1 top-margin=1 bottom-margin=1 end-declareend-setup

In the above example, the DECLARE-LAYOUT command sets the papersize to 8 1/2 by 11 inches, with all margins at 1 inch.

In SQR, data is positioned on the page using line and character positioncoordinates. Think of the page as a grid where each cell holds onecharacter. With such a grid, in a position qualifier consisting of(line,column,width), column and width are numbers that denote charactersand spaces.

The SQR page layout is shown below:

Paper size (width)

Pap

er s

ize

(hei

ght)Li

ne h

eigh

t

Character width

Topmargin

Rightmargin

Bottommargin

Leftmargin

Page 61: SQR User's Guide

SQR 4.0 The SETUP Section

SQR User's Guide 47

The diagram shows how the main attributes of the DECLARE-LAYOUTcommand affect the structure of the page. The PAPER-SIZE argumentdefines the dimensions of the entire page, including margins. Thearguments TOP-MARGIN, LEFT-MARGIN, BOTTOM-MARGIN, andRIGHT-MARGIN define the margins. In SQR, you cannot print in themargins.

In the sample code above, the left margin will use 10 spaces and the topmargin will use 6 lines. The page width will accommodate 65 characters(without the margins) and 54 lines.

The default mapping of characters and lines to inches is 10 CPI (charactersper inch) and 6 LPI (lines per inch). This means that each character cell is1/10 inch wide and 1/6 inch high. These settings are used when aprogram does not contain a DECLARE-LAYOUT command.

You can override the default settings by using the LINE-HEIGHT andCHAR-WIDTH arguments in the DECLARE-LAYOUT command. Thesearguments will adjust the dimensions of the grid, which implies a changein the meaning of column and line. If your DECLARE-LAYOUT paragraphincludes the arguments LINE-HEIGHT=1 and CHAR-WIDTH=1, the cellsin the grid will measure 1 point by 1 point (1 point = 1/72 inch or approx.0.35 mm). In that case, column will be a dimension given in points. Thelength of a string, however, will still be given in characters.

Alternatively, you can use the MAX-LINES and MAX-COLUMNSarguments of the DECLARE-LAYOUT command to specify the number oflines on the page and the number of characters to fit across the page. SQRwill calculate the line height and character width based on these settingsand the size of the page and margins.

Coordinates are specified in terms of lines and character positions. Thefirst line from the top is 1 and the first column (from the left) is 1. There isno coordinate 0.

The DECLARE-LAYOUT command also allows you to declare the pageorientation. Note that this declaration does not affect how SQR usesposition coordinates. Line and character positions are not transposedwhen page orientation is switched. The only effect of the ORIENTATIONoption of the DECLARE-LAYOUT command is that SQR will switch theprinter to the specified orientation, portrait or landscape. The defaultmode is portrait.

Page 62: SQR User's Guide

The SETUP Section SQR 4.0

48 SQR User's Guide

Summary• The SETUP section holds declarations and several commands. Most

commands in the SETUP section are performed at compile time.

• DECLARE-LAYOUT sets the page layout and includes such importantoptions as the paper size and margins.

The next chapter explains how to create a master/detail report, whichcombines information from multiple tables.

Page 63: SQR User's Guide

SQR User's Guide 49

7 Master/Detail Reports

This chapter presents master/detail reports, which show hierarchicalinformation. The information is normally retrieved from multiple tablesthat have a one-to-many relationship, such as customers and orders. Thecustomer information is the "master" and the orders are the "detail."

In many cases, you can obtain such information with a single SQR SELECTstatement. In such a program, the data from the master table is joined withdata from the detail table. You can implement break logic as described inChapter 5, "Break Logic," to group the detail records for each masterrecord.

This type of report has one major disadvantage—if a master record has noassociated detail records, it will not be displayed. If you need to show allmaster records, whether they have detail records or not, this type of reportwill not meet your needs.

The solution is to create a master/detail report with one SELECT thatretrieves records from the master table, followed by separate SELECTstatements that retrieve the detail records associated with each masterrecord.

The code example in this chapter produces just such a report. In ourexample, one BEGIN-SELECT returns the names of customers. For eachcustomer, two additional BEGIN-SELECT commands are performed, oneto retrieve order information and another to retrieve payment information.

The following diagram depicts the BEGIN-SELECT structure in thisexample:

Customers

Orders

Payments

Page 64: SQR User's Guide

Master/Detail Reports SQR 4.0

50 SQR User's Guide

When one query returns master information and another query returnsdetail information, the detail query is nested within the master query.

In our sample program, one query returns customer names and two nestedqueries return detail information. The nested queries are invoked once foreach customer, each one retrieving records that correspond to the currentcustomer. The subqueries are correlated with a bind variable in theWHERE clause. This variable correlates the customer number (cust_num)with the current customer record. (See Chapter 16, "Dynamic SQL andError Checking," for a more detailed explanation of bind variables.)

Program ex7a.sqr

begin-program do mainend-program

begin-procedure mainbegin-select Print 'Customer Information' (,1) Print '-' (+1,1,45) Fillname (+1,1,25)city (,+1,16)state (,+1,2)cust_num do cash_receipts(&cust_num) do orders(&cust_num) position (+2,1)from customersend-selectend-procedure ! main

begin-procedure cash_receipts (#cust_num) let #any = 0begin-select if not #any print 'Cash Received' (+2,10) print '-------------' (+1,10) let #any = 1 end-ifdate_received (+1,10,20) edit 'DD-MON-YY'amount_received (,+1,13) Edit $$$$,$$0.99from cash_receipts awhere a.cust_num = #cust_numend-selectend-procedure ! cash_receipts

Program continues on the following page.

Page 65: SQR User's Guide

SQR 4.0 Master/Detail Reports

SQR User's Guide 51

Program ex7a.sqr (continued)

begin-procedure orders (#cust_num) let #any = 0begin-select if not #any print 'Orders Booked' (+2,10) print '-------------' (+1,10) let #any = 1 end-ifa.order_numorder_date (+1,10,20) Edit 'DD-MON-YY'description (,+1,20)c.price * b.quantity (,+1,13) Edit $$$$,$$0.99from orders a, ordlines b, products cwhere a.order_num = b.order_num and b.product_code = c.product_code and a.cust_num = #cust_numend-selectend-procedure ! orders

begin-heading 3 print $current-date (1,1) Edit 'DD-MON-YYYY' page-number (1,69) 'Page 'end-heading

Correlating Subqueries

The above program consists of three procedures, main, cash_receipts, andorders, which correspond to the three queries. The procedure main is themaster. It retrieves the customer names. For each customer, we invoke theprocedures cash_receipts to list the cash receipts, if there are any, and ordersto list the customer's orders, if there are any.

The procedures take the variable cust_num as an argument. This feature isdiscussed in more detail in Chapter 17, "Procedures, Argument Passing,and Local Variables." As you can see, cash_receipts and orders are calledmany times, once for each customer. Each time, the procedures performthe same query with a different value for the cust_num variable in theWHERE clause.

Note the use of the IF command and the numeric variable #any in theseprocedures. When the BEGIN-SELECT command returns no records, SQRwill not execute the following PRINT commands. Thus, the headings forthese procedures are only displayed for those customers who have recordsin the detail tables.

Page 66: SQR User's Guide

Master/Detail Reports SQR 4.0

52 SQR User's Guide

The procedure orders demonstrates the use of an expression in theBEGIN-SELECT. The expression is c.price * b.quantity.

Finally, note that the format given to the dollar amount with the argumentEDIT "$$$$,$$0.99." This format uses a "floating-to-the-right" moneysymbol. If there are fewer digits than the six that we allowed here, thedollar sign will float to the right and stay close to the number.

ØØ Note See Chapter 20, "Working with Dates," for more information on formattingdates.

Output for ex7a.sqr

26-APR-1996Page 1

Customer Information---------------------------------------------Gregory Stonehaven Everretsville OH

Cash Received ------------- 01-FEB-94 $130.00

Customer Information---------------------------------------------Alfred E Newman & Company New York NY

Cash Received ------------- 01-MAR-94 $140.00Customer Information---------------------------------------------Eliot Richards Queens NY

Cash Received ------------- 16-JAN-94 $220.12 17-JAN-94 $260.00

Orders Booked ------------- 02-MAY-94 Whirlybobs $239.19 02-MAY-94 Canisters $3,980.25

Output continues on the following page.

Page 67: SQR User's Guide

SQR 4.0 Master/Detail Reports

SQR User's Guide 53

Output for ex7a.sqr

Customer Information---------------------------------------------Isaiah J Schwartz and Com Zanesville OH

Cash Received ------------- 18-JAN-94 $190.00 02-JAN-94 $1,100.00

Orders Booked ------------- 02-MAY-94 Hop scotch kits $6,902.00 02-MAY-94 Wire rings $19,872.90

Customer Information---------------------------------------------Harold Alexander Fink Davenport IN

Cash Received ------------- 01-FEB-94 $1,200.00 01-MAR-94 $1,300.00

Orders Booked ------------- 19-MAY-94 Ginger snaps $44.28 19-MAY-94 Modeling clay $517.05

Summary• Multiple BEGIN-SELECT commands can be used to retrieve detail

information that is contained in different database tables.

• Queries that retrieve detail information are said to be nested in thequeries that retrieve master information.

• Subqueries are joined to the main query by use of bind variables.

The next chapter describes how to create cross-tabular reports andassemble data in an SQR array.

Page 68: SQR User's Guide
Page 69: SQR User's Guide

SQR User's Guide 55

8 Cross-Tabular Reports

This chapter presents cross-tabular reports, which are matrix- orspreadsheet-like reports. These reports are useful for presenting summarynumeric data. Cross-tabular reports vary in format. Look at the followingexample, which shows sales revenue summarized by product by saleschannel:

Revenue by Product by Sales Channel

Product Direct Sales Resellers Mail Order Total---------- ------------ --------- ----------- -------A $2,100 $1,209 $0 $3,309B $120 $311 $519 $950C $2 $0 $924 $926---------- ------------ --------- ----------- -------Total $2,222 $1,520 $1,443 $5,185

This report is based on many sales records. The three middle columnscorrespond to sales channel categories. Each row corresponds to a product.The records fall into nine groups: three products sold through three saleschannels. Some groups have no sales (such as mail order for Product A).

Each category may be a discrete value of some database column or a set ofvalues. For example, Resellers can be domestic resellers plus internationaldistributors.

A category may also represent a range, as demonstrated in the nextexample:

Orders by Product by Order SizeProductCategory Less than 10 10 to 100 More than 100 Total----------- ------------ --------- ------------- -------Durable 200 120 0 320Nondurable 122 311 924 1876----------- ------------ --------- ------------- -------Total 322 431 1443 2196

In this example, the rows correspond to nondiscrete categories. Productsare classified as durable and nondurable. The columns representcategories that are ranges of order size.

Page 70: SQR User's Guide

Cross-Tabular Reports SQR 4.0

56 SQR User's Guide

For each record selected, the program must determine the range to which itbelongs and add 1 to the count for that category. The numbers in the cellsare counts, but they could be sums, averages, or any other expression.

Of course, there are other types of cross-tabular reports. These reportsbecome more complex when the number of columns is not predefined andwhen there are more columns than can fit across the page.

Arrays

In a many cases, the program must process all the records before it canbegin printing the data. During the processing, the program needs to keepthe data in some buffer where it can accumulate the numbers. This can bedone in an SQR array.

An array is a unit of storage that consists of rows and columns and exists inmemory. An array is similar to a database table, but it exists only inmemory.

In the next sample program, an array called order_qty is created to hold thesum of the quantity of orders in a given month. This specific examplecould be programmed without an array, but as you will see later, using onecan be beneficial. Data retrieved once and stored in an array can bepresented in many ways without additional database queries. The datacan even be presented in a chart, as we will see later in Chapter 13,"Business Charts."

This example demonstrates an SQR feature called a "three-dimensionalarray." It has fields (columns) and rows, and it also has repeating fields(the "third dimension"). In the order_qty array, the first field is the productdescription. The second field is the order quantity of each month. Thereare three months in the example; therefore, this field occurs (repeats) threetimes.

SQR arrays are referenced in expressions as array_name.field(sub1[,sub2]).Sub1 is the first subscript, the row number. Rows are numbered startingwith zero. The second subscript (sub2) is specified when the field repeats.Repeating fields are also numbered starting with zero. The subscript canbe a literal or an SQR numeric variable.

Page 71: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 57

Program ex8a.sqr

#define max_products 100

begin-setup create-array name=order_qty size={max_products} field=product:char field=month_qty:number:3end-setup

begin-program do select_data do print_arrayend-program

begin-procedure print_array let #entry_cnt = #i let #i = 0 while #i <= #entry_cnt let $product = order_qty.product(#i) let #jan = order_qty.month_qty(#i,0) let #feb = order_qty.month_qty(#i,1) let #mar = order_qty.month_qty(#i,2) let #prod_tot = #jan + #feb + #mar print $product (,1,30) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #prod_tot (,62,9) edit 9,999,999 position (+1) let #jan_total = #jan_total + #jan let #feb_total = #feb_total + #feb let #mar_total = #mar_total + #mar let #i = #i + 1 end-while let #grand_total = #jan_total + #feb_total + #mar_total print 'Totals' (+2,1) print #jan_total (,32,9) edit 9,999,999 print #feb_total (,42,9) edit 9,999,999 print #mar_total (,52,9) edit 9,999,999 print #grand_total (,62,9) edit 9,999,999end-procedure print_array

Program continues on the following page.

Page 72: SQR User's Guide

Cross-Tabular Reports SQR 4.0

58 SQR User's Guide

Program ex8a.sqr (continued)

begin-procedure select_databegin-selectorder_date! The quantity for this orderquantity! the product for this orderdescription if #i = 0 and order_qty.product(#i) = '' let order_qty.product(#i) = &description end-if if order_qty.product(#i) != &description let #i = #i + 1 if #i >= {max_products} display 'Error: There are more than {max_products}products' stop end-if let order_qty.product(#i) = &description end-if let #j = to_number(datetostr(&order_date,'MM')) - 1 if #j < 3 let order_qty.month_qty(#i,#j) = order_qty.month_qty(#i,#j) + &quantity end-iffrom orders a, ordlines b, products cwhere a.order_num = b.order_numand b.product_code = c.product_codeorder by descriptionend-selectend-procedure ! select_data

begin-heading 4 print $current-date (1,1) print 'Order Quantity by Product by Month' (1,18) page-number (1,64) 'Page ' print 'Product' (3,1) print ' January' (,32) print ' February' (,42) print ' March' (,52) print ' Total' (,62) print '-' (4,1,70) Fillend-heading

Page 73: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 59

Creating the Array

You must define the size of an array when you create it. The programcreates the array order_qty with a size of 100.

The command #DEFINE MAX_PRODUCTS 100 defines the constantmax_products as a substitution variable. The sample program uses thisconstant to define the size of the array. It is a good practice to use#DEFINE because it displays our limit at the top of the program source.Otherwise, it would be buried in the code.

The SETUP section creates the array using the CREATE-ARRAYcommand. All SQR arrays are created before the program beginsexecuting. Their size must be known at compile time. If you do not knowexactly how many rows you will have, you must over-allocate and specifyan upper bound. In the example, the array has 100 rows, even though theprogram only uses 12 rows to process the sample data.

The above program has two procedures: select_data and print_array.Select_data performs the database query, as its name suggests. While thedatabase records are being processed, nothing is printed, and the dataaccumulates in the array. When the processing is over, the procedureprint_array does two things: It loops through the array and prints the data.It also adds up the month totals and prints them at the bottom.

The report summarizes the product order quantities for each month, whichare the records ordered by the product description. It then fills the arrayone product at a time. For each record selected, the program checks to seeif it's a new product; if it is, the array is incremented by row subscript #i.The program also adds the quantity to the corresponding entry in the arraybased on the month.

There is one complication with this program—how to obtain the month.Date manipulation can vary among databases, and to write truly portablecode calls for careful planning.

The key is the datetostr function in the following command:

let #j = to_number(datetostr(&order_date, 'MM')) - 1

This function converts the order_date column into a string. (The 'MM' editmask specifies that only the month part will be converted.) The resultingstring is then converted to a number; if it is less than 3, it representsJanuary, February, or March, and is added to the array.

Page 74: SQR User's Guide

Cross-Tabular Reports SQR 4.0

60 SQR User's Guide

Grouping by Category

The next example is a cross-tabular report that groups the products byprice range. This grouping cannot be done using a SQL GROUP BY clause.Moreover, to process the records in order of price category, the programwould have to sort the table by price. The example shows how to do itwithout sorting the data.

The program uses an SQR EVALUATE command to determine the pricecategory and assign the array subscript #i to 0, 1, or 2. Then it adds theorder quantity to the array cell that corresponds to the price category (row)and the month (column).

Output for ex8a.sqr

11-JUN-96 Order Quantity by Product by Month Page 1

Product January February March Total----------------------------------------------------------------------Canisters 3 0 0 3Curtain rods 2 8 18 28Ginger snaps 1 10 0 11Hanging plants 1 20 0 21Hookup wire 16 15 0 31Hop scotch kits 2 0 0 2Modeling clay 5 0 0 5New car 1 9 0 10Thimble 7 20 0 27Thingamajigs 17 0 120 137Widgets 4 0 12 16Wire rings 1 0 0 1

Totals 60 82 150 292

Page 75: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 61

Program ex8b.sqr

#define max_categories 3

begin-setup create-array name=order_qty size={max_categories} field=category:char field=month_qty:number:3end-setup

begin-program do select_data do print_arrayend-program

begin-procedure print_array let #i = 0 while #i < {max_categories} let $category = order_qty.category(#i) let #jan = order_qty.month_qty(#i,0) let #feb = order_qty.month_qty(#i,1) let #mar = order_qty.month_qty(#i,2) let #category_tot = #jan + #feb + #mar print $category (,1,31) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #category_tot (,62,9) edit 9,999,999 position (+1) let #jan_total = #jan_total + #jan let #feb_total = #feb_total + #feb let #mar_total = #mar_total + #mar let #i = #i + 1 end-while let #grand_total = #jan_total + #feb_total + #mar_total print 'Totals' (+2,1) print #jan_total (,32,9) edit 9,999,999 print #feb_total (,42,9) edit 9,999,999 print #mar_total (,52,9) edit 9,999,999 print #grand_total (,62,9) edit 9,999,999end-procedure print_array

begin-procedure select_data let order_qty.category(0) = '$0-$4.99' let order_qty.category(1) = '$5.00-$100.00' let order_qty.category(2) = 'Over $100'

Program continues on the following page.

Page 76: SQR User's Guide

Cross-Tabular Reports SQR 4.0

62 SQR User's Guide

Program ex8b.sqr (continued)

begin-selectorder_date! the price / price category for the orderc.price &price move &price to #price_num evaluate #price_num when < 5.0 let #i = 0 break when <= 100.0 let #i = 1 break when-other let #i = 2 break end-evaluate! The quantity for this orderquantity let #j = to_number(datetostr(&order_date,'MM')) - 1 if #j < 3 let order_qty.month_qty(#i,#j) = order_qty.month_qty(#i,#j) + &quantity end-iffrom orders a, ordlines b, products cwhere a.order_num = b.order_numand b.product_code = c.product_codeend-selectend-procedure ! select_data

begin-heading 5 print $current-date (1,1) page-number (1,64) 'Page ' print 'Order Quantity by Product Price Category by Month'(2,11) print 'Product Price Category' (4,1) print ' January' (,32) print ' February' (,42) print ' March' (,52) print ' Total' (,62) print '-' (5,1,70) Fillend-heading

The output is shown on the following page.

Page 77: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 63

Output for ex8b.sqr

11-JUN-96 Page 1 Order Quantity by Product Price Category by Month

Product Price Category January February March Total----------------------------------------------------------------------$0-$4.99 28 45 12 85$5.00-$100.00 25 28 138 191Over $100 7 9 0 16

Totals 60 82 150 292

Using Multiple Arrays

Using SQR arrays to buffer the data offers several advantages. In the lastexample, you saw how it eliminated the need to sort the data. Anotheradvantage is that you can combine the two sample reports into one. Withone pass on the data, you can fill the two arrays and then print the twoparts of the report.

The next sample program performs the work done by the first twoprograms. In the SETUP section, two arrays are created—one tosummarize monthly orders by product, and another to summarizemonthly orders by price range.

Program ex8c.sqr

#define max_categories 3#define max_products 100

begin-setup create-array name=order_qty size={max_products} field=product:char field=month_qty:number:3 create-array name=order_qty2 size={max_categories} field=category:char field=month_qty:number:3end-setup

Program continues on the following page.

Page 78: SQR User's Guide

Cross-Tabular Reports SQR 4.0

64 SQR User's Guide

Program ex8c.sqr (continued)begin-program do select_data do print_array print '-' (+2,1,70) fill position (+1) do print_array2end-program

begin-procedure print_array let #entry_cnt = #i let #i = 0 while #i <= #entry_cnt let $product = order_qty.product(#i) let #jan = order_qty.month_qty(#i,0) let #feb = order_qty.month_qty(#i,1) let #mar = order_qty.month_qty(#i,2) let #prod_tot = #jan + #feb + #mar print $product (,1,30) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #prod_tot (,62,9) edit 9,999,999 position (+1) let #i = #i + 1 end-whileend-procedure ! print_array

begin-procedure print_array2 let #i = 0 while #i < {max_categories} let $category = order_qty2.category(#i) let #jan = order_qty2.month_qty(#i,0) let #feb = order_qty2.month_qty(#i,1) let #mar = order_qty2.month_qty(#i,2) let #category_tot = #jan + #feb + #mar print $category (,1,31) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #category_tot (,62,9) edit 9,999,999 position (+1) let #jan_total = #jan_total + #jan let #feb_total = #feb_total + #feb let #mar_total = #mar_total + #mar let #i = #i + 1 end-while let #grand_total = #jan_total + #feb_total + #mar_total print 'Totals' (+2,1) print #jan_total (,32,9) edit 9,999,999 print #feb_total (,42,9) edit 9,999,999 print #mar_total (,52,9) edit 9,999,999 print #grand_total (,62,9) edit 9,999,999end-procedure ! print_array2

Program continues on the following page.

Page 79: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 65

Program ex8c.sqr (continued)

begin-procedure select_data let order_qty2.category(0)='$0-$4.99' let order_qty2.category(1)='$5.00-$100.00' let order_qty2.category(2)='Over $100'begin-selectorder_date! the price / price category for the orderc.price &price move &price to #price_num evaluate #price_num when < 5.0 let #x = 0 break when <= 100.0 let #x = 1 break when-other let #x = 2 break end-evaluate! The quantity for this orderquantity let #j = to_number(datetostr(&order_date,'MM')) - 1 if #j < 3 let order_qty2.month_qty(#x,#j) = order_qty2.month_qty(#x,#j) + &quantity end-if! the product for this orderdescription if #i = 0 and order_qty.product(#i) = '' let order_qty.product(#i) = &description end-if if order_qty.product(#i) != &description let #i = #i + 1 if #i >= {max_products} display 'Error: There are more than {max_products}products' stop end-if let order_qty.product(#i) = &description end-if if #j < 3 let order_qty.month_qty(#i,#j) = order_qty.month_qty(#i,#j) + &quantity end-iffrom orders a, ordlines b, products cwhere a.order_num = b.order_numand b.product_code = c.product_codeorder by descriptionend-selectend-procedure ! select_data

Program continues on the following page.

Page 80: SQR User's Guide

Cross-Tabular Reports SQR 4.0

66 SQR User's Guide

Program ex8c.sqr (continued)

begin-heading 5print $current-date (1,1) page-number (1,64) 'Page ' print 'Order Quantity by Product and Price Category by Month'(2,10) print 'Product / Price Category' (4,1) print ' January' (,32) print ' February' (,42) print ' March' (,52) print ' Total' (,62) print '-' (5,1,70) Fillend-heading

Output for ex8c.sqr

11-JUN-96 Page 1 Order Quantity by Product and Price Category by Month

Product / Price Category January February March Total----------------------------------------------------------------------Canisters 3 0 0 3Curtain rods 2 8 18 28Ginger snaps 1 10 0 11Hanging plants 1 20 0 21Hookup wire 16 15 0 31Hop scotch kits 2 0 0 2Modeling clay 5 0 0 5New car 1 9 0 10Thimble 7 20 0 27Thingamajigs 17 0 120 137Widgets 4 0 12 16Wire rings 1 0 0 1

----------------------------------------------------------------------$0-$4.99 28 45 12 85$5.00-$100.00 25 28 138 191Over $100 7 9 0 16

Totals 60 82 150 292

SQR arrays are also advantageous in programs that produce charts. Withthe data for the chart already in the array, presenting the above cross-tab asa bar chart is easy. For more information on charts, see Chapter 13,"Business Charts."

Page 81: SQR User's Guide

SQR 4.0 Cross-Tabular Reports

SQR User's Guide 67

Summary• Cross-tabular reports are matrix- or spreadsheet-like reports that are

useful for presenting summary data.

• CREATE-ARRAY can be used to assemble data for a report in arrays.

• Arrays can be referenced in expressions.

• Procedures can be written to select data for an array and print it.

• EVALUATE can be used to place data in the correct row of the array.

• Using multiple arrays can allow you to reduce database calls.

The next chapter explains how to use SQR to print mailing labels or otherdata in columns.

Page 82: SQR User's Guide
Page 83: SQR User's Guide

SQR User's Guide 69

9 Printing Mailing Labels

This chapter explains how to print mailing labels and similar information.The process is quite simple. A SQR SELECT paragraph retrieves theaddresses and prints them on the page.

Sometimes you'll need to print labels in multiple columns. The page thenbecomes a matrix of rows and columns of labels. SQR allows you to printinto columns with the commands COLUMNS and NEXT-COLUMN, inconjunction with NEXT-LISTING.

The following program prints mailing labels in a format of three columnsby ten rows. It also counts the number of labels printed and prints thatnumber on the last sheet of the report.

Program ex9a.sqr

#define MAX_LABEL_LINES 10#define LINES_BETWEEN_LABELS 3

begin-setup declare-layout default paper-size=(10,11) left-margin=0.33 end-declareend-setup

begin-program do mailing_labelsend-program

begin-procedure mailing_labels let #label_count = 0 let #label_lines = 0 columns 1 29 57 ! enable columns alter-printer font=5 point-size=10

Program continues on the following page.

Page 84: SQR User's Guide

Printing Mailing Labels SQR 4.0

70 SQR User's Guide

Program ex9a.sqr (continued)

begin-selectname (1,1,30)addr1 (2,1,30)citystatezip move &zip to $zip XXXXX-XXXX let $last_line = &city || ', ' || &state || ' ' || $zip print $last_line (3,1,30) next-column at-end=newline add 1 to #label_count if #current-column = 1 add 1 to #label_lines if #label_lines = {MAX_LABEL_LINES} new-page let #label_lines = 0 else next-listing no-advance skiplines={LINES_BETWEEN_LABELS} end-if end-iffrom customersend-select use-column 0 ! disable columns new-page print 'Labels printed on ' (,1) print $current-date () print 'Total labels printed = ' (+1,1) print #label_count () edit 9,999,999end-procedure ! mailing_labels

Defining Columns and Rows

The command COLUMNS 1 29 57 defines the starting position for threecolumns. The first column starts at character position 1, the second atcharacter position 29, and the third at character position 57.

The above program writes the first address into the first column, thesecond address into the second, the third address into the third. The fourthaddress will go into the second row of the first column, just below the firstlabel. When ten lines of labels are complete, a new page is started. Afterthe last page of labels has been printed, the program prints a summarypage showing the number of labels printed.

Page 85: SQR User's Guide

SQR 4.0 Printing Mailing Labels

SQR User's Guide 71

Note the technique for composing the last line of the label. The city, state,and zip columns are moved to string variables. The command LET$last_line = &city || ', ' || &state || ' ' || $zip combines the city, state,and zip code, plus appropriate punctuation and spacing, into a string,which it stores in the variable $last_line. In this way, city, state, and zipcode are printed without unnecessary gaps.

The program defines two counters, #label_count and #label_lines. The firstcounter, #label_count, counts the total number of labels and prints it on thesummary page. The second counter, #label_lines, counts the number ofrows of labels that were printed. When the program has printed thenumber of lines defined by {MAX_LABEL_LINES}, it starts a new page andresets the #label_lines counter.

After each row of labels, the NEXT-LISTING command redefines theposition where the next row of labels will be printed as line 1.NEXT-LISTING skips the specified number of lines (SKIPLINES) from thelast line that was printed (NO-ADVANCE) and sets the new position asline 1.

Note the use of the ALTER-PRINTER command. This command changesthe font in which the report is printed. For more information on changingfonts in SQR, see Chapter 14, "Changing Fonts."

The sample program prints the labels in 10-point Times Roman, which is aproportionally spaced font. In Windows, you can use proportionallyspaced fonts with any printer that supports fonts or graphics. On otherplatforms, SQR directly supports HP LaserJet printers and PostScriptprinters.

Printing and printer support are explained in greater detail in Chapter 26,"Printing Issues." For more information on using proportionally spacedfonts, see Chapter 14, "Changing Fonts."

In the sample program, the command DECLARE-LAYOUT defines a pagewidth of 10 inches. This width accommodates the printing of the thirdcolumn, which contains 30 characters and begins at character position 57.SQR assumes a default character grid of 10 characters per inch, whichwould cause the third column to print beyond the paper edge if this reportused the default font. The 10-point Times Roman used here, however,condenses the text so that it will fit on the page. The page width is set at 10inches to prevent SQR from treating the third-column print position as anerror.

Page 86: SQR User's Guide

Printing Mailing Labels SQR 4.0

72 SQR User's Guide

Running the Program

When you print with a proportionally spaced font, you must use a slightlydifferent technique for running the program and viewing the output. Ifyou are using a platform such as UNIX or VMS, specify the printer typewith the -PRINTER:xx flag. If you are using an HP LaserJet, enter-PRINTER:HP (or -printer:hp). If you are using a PostScript printer, enter-PRINTER:PS (or -printer:ps) on the command line. For example:

sqr ex9a username / password -printer:hp

You may also use the -KEEP command-line flag to produce output in theSQR Portable File format (SPF) and print it using SQR Print. You will stillneed to use the -PRINTER:xx flag when printing. SQR Portable Fileformat is covered in greater detail in Chapter 26.

With Workbench for Windows, neither -PRINTER:xx nor -KEEP isrequired. The output will automatically appear in the Viewer windowafter the report has been run. Here is a portion of the output:

Output for ex9a.sqr

Gregory Stonehaven Alfred E Newman & Company Eliot RichardsMiddlebrook Road 2837 East Third Street 2134 Partridge AveEverretsville, OH 40233-1000 New York, NY 10002-1001 Queens, NY 10213-1002

Isaiah J Schwartz and Company Harold Alexander Fink Harriet Bailey37211 Columbia Blvd 32077 Cedar Street 47 Season StreetZanesville, OH 44900-1300 Davenport, IN 62130-1025 Mamaroneck, NY 10833-1660

Clair Butterfield Quentin Fields Jerry's Junkyard Specialties371 Youngstown Blvd 37021 Cedar Road Crazy Lake CottagesTeaneck, NJ 00355-4530 Cleveland, OH 44121-9475 Frogline, NH 04821-9876

Kate's Out of Date Dress Shop Sam Johnson Joe Smith and Company2100 Park Ave 37 Cleaver Street 1711 Sunset BlvdNew York, NY 10134-2030 Bell Harbor, MI 40674-3900 Big Falls, NM 87893-7070

Corks and Bottles, Inc. Harry's Landmark Diner167 East Blvd. 17043 Silverfish RoadNew York, NY 10204-1234 Miningville, IN 40622-4321

The report produces the output in three columns corresponding to thedimensions of a sheet of mailing label stock. In the example above, thereport prints the labels left to right, filling each row of labels before movingdown the page.

Page 87: SQR User's Guide

SQR 4.0 Printing Mailing Labels

SQR User's Guide 73

You can also print the labels from the top down, filling each column beforemoving to the next column of labels. The code is shown below. Thedifferences between this code and the previous one are shown in bold. Theoutput is not printed here, but you can run the file and view it using thesame procedure you used for the previous example.

Program ex9b.sqr

#define MAX_LABEL_LINES 10#define LINES_BETWEEN_LABELS 3

begin-setup declare-layout default paper-size=(10,11) left-margin=0.33 end-declareend-setup

begin-program do mailing_labelsend-program

begin-procedure mailing_labels let #Label_Count = 0 let #Label_Lines = 0 columns 1 29 57 ! enable columnsalter-printer font=5 point-size=10begin-selectname (0,1,30)addr1 (+1,1,30)citystatezip move &zip to $zip xxxxx-xxxx let $last_line = &city || ', ' || &state || ' ' || $zip print $last_line (+1,1,30) add 1 to #label_count add 1 to #label_lines if #label_lines = {MAX_LABEL_LINES} next-column goto-top=1 at-end=newpage let #label_lines = 0 else position (+1) position (+{LINES_BETWEEN_LABELS}) end-iffrom customersend-select use-column 0 ! disable columns new-page print 'Labels printed on ' (,1) print $current-date () print 'Total labels printed = ' (+1,1) print #label_count () edit 9,999,999end-procedure ! mailing_labels

Page 88: SQR User's Guide

Printing Mailing Labels SQR 4.0

74 SQR User's Guide

Summary• A SELECT paragraph is used to retrieve data for mailing labels and

other similar reports.

• COLUMNS is used to define report columns.

• Counters, such as #label_count and #label_lines, produce summaryinformation about a report, such as the number of labels printed.Counters also determine when a page is full.

• NEXT-LISTING ends the current listing and begins another.

• ALTER-PRINTER can be used to specify fonts.

The next chapter describes how to create form letters.

Page 89: SQR User's Guide

SQR User's Guide 75

10 Creating Form Letters

This chapter explains how to create a form letter. You will be introducedto the SQR DOCUMENT section and two new commands:BEGIN-DOCUMENT and END-DOCUMENT.

Laying Out the Letter

To create form letters, you use a DOCUMENT section. It starts with aBEGIN-DOCUMENT command and ends with an END-DOCUMENTcommand. In between you lay out the letter and insert variables whereyou want data from the database to be inserted. SQR will insert the valueof the variable when the document is printed. To leave blank lines in aletter, you must explicitly mark them with a .b (see the sample codebelow).

Another way to mix data with the letter is to use document markers. Theseare placeholders in the DOCUMENT section where you can print data afterthe DOCUMENT section is printed. Document markers are denoted with aname preceded by the at sign (@).

The sample program demonstrates the use of variables as well asdocument markers. For most purposes, a variable would do. SQR willprint the contents of the variable in the position where it is placed in theDOCUMENT section. For example, in the program below, the customer'sname is printed on the first line.

Using a document marker is less direct, but it gives more flexibility inpositioning the contents of variables. The sample program uses adocument marker to position the city, state, and zip code because the cityname varies in length and thus affects the position of the state name andzip code.

This use of document markers is demonstrated in the simple form letterprogram below.

Page 90: SQR User's Guide

Creating Form Letters SQR 4.0

76 SQR User's Guide

Program ex10a.sqrbegin-program do mainend-program

begin-procedure mainbegin-selectnameaddr1addr2citystatezip do write_letterfrom customersorder by nameend-selectend-procedure ! main

begin-procedure write_letterbegin-document (1,1)&name&addr1&addr2@city_state_zip.b.b $current-dateDear Sir or Madam:.b Thank you for your recent purchases from ACME Inc. We would like totell you about our limited-time offer. During this month, our entireinventory is marked down by 25%. Yes, you can buy your favoritemerchandise and save too. To place an order simply dial 800-555-ACME. Delivery is free too, sodon't wait..b.b Sincerely, Clark Axelotle ACME Inc.end-documentposition () @city_state_zipprint &city ()print ', ' ()print &state ()print ' ' ()print &zip () edit xxxxx-xxxxnew-pageend-procedure ! write_letter

Page 91: SQR User's Guide

SQR 4.0 Creating Form Letters

SQR User's Guide 77

First, SQR performs the main procedure and the SELECT statement. Next,it performs the write_letter procedure and the DOCUMENT section. ThePOSITION command sets the position to the appropriate line, which isgiven by the marker @city_state_zip. The program prints the city, thencontinues printing the other elements to the current position. The statename, and zip code are automatically printed in the correct positions withappropriate punctuation.

Below is the first page of the output of our program for ex10a.sqr.

Alfred E Newman & Company2837 East Third StreetGreenwich VillageNew York, NY 10002-1001

10-MAY-1996Dear Sir or Madam:

Thank you for your recent purchases from ACME Inc. We would like totell you about our limited-time offer. During this month, our entireinventory is marked down by 25%. Yes, you can buy your favorite merchandiseand save too. To place an order simply dial 800-555-ACME. Delivery is free too, sodon't wait.

Sincerely, Clark Axelotle ACME Inc.

You will find another example of a form letter in Chapter 12, "UsingGraphics."

Summary• To print form letters, use variables or document markers inserted in the

DOCUMENT section to place data in the text.

The next chapter explains how to export data to other applications.

Page 92: SQR User's Guide
Page 93: SQR User's Guide

SQR User's Guide 79

11 Exporting Data to Other

Applications

This chapter shows you how to create a tab-delimited file that is suitablefor exporting data to many applications.

The following program example creates such a file, which you can loadinto a document such as a spreadsheet. The tabs create columns in yourspreadsheet or word processing document which will correspond to thecolumns in your database table.

Program ex11a.sqr

begin-setup ! No margins, wide enough for the widest record ! and no page breaks declare-layout default left-margin=0 top-margin=0 max_columns=160 formfeed=no end-declareend-setup

begin-program do mainend-program

begin-procedure mainencode '<009>' into $sep ! Separator character is TABlet $cust_num = 'Customer Number'let $name = 'Customer Name'let $addr1 = 'Address Line 1'let $addr2 = 'Address Line 2'let $city = 'City'let $state = 'State'let $zip = 'Zip Code'let $phone = 'Phone Number'let $tot = 'Total'string $cust_num $name $addr1 $addr2 $city $state $zip $phone $tot by $sep into $col_hdsprint $col_hds (1,1)new-page

Program continues on the following page.

Page 94: SQR User's Guide

Exporting Data to Other Applications SQR 4.0

80 SQR User's Guide

Program ex11a.sqr (continued)

begin-selectcust_numnameaddr1addr2citystatezipphonetot string &cust_num &name &addr1 &addr2 &city &state &zip &phone &tot by $sep into $db_cols print $db_cols () new-pagefrom customersend-selectend-procedure ! main

The ENCODE command stores the ASCII code for the tab character in thevariable $sep. The code (9) is enclosed in angle brackets to indicate that it isa non-display character. SQR will then treat it as a character code and setthe variable accordingly. ENCODE is a useful way to place nonalpha andnonnumeric characters into variables.

The LET command creates variables for the text strings used as columnheadings in the export file. The STRING command combines thesevariables in the $col_hds variable, with each heading separated by a tab.

In the SELECT paragraph, we use the STRING command again, this timeto combine the records (named as column variables) in the $db_colsvariable, with each record similarly separated by a tab.

The NEW-PAGE command is used in this example in an unusual way. Itreally causes a new line and carriage return at the end of each record, withthe line number reset to 1. There is no page ejection because of theFORMFEED=NO argument in the DECLARE-LAYOUT command.Remember, this report is meant to be exported, not printed.

You can now load the output file (ex11a.lis) into a spreadsheet or otherapplication.

Page 95: SQR User's Guide

SQR 4.0 Exporting Data to Other Applications

SQR User's Guide 81

Summary• A tab-delimited output file can be used to export data into other

applications.

• The contents of database column variables can also be exported.

• ENCODE can be used to place the ASCII code for a tab into a value.

• LET can be used to place text in variables for export.

• STRING can be used to create a variable holding several text or dataitems separated by a variable representing a tab or other separatorcharacter.

The next chapter explains how to create graphical reports.

Page 96: SQR User's Guide
Page 97: SQR User's Guide

SQR User's Guide 83

12 Using Graphics

This chapter explains how to add graphical features to SQR reports. Youwill learn how to include a logo or other graphic in a report, change thefont, and draw solid lines.

The following example produces a simple tabular report similar to the onein Chapter 3.

Program ex12a.sqr

begin-setup declare-layout default end-declareend-setup

begin-program do mainend-program

begin-procedure mainbegin-selectname (,1,30)city (,+1,16)state (,+1,5)tot (,+1,11) edit 99999999.99 next-listing no-advance need=1 let #grand_total = #grand_total + &totfrom customersend-selectprint '-' (,55,11) fillprint 'Grand Total' (+1,40)print #grand_total (,55,11) edit 99999999.99end-procedure ! main

begin-heading 5 print $current-date (1,1) Edit 'DD-MON-YYYY' page-number (1,60) 'Page ' print 'Name' (3,1) print 'City' (,32) print 'State' (,49) print 'Total' (,61) print '-' (4,1,65) fillend-heading

Page 98: SQR User's Guide

Using Graphics SQR 4.0

84 SQR User's Guide

The SETUP section contains a DECLARE-LAYOUT command thatspecifies the default layout without defining any options. The purpose ofspecifying the default layout is to use its margin settings, which aredefined as 1/2 inch. Without DECLARE-LAYOUT, the report would haveno margins.

Note the PRINT command with the FILL option. This command producesdashed lines, which is a simple way to draw lines for a report printed on aline printer. On a graphical printer, however, it is possible to draw solidlines. The next section, "Adding Graphics," shows you how to takeadvantage of this feature.

06-JUN-96 Page 1

Name City State Total -----------------------------------------------------------------

Gregory Stonehaven Everretsville OH 39.00 Alfred E Newman & Company New York NY 42.00 Eliot Richards Queens NY 30.00 Isaiah J Schwartz and Company Zanesville OH 33.00 Harold Alexander Fink Davenport IN 36.00 Harriet Bailey Mamaroneck NY 21.00 Clair Butterfield Teaneck NJ 24.00 Quentin Fields Cleveland OH 27.00 Jerry's Junkyard Specialties Frogline NH 12.00 Kate's Out of Date Dress Shop New York NY 15.00 Sam Johnson Bell Harbor MI 18.00 Joe Smith and Company Big Falls NM 3.00 Corks and Bottles, Inc. New York NY 6.00 Harry's Landmark Diner Miningville IN 9.00 ----------- Grand Total 315.00

Adding Graphics

The next sample program includes graphical features—a logo, solid lines,and a change of font in the heading. Text that has changed is shown inbold.

Page 99: SQR User's Guide

SQR 4.0 Using Graphics

SQR User's Guide 85

Program ex12b.sqr

begin-setup declare-layout default end-declareend-setup

begin-program do mainend-programbegin-procedure mainbegin-selectname (,1,30)city (,+1,16)state (,+1,5)tot (,+1,11) edit 99999999.99 next-listing no-advance need=1 let #grand_total = #grand_total + &totfrom customersend-selectgraphic (,55,12) horz-line 20print 'Grand Total' (+2,40)print #grand_total (,55,11) Edit 99999999.99end-procedure ! main

begin-heading 11 print $current-date (1,1) page-number (1,60) 'Page ' alter-printer point-size=14 font=4 ! switch font print 'Name' (9,1) bold print 'City' (,32) bold print 'State' (,49) bold print 'Total' (,61) bold alter-printer point-size=12 font=3 ! restore font graphic (9,1,66) horz-line 20 print-image (1,23) type=bmp-file image-size=(21,5) source='acmelogo.bmp'end-heading

The GRAPHIC command is used to draw solid lines with the HORZ-LINEoption. The line is positioned using a normal SQR position specifier. Notethat the third number in the position specifier is the length of the line,which is given in characters. (The actual width of a character cell isdetermined by the CHAR-WIDTH or MAX-COLUMNS arguments ofDECLARE-LAYOUT. See Chapter 6 for more information on charactergrids.)

Page 100: SQR User's Guide

Using Graphics SQR 4.0

86 SQR User's Guide

The HORZ-LINE argument of the GRAPHIC HORZ-LINE command isthe thickness of the line, and it is specified in decipoints (there are 720decipoints per inch). For example, the command

graphic (10,1,66) horz-line 20

specifies a horizontal line below line 10 in the report starting with position1 (the left side of the report) and stretching for 66 character positions (at 10characters per inch this is 6.6 inches). The thickness of the line is 20decipoints, which is 1/36 of an inch (about 0.7 millimeters).

The GRAPHIC command can also be used to draw vertical lines, boxesand shaded boxes. See the program sqrlaser.sqr, which is in your SAMPLE(or SAMPLEW) subdirectory, for an example. The GRAPHIC command inthe SQR Language Reference also provides more information.

The ALTER-PRINTER command in ex12b.sqr changes the font for theheading. When used a second time, it restores the normal font for the restof the report. The FONT option selects a font (typeface) that is supportedby the printer. The font is specified by number, but the number is printer-specific. On a PostScript printer, for example, font 3 is Courier, font 4 isHelvetica, and font 5 is Times Roman. For more information on fonts, seeDECLARE-PRINTER in the SQR Language Reference.

The POINT-SIZE option specifies type size in points. You can use a wholenumber or even a fraction (for example, POINT-SIZE=10.5). Thefollowing command changes the font to 14-point Helvetica:

alter-printer point-size=14 font=4 ! switch font

The PRINT-IMAGE command inserts the logo. PRINT-IMAGE isfollowed by a print position corresponding to the top left corner of theimage (line 1, column 19 in our example). The TYPE option specifies theimage file type. In our example the image is stored in Windows bitmapformat (bmp-file). The size of the image is specified in terms of columns(width) and lines (height). In the example, the image is 30 characters wide(3 inches) and 7 lines high (1 1/6 inches).

In SQR, images are always stored in external files. The format of the imagemust match that of the printer you are using. These formats are:

• Windows—bmp-file images

• PostScript printer or viewer—eps-file

• HP LaserJet—hpgl-file images

• HTML output—GIF or JPEG formats (gif-file or jpeg-file)

Page 101: SQR User's Guide

SQR 4.0 Using Graphics

SQR User's Guide 87

For more information on HTML output, see Chapter 28, "Working withHTML."

The SOURCE option specifies the file name of the image file. In ourexample, the file is ACMELOGO.BMP. The file is assumed to reside in thecurrent directory or in the directory where SQR is installed (you can placethe logo file in either of these two places). The file may reside in anydirectory, however, as long as you specify a full pathname for the imagefile.

Output for ex12b.sqr

The output file now contains graphic language commands. SQR canproduce output suitable for HP LaserJet printers in a file format that usesthe HP PCL language or output suitable for PostScript printers in a fileformat that uses the PostScript language. SQR can also produce printer-independent output files in a special format called SQR Portable Format(SPF).

Page 102: SQR User's Guide

Using Graphics SQR 4.0

88 SQR User's Guide

SQR can create a printer-specific output file (an .LIS file) or create theoutput in portable format (.SPF). When you create an .SPF file, the nameof the image file is copied into it, and the image is processed at print time,when printer-specific output is generated. When using .SPF files, a changein the contents of the image file will be reflected in the report the next timeyou print it or view it. You can create printer-specific output by using SQRor SQR Execute to directly generate an .LIS file or by using SQR Print togenerate an .LIS file from an .SPF file.

For more information on SQR Portable Format, see Chapter 26, "PrintingIssues."

Sharing Images among Reports

You can place logos and other images in a report using only thePRINT-IMAGE command. However, the DECLARE-IMAGE command isuseful if you want several programs to share the definition of an image.

Program ex12c.sqr prints a simple form letter. It shows how to print a logousing the DECLARE-IMAGE and PRINT-IMAGE commands and how toprint a signature using only PRINT-IMAGE.

Because the image is shared among several reports, the commandDECLARE-IMAGE is contained in this file, acme.inc:

File acme.inc

declare-image acme_logo type=bmp-file image-size=(30,7) source='acmelogo.bmp'end-declare

This file declares an image with "acme-logo" as the name. It specifies thelogo used in the last sample program. The declaration includes the typeand source file for the image. As you will see, when the image is printed,you do not need to respecify these attributes.

Multiple programs can share the declaration and include the file acme.inc.If you later need to change an attribute, such as the source, you only needto change it in one place. The image size is specified and provides thedefault.

Page 103: SQR User's Guide

SQR 4.0 Using Graphics

SQR User's Guide 89

If you need to change the size of an image in a particular report, use theIMAGE-SIZE argument of the PRINT-IMAGE command. It will overridethe image size specified in DECLARE-IMAGE.

Program ex12c.sqr

begin-setup#include 'acme.inc'end-setup

begin-program do mainend-program

begin-procedure mainbegin-selectnameaddr1addr2citystatezipphone do write_letterfrom customersorder by nameend-selectend-procedure ! main

begin-procedure write_lettermove &city to $cszconcat ', ' with $cszconcat &state with $cszconcat ' ' with $cszmove &zip to $zip xxxxx-xxxxconcat $zip with $cszmove &phone to $phone_no (xxx)bxxx-xxxx ! Edit phone number.

Program continues on the following page.

Page 104: SQR User's Guide

Using Graphics SQR 4.0

90 SQR User's Guide

Program ex12c.sqr (continued)

begin-document (1,1,0)&name @logo&addr1&addr2$csz.b.b.b $current-dateDear &name.b Thank you for your inquiry regarding Encore, Maestro!!, ourrevolutionary teaching system for piano and organ. If you've always wantedto play an instrument but felt you could never master one, Encore,Maestro!! is made for you..b Now anyone who can hum a tune can play one too. Encore, Maestro!!begins with a step-by-step approach to some of America's favoritesongs. You'll learn the correct keyboarding while hearing the soundsyou make through the headphones provided with the Encore, Maestro!!system. From there, you'll advance to intricate compositions withdazzling melodic runs. Encore, Maestro!! can even teach you toimprovise your own solos..b Whether you like classical, jazz, pop, or blues, Encore, Maestro!!is the music teacher for you..b A local representative will be calling you at $phone_noto set up an in-house demonstration, so get ready to play your favoritetunes!!.b Sincerely, @signature.b.b Clark Axelotleend-documentposition () @logoprint-image acme-logo () image-size=(16,4)position () @signatureprint-image () type=bmp-file image-size=(12,3) source='clark.bmp'new-pageend-procedure ! write_letter

Page 105: SQR User's Guide

SQR 4.0 Using Graphics

SQR User's Guide 91

The #INCLUDE command, which is performed at compile time, is used topull in text from another file. In this program, see the command#INCLUDE 'ACME.INC' includes the code from the file acme.inc in thisprogram.

The DOCUMENT section begins with a BEGIN-DOCUMENT commandand ends with an END-DOCUMENT command. It uses variables anddocument markers to print inside the letter. The program uses variablesfor the name and address, the date, and the phone number. It usesdocument markers for the logo and signature.

Document markers are placeholders in the letter. The program uses thedocument markers @logo and @signature in a POSITION command beforeprinting each image. The document markers make it unnecessary tospecify the position of these items in the PRINT-IMAGE command.Instead, you simply print to the current position.

The date is prepared with the reserved variable $current-date. It is printeddirectly in the DOCUMENT section without issuing a PRINT command.

The program uses the CONCAT command to put together the city, state,and zip code. In the DOCUMENT section, variables retain their predefinedsize. A column variable, for example, will remain the width of the columnas defined in the database. You can print the date and phone numberdirectly, however, because they fall at the end of a line, without anyfollowing text.

The output of our program is shown on the following page.

Page 106: SQR User's Guide

Using Graphics SQR 4.0

92 SQR User's Guide

File ex12c.spf

Printing Bar Codes

You can also include bar codes in your SQR report. SQR supports a widevariety of bar code types.

To create a bar code, use the PRINT-BAR-CODE command. Specify theposition of the bar code in an ordinary position qualifier. In separatearguments, specify the bar code type, height, text to be encoded, caption,and optional check sum. For example:

print-bar-code (1,1) type=1 height=0.5 text='01234567890' caption='0 12345 67890'

Page 107: SQR User's Guide

SQR 4.0 Using Graphics

SQR User's Guide 93

Arguments to PRINT-BAR-CODE may be variables or literals. Theexample above will produce the following bar code:

For further information, see the PRINT-BAR-CODE command in the SQRLanguage Reference.

Summary• DECLARE-LAYOUT can be used to set a margin.

• GRAPHIC can be used to draw solid lines or shaded boxes.

• ALTER-PRINTER chooses a font.

• PRINT-IMAGE prints a logo or other graphic in the report.

• DECLARE-IMAGE allows you to share images among reports.

• The #INCLUDE command is used to include commands from otherfiles in a program.

• CONCAT is used to combine multiple data elements into one variable.

• PRINT-BAR-CODE can be used to create bar codes.

The next chapter shows how to present information visually with chartsand other graphics.

Page 108: SQR User's Guide
Page 109: SQR User's Guide

SQR User's Guide 95

13 Business Charts

This chapter shows how to present information visually with graphs,charts, and histograms.

Business charts are useful tools for presenting summary data. SQRprovides two commands for creating charts, DECLARE-CHART andPRINT-CHART, and a rich set of chart types—line, pie, bar, stacked bar,100% bar, overlapped bar, floating bar, histogram, area, stacked area, 100%area, xy-scatter plot and high-low-close.

You can customize many attributes of SQR charts by turning on three-dimensional effects or setting titles and legends. SQR charts are alsoportable—you can move them from one hardware platform to another.

A business chart can be prepared using data held in an array, just like across-tabular report (see Chapter 8). If you've already written a cross-tabular report, it's just one more step to make a chart using the dataalready collected in the array.

Creating a Chart

The following example builds on the report created in Chapter 8, "Cross-Tabular Reports and the Use of Arrays" (ex8c.sqr). That example combinedthe two reports in one program. The following program produces twocharts corresponding to the two cross-tabs.

Here is the code. The lines that were changed or added are shown in bold.

Page 110: SQR User's Guide

Business Charts SQR 4.0

96 SQR User's Guide

Program ex13a.sqr

#define max-categories 3#define max-products 100

begin-setup create-array name=order_qty size={max-products} field=product:char field=month_qty:number:3 create-array name=order_qty2 size={max-categories} field=category:char field=month_qty:number:3 declare-chart orders-stacked-bar chart-size=(70,30) title='Order Quantity' legend-title='Month' type=stacked-bar end-declare ! orders-stacked-barend-setup

begin-program do select_data do print_array print '-' (+2,1,70) fill position (+1) do print_array2 new-page let $done = 'YES' ! Don't need heading any more do print_the_chartsend-program

begin-procedure print_array let #entry_cnt = #i let #i = 0 while #i <= #entry_cnt let $product = order_qty.product(#i) let #jan = order_qty.month_qty(#i,0) let #feb = order_qty.month_qty(#i,1) let #mar = order_qty.month_qty(#i,2) let #prod_tot = #jan + #feb + #mar print $product (,1,30) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #prod_tot (,62,9) edit 9,999,999 position (+1) let #i = #i + 1 end-whileend-procedure ! print_array

Program continues on the following page.

Page 111: SQR User's Guide

SQR 4.0 Business Charts

SQR User's Guide 97

Program ex13a.sqr (continued)

begin-procedure print_array2 let #i = 0 while #i < {max_categories} let $category = order_qty2.category(#i) let #jan = order_qty2.month_qty(#i,0) let #feb = order_qty2.month_qty(#i,1) let #mar = order_qty2.month_qty(#i,2) let #category_tot = #jan + #feb + #mar print $category (,1,31) print #jan (,32,9) edit 9,999,999 print #feb (,42,9) edit 9,999,999 print #mar (,52,9) edit 9,999,999 print #category_tot (,62,9) edit 9,999,999 position (+1) let #jan_total = #jan_total + #jan let #feb_total = #feb_total + #feb let #mar_total = #mar_total + #mar let #i = #i + 1 end-while let #grand_total = #jan_total + #feb_total + #mar_total print 'Totals' (+2,1) print #jan_total (,32,9) edit 9,999,999 print #feb_total (,42,9) edit 9,999,999 print #mar_total (,52,9) edit 9,999,999 print #grand_total (,62,9) edit 9,999,999end-procedure ! print_array2

begin-procedure select_data let order_qty2.category(0)='$0-$4.99' let order_qty2.category(1)='$5.00-$100.00' let order_qty2.category(2)='Over $100'begin-selectorder_date! the price / price category for the orderc.price &price move &price to #price_num evaluate #price_num when < 5.0 let #x = 0 break when <= 100.0 let #x = 1 break

Program continues on the following page.

Page 112: SQR User's Guide

Business Charts SQR 4.0

98 SQR User's Guide

Program ex13a.sqr (continued)

when-other let #x = 2 break end-evaluate! The quantity for this orderquantity let #j = to_number(datetostr(&order_date,'MM')) - 1 if #j < 3 let order_qty2.month_qty(#x,#j) = order_qty2.month_qty(#x,#j) + &quantity end-if! the product for this orderdescription if #i = 0 and order_qty.product(#i) = '' let order_qty.product(#i) = &description end-if if order_qty.product(#i) != &description let #i = #i + 1 if #i >= {max_products} display 'Error: There are more than {max_products}products' stop end-if let order_qty.product(#i) = &description end-if if #j < 3 let order_qty.month_qty(#i,#j) = order_qty.month_qty(#i,#j) + &quantity end-iffrom orders a, ordlines b, products cwhere a.order_num = b.order_numand b.product_code = c.product_codeorder by descriptionend-selectend-procedure ! select_data

begin-heading 5 if not ($done = 'YES') print $current-date (1,1) page-number (1,64) 'Page ' print 'Order Quantity by Product and Price Category by Month' (2,10) print 'Product / Price Category' (4,1) print ' January' (,32) print ' February' (,42) print ' March' (,52) print ' Total' (,62) Print '-' (5,1,70) Fill end-ifend-heading

Program continues on the following page.

Page 113: SQR User's Guide

SQR 4.0 Business Charts

SQR User's Guide 99

Program ex13a.sqr (continued)

begin-procedure print_the_charts print-chart orders-stacked-bar (+2,1) data-array=order_qty data-array-row-count=12 data-array-column-count=4 data-array-column-labels=('Jan','Feb','Mar')sub-title='By Product By Month' new-page print-chart orders-stacked-bar (+2,1) data-array=order_qty2 data-array-row-count=3 data-array-column-count=4 data-array-column-labels=('Jan','Feb','Mar') sub-title='By Price Category By Month'end-procedure ! print_the_charts

Defining the Chart

The two charts in program ex13a.sqr are based on the DECLARE-CHARTcommand in the SETUP section and are named orders-stacked-bar. Thewidth and height of the charts are specified in terms of character cells. Thecharts generated by this program will be 70 characters wide, which is 7inches on a default layout. The height (or depth; these terms are usedinterchangeably) of the charts is 30 lines, which translates to 5 inches at 6lines per inch. These dimensions define a rectangle that contains the chart.The box that surrounds the chart is drawn by default, but you can disableit using the qualifier BORDER=NO.

The title is centered at the top of the chart. The text generated byLEGEND-TITLE must fit in the small legend box above the categories, sokeep this description short. In general, you'll find that charts look bestwhen the text items are short. Here is the DECLARE-CHART command:

declare-chart orders-stacked-bar chart-size=(70,30) title='Order Quantity' legend-title='Month' type=stacked-bar end-declare ! orders-stacked-bar

The heading is disabled for the last two pages where the charts are printed.

Page 114: SQR User's Guide

Business Charts SQR 4.0

100 SQR User's Guide

Printing the Chart

Now look at the PRINT-CHART commands. Both are based on the orders-stacked-bar chart that was declared above.

print-chart orders-stacked-bar (+2,1) data-array=order_qty data-array-row-count=12 data-array-column-count=4 data-array-column-labels=('Jan','Feb','Mar')sub-title='By Product By Month' new-page print-chart orders-stacked-bar (+2,1) data-array=order_qty2 data-array-row-count=3 data-array-column-count=4 data-array-column-labels=('Jan','Feb','Mar') sub-title='By Price Category By Month'

The data source is specified using the DATA-ARRAY option. The namedarray is expected to have a certain structure that is specified by the TYPEoption. For a stacked-bar chart, the first field in the array gives the namesof the categories for the bars. The rest of the fields are series of numbers.In this case, each series corresponds to a month.

The subtitle goes under the title and can be used as a second line of thetitle. A legend is used to label the series. The argumentDATA-ARRAY-COLUMN-LABELS is used to pass these labels. Theargument DATA-ARRAY-ROW-COUNT is the number of rows (bars) tochart and DATA-ARRAY-COLUMN-COUNT is the number of fields inthe array that the chart uses. There are four fields in the array—theproduct (or price category) field plus the three series (months).

Running the Program

When you create a graphical report, you must use a slightly differenttechnique for running the program and viewing the output. If you areusing a platform such as UNIX or VMS, specify the printer type with theflag -PRINTER:xx. If you are using an HP LaserJet, enter -PRINTER:HP(or -printer:hp). If you are using a PostScript printer, enter -PRINTER:PS(or -printer:ps) on the command line. For example:

sqr ex9a username / password -printer:hp

You may also use the -KEEP command-line flag to produce output in theSQR Portable File format (SPF) and print it using SQR Print. You will stillneed to use the -PRINTER:xx flag when printing. SQR Portable Fileformat is covered in greater detail in Chapter 26.

Page 115: SQR User's Guide

SQR 4.0 Business Charts

SQR User's Guide 101

With Workbench for Windows, neither -PRINTER:xx nor -KEEP isrequired. The output will automatically appear in the Viewer windowafter the report has been run. Here is a portion of the output:

The charts will appear on pages 2 and 3 of the report.

Output for file ex13a.spf

Page 116: SQR User's Guide

Business Charts SQR 4.0

102 SQR User's Guide

Passing Data to the Chart

The procedure for passing the data to the chart is to use the first field forthe descriptions of bars (or lines or areas) and then use one or moreadditional fields with series of numbers. This procedure is common tomany chart types, including line, bar, stacked-bar, 100% bar, overlappedbar, histogram, area, stacked-area, and 100% area. You can omit the firstfield and SQR will use cardinal numbers (1,2, ...) for the bars. Only textfields will be used for these options.

For pie charts, only one series is allowed. Pie charts are also a special casebecause you can specify which segments to "explode," or pull away, fromthe center of the pie. Using a third field in the array, you can have a seriesof 'Y' and 'N' values which indicate whether or not to explode the segment.If 'Y' is the value in the first row of the array, the pie segment thatcorresponds to the first row will be exploded. With pie charts, you cannotomit the first field with the descriptions. Pie charts cannot have more than12 segments.

Page 117: SQR User's Guide

SQR 4.0 Business Charts

SQR User's Guide 103

Pie charts display the numeric value next to each segment. The descriptionis displayed in the legend. In addition, SQR displays the percentage nextto the value. You can disable this feature by using the qualifierPIE-SEGMENT-PERCENT-DISPLAY=NO.

When data is passed to an xy scatter plot or a floating-bar chart, the seriesare paired. A pair in a floating-bar chart represents the base and height ofthe bars. A pair in an xy-scatter plot represents x and y coordinates. In anxy-scatter plot, the first field does not have descriptions. In a floating-barchart, the first field may or may not have descriptions for the bars. Forboth types, you can have one or more pairs of series.

Summary• DECLARE-CHART and PRINT-CHART are used to print charts.

• Data arrays must be used to assemble and process the data used inmaking a chart.

The next chapter gives details on changing fonts.

Page 118: SQR User's Guide
Page 119: SQR User's Guide

SQR User's Guide 105

14 Changing Fonts

This chapter explains how to print text in different fonts.

To select a font in SQR, you use the commands DECLARE-PRINTER andALTER-PRINTER. The DECLARE-PRINTER command sets the defaultfont for the entire report. The ALTER-PRINTER command changes thefont anywhere in the report, and the change remains in effect until the nextALTER-PRINTER.

If you want to set a font for the entire report, use ALTER-PRINTER, whichis not printer-specific, at the beginning of the program. If you are writing aprinter-independent report, be aware that the attributes you set withDECLARE-PRINTER only take effect when you print your report with theprinter you specify with the TYPE argument. To specify a printer at printtime, use the -PRINTER:xx command-line flag.

Positioning Text

In SQR, text is positioned according to a grid. That grid is set by default to10 characters per inch and 6 lines per inch, but you can give it anotherdefinition by altering the CHAR-WIDTH and LINE-HEIGHT parametersof the DECLARE-LAYOUT command.

Note however that character grid and character size functionindependently of one another. Fonts will print in the size set byDECLARE-PRINTER or ALTER-PRINTER, not the size defined by thegrid. A character grid is best used for positioning the first character in astring. It can only express the width of a string in terms of the number ofcharacters it contains, not in an actual linear measurement, such as inchesor picas.

When you use a proportionally spaced font, the number of letters that youprint may no longer match the number of character cells that the textactually fills. For example, in the illustration below, the word"Proportionally" fills only 9 cells, although it contains 14 letters.

Page 120: SQR User's Guide

Changing Fonts SQR 4.0

106 SQR User's Guide

Report Title

Proportionally spaced font

Large TimesRoman font atposition (4,4)

SQR default fontat position (8,3)

12-pt TimesRoman font atposition (10,2)

.

.Fixed pitch font

When you print consecutive text strings, the actual position at the end of astring may differ from the position SQR assumes according to the grid. Forthis reason, we advise you to concatenate consecutive pieces of text andprint them as one. For example, instead of writing code such as:

alter-printer font=5 ! select a proportional fontprint &first_name () ! print first nameprint ' ' () ! print a spaceprint &last_name () ! print the last namealter-printer font=3 ! restore the font

You should write code such as:

alter-printer font=5 ! select a proportional font! concatenate the namelet $full_name = &first_name || ' ' || &last_nameprint $full_name () ! print the namealter-printer font=3 ! restore the font

The WRAP and CENTER options of the PRINT command also requirespecial consideration when used with proportional fonts. They bothcalculate the text length based on the character count in the grid, which isnot the same as its dimensional width. The use of these options withproportional fonts is explained below, after the output example.

Look at the sample program. It consists of a list of reminders from thereminders table. It is printed in a mix of fonts—Times Roman in twodifferent sizes, plus Helvetica bold.

Page 121: SQR User's Guide

SQR 4.0 Changing Fonts

SQR User's Guide 107

Program ex14a.sqr

begin-setup declare-layout default paper-size=(10,11) end-declareend-setup

begin-program do mainend-program

begin-procedure main! Set Times Roman as the font for the reportalter-printer font=5 point-size=12begin-selectremind_date (,1,20) edit 'DD-MON-YY'reminder (,+1) wrap 60 5 position (+2)from remindersend-selectend-procedure ! main

begin-heading 7 print $current-date (1,1) Edit 'DD-MON-YYYY' page-number (1,60) 'Page ' ! Use large font for the title alter-printer font=5 point-size=24 print 'Reminder List' (3,25) ! Use Helvetica for the column headings alter-printer font=4 point-size=12 print 'Date' (6,1) bold print 'Reminder' (6,22) bold graphic (6,1,66) horz-line ! Restore the font alter-printer font=5 point-size=12end-heading

The report uses the default layout grid of 10 characters per inch and 6 linesper inch, both for positioning the text and for setting the length of the solidline.

The font is set at the beginning of the main procedure to font 5, which isTimes Roman. The point size was not set, so it remains at the default of 12.In the HEADING section, its size is set to 24 points to print the title.

The column headings are set to 12-point Helvetica with the commandALTER-PRINTER FONT=4 POINT-SIZE=12. The BOLD option of thePRINT command specifies that they are printed in bold.

Page 122: SQR User's Guide

Changing Fonts SQR 4.0

108 SQR User's Guide

Under the column headings, there is a solid line. Note that it is positionedat line 6, the same as the column headings. SQR is designed to draw thesolid line as an underline. At the end the HEADING section, the font isrestored to Times Roman.

Program ex14a.spf

In an SQR program, the report heading is performed after the body. A fontchange in the heading will not affect the font used in the body of thecurrent page, although it will change the font used in the body ofsubsequent pages. Make sure you keep track of your font changes. Werecommend that you return fonts to their original settings in the samesection in which you change them.

Positioning the title requires careful coding. The CENTER option of thePRINT command won't work because it does not account for the actualsize of the text. Instead, position the title by estimating its length. In thiscase, the title should start 2 1/2 inches from the left margin. The charactercoordinates will be "(3,25)," which is line 3, character position 25.Remember that the character grid used for positioning assumes 10characters per inch. Therefore, 25 characters translates to 2 1/2 inches.

Using WRAP

The WRAP option of the PRINT command is used to print the text of thereminder column. This option wraps text based on a given width, which is60 characters in the sample program.

Page 123: SQR User's Guide

SQR 4.0 Changing Fonts

SQR User's Guide 109

The WRAP option works only on the basis of the width given in thecharacter grid. It does not depend on the font.

Text printed in Times Roman takes about 30-50 percent less room than thesame text in Courier (the default font, which is a fixed-size font). Thismeans that a column with a nominal width of 44 characters (that's thewidth of the reminder column) can actually hold as many as 66 letters whenprinted in the Times Roman font. To be conservative, specify a width of60.

The other argument of the WRAP option is the maximum number of lines.Since the reminder column in the database is 240 characters wide, at 60characters per line, no more than 5 lines are needed. Remember, thissetting only specifies the maximum number of lines. SQR will not usemore lines than are needed.

SQR calculates the maximum number of characters on a line using thepage dimensions in the DECLARE-LAYOUT command (the default is8 1/2 inches wide). In the sample program, 8 1/2 inches minus the inchused in the margins is 7 1/2 inches, or 75 characters at 10 CPI. Printing 60characters starting from position 22 could exceed this maximum and causean error or undesirable output. To avoid this error, define the page aswider than it actually is. This definition is given by the argument PAPER-SIZE=(10,11) in the DECLARE-LAYOUT command.

Summary• DECLARE-PRINTER and ALTER-PRINTER are used to specify fonts.

• DECLARE-PRINTER is printer-specific. ALTER-PRINTER is printer-neutral.

• The BOLD, CENTER, and WRAP options of the PRINT command areused to format text.

The next chapter explains how to write reports that can be printed on anyprinter.

Page 124: SQR User's Guide
Page 125: SQR User's Guide

SQR User's Guide 111

15 Writing Printer-Independent

Reports

This chapter explains how to prepare printer-independent reports, whichcan be run on any printer that SQR supports or distributed electronically.

To create a printer-independent report, you must write a program thatavoids using any characteristics that are unique to a specific printer.

As you will see, complete printer independence may be too restrictive.However, the closer you can get to a truly printer-independent report, thebetter.

Guidelines for Printer-Independent Reports

• Your program should not assume or require a specific printer. Yourprogram should be free of the following commands: GRAPHIC FONT(use ALTER-PRINTER instead), PRINTER-INIT, PRINTER-DEINIT,USE-PRINTER-TYPE (except for using this command to select a printerat run time, as demonstrated below), and the CODE-PRINTER andCODE qualifiers of the PRINT command.

• DECLARE-PRINTER, PRINT-DIRECT, the CODE orCODE-PRINTER qualifiers of the PRINT command, and theSYMBOL-SET argument of the ALTER-PRINTER command onlydefine behavior when a specific printer is used.

• Your report should be readable if printed on a line printer. Graphics orsolid lines printed with the graphic command are not printed on a lineprinter. Test your graphical report on a line printer.

• Use only a small set of fonts. Font numbers 3, 4, 5 and their boldfaceversions are the same regardless of the type of printer you use (exceptfor a line printer). Font 3 is Courier, font 4 is Helvetica, and font 5 isTimes Roman. Note that on some HP printers, Helvetica may not beavailable. This reduces the common fonts to fonts 3 and 5 only.

Page 126: SQR User's Guide

Writing Printer-Independent Reports SQR 4.0

112 SQR User's Guide

• Be aware of certain limitations. Eps-file images can only be printed onPostScript printers. Hpgl-file images can only be printed on HPLaserJet Series 3 or higher or printers that emulate HP PCL at that level.Bmp-file images can only be printed using Windows. Gif-file andjpeg-file images are suitable only for HTML output. PRINT-IMAGEand PRINT-CHART may not work with old printers that use PostScriptLevel 1 or HP LaserJet Series II.

If your report is printer-neutral and does not specify a printer, you canspecify the printer at run time in two ways.

The first way is to use the -PRINTER:xx command-line flag, whichspecifies the output type for your report. Use -PRINTER:LP for line-printer output, -PRINTER:PS for PostScript output, -PRINTER:HP for HPLaserJet output, -PRINTER:WP for Windows output, or -PRINTER:HT forHTML output.

If you are using Workbench for Windows, enter this command-line flag inthe Parameters field of the Run dialog box. If you are using the systemshell, enter the following on the command line:

sqr test username / password -printer:ps

The second way of specifying the printer type is by using theUSE-PRINTER-TYPE command. In the next example, you can see thePROGRAM section of the program ex3a.sqr modified to prompt the user toselect the printer type at run time. The added lines are shown in bold type.

begin-program input $p 'Printer type' ! Prompt user for printer type let $p = lower($p) ! Convert type to lowercase evaluate $p ! Case statement when = 'hp' when = 'hplaserjet' ! HP LaserJet use-printer-type hp break when = 'lp' when = 'lineprinter' ! Line Printer use-printer-type lp break when = 'ps' when = 'postscript' ! PostScript use-printer-type ps break when-other display 'Invalid printer type.' stop end-evaluate do list_customers

Page 127: SQR User's Guide

SQR 4.0 Writing Printer-Independent Reports

SQR User's Guide 113

end-program

In the code above, the INPUT command prompts the user to enter theprinter type. Because the USE-PRINTER-TYPE command does not accepta variable as an argument, the EVALUATE command is used to test for thesix possible values and set the printer type accordingly.

The EVALUATE command is similar to a switch statement in the Clanguage. It compares a variable to multiple constants and executes theappropriate code.

Summary• Reports can be made printer-independent by writing programs that do

not require a certain printer.

• The -PRINTER:xx command-line flag and the USE-PRINTER-TYPEand EVALUATE commands prompt the user to specify the printer atrun time.

The next chapter describes how to produce reports that vary according tothe report parameters and selection criteria supplied by the user.

Page 128: SQR User's Guide
Page 129: SQR User's Guide

SQR User's Guide 115

16 Dynamic SQL and Error Checking

This chapter describes how to vary the SQL statement based on a user'sselection criteria or other report parameters.

SQR provides three ways to vary a SQL statement:

• Using variables in SQL

• Dynamic SQL

• SQL and substitution variables

SQR provides three ways to do error checking:

• ON-ERROR procedures

• Commands with ON-ERROR options

• The INPUT command

These techniques are described in more detail in the following sections.

Using Variables in SQL

The SQL language supports the use of variables. A SQL statementcontaining variables is considered static. When SQR executes thisstatement several times, it is considered as executing the same statement,even if the values of the variables change. Since SQL only allows variablesin places where literals are allowed (such as in a WHERE clause or INSERTstatement), the database can parse the statement before the values for thevariables are given.

This sample program selects customers from a state that the user specifies.

Page 130: SQR User's Guide

Dynamic SQL and Error Checking SQR 4.0

116 SQR User's Guide

Program ex16a.sqr

begin-program do list_customers_for_stateend-program

begin-procedure list_customers_for_stateinput $state maxlen=2 type=char 'Enter state abbreviation'let $state = upper($state)begin-selectname (,1) position (+1)from customerswhere state = $stateend-selectend-procedure ! list_customers_for_state

Note the use of the $state variable in the SELECT paragraph. When youuse a variable in a SQL statement in SQR, the SQL statement sent to thedatabase contains that variable. SQR "binds" the variable before the SQL isexecuted. In many cases, the database only needs to parse the SQLstatement once. The only thing that changes between executions of theSELECT statement is the value of the variable. This is the most commonexample of varying a SELECT statement.

In this program, the INPUT command prompts the user to enter the valueof state. The arguments MAXLEN and TYPE check the input, ensuringthat the user enters a string of no more than two characters. If the entry isincorrect, INPUT reprompts.

The program converts the contents of the $state variable to uppercase,which allows the user to input the state without worrying about the case.In the example, state is uppercase in the database. The example shows theLET command used with the SQR upper function.

You could let the SQL perform the conversion to uppercase. You would doso by using "where state = upper($state)" if you are using Oracle orSYBASE or by using "where state = ucase($state)" if you are using anotherdatabase. However, SQR allows you to write database-independent codeby moving the use of such SQL extensions to the SQR code.

When you run this program, you must specify one of the states included inthe sample data for the program to return any records. At the prompt,enter IN, MI, NH, NJ, NM, NY, or OH. If you enter NY (the state wheremost of the customers in the sample data reside), SQR will generate theoutput shown below.

Page 131: SQR User's Guide

SQR 4.0 Dynamic SQL and Error Checking

SQR User's Guide 117

Output for ex16a.sqr

Alfred E Newman & CompanyEliot RichardsHarriet BaileyKate's Out of Date Dress ShopCorks and Bottles, Inc.

Dynamic SQL

You may find the restriction against using variables where only literals areallowed too limiting in some cases. In the following example, the orderingof the records is changed based on the user's selection. The program runsthe SELECT twice. The first time, the first column is called name and thesecond column is called city, and the program sorts the records by namewith a secondary sort by city. The second time, the first column is the cityand the second is name, and the program sorts by city with a secondary sortby name. The first SELECT statement will therefore be:

select name, cityfrom customersorder by name, city

The second SELECT statement will be:

select city, namefrom customersorder by city, name

As you can see, the statements are different. SQR actually constructs thestatement each time before executing it. This technique is called dynamicSQL. It is illustrated in the following example. To take full advantage ofthe error-handling procedure, run it with the command-line flag -CB.

Page 132: SQR User's Guide

Dynamic SQL and Error Checking SQR 4.0

118 SQR User's Guide

Program ex16b.sqr

begin-program let $col1 = 'name' let $col2 = 'city' let #pos = 32 do list_customers_for_state position (+1) let $col1 = 'city' let $col2 = 'name' let #pos = 18 do list_customers_for_stateend-program

begin-procedure give_warning display 'Database error occurred' display $sql-errorend-procedure ! give_warning

begin-procedure list_customers_for_state let $my_order = $col1 || ',' || $col2begin-select on-error=give_warning[$col1] &column1=char (,1)[$col2] &column2=char (,#pos) position (+1)from customersorder by [$my_order]end-selectend-procedure ! list_customers_for_state

When you use variables in a SQL statement in SQR to replace more thanliterals, you make them dynamic variables by enclosing them in squarebrackets. For example, when you use the dynamic variable [$my_order] inthe ORDER BY clause of the SELECT statement, SQR will place the textfrom the variable $my_order in that statement. Each time the statement isexecuted, if the text changes, a new statement is compiled and executed.

Other dynamic variables used are [$col1] and [$col2]. They substitute thenames of the columns in the SELECT statement. The variables &column1and &column2 are column variables.

You can use dynamic variables to produce reports like this one. Note thatthe data in the first half of the report is sorted differently than the data inthe second half.

Note the error-handling procedure give_warning. It is discussed below in"SQL Error Checking."

Page 133: SQR User's Guide

SQR 4.0 Dynamic SQL and Error Checking

SQR User's Guide 119

Output for ex16b .sqr

Alfred E Newman & Company New YorkClair Butterfield TeaneckCorks and Bottles, Inc. New YorkEliot Richards QueensGregory Stonehaven EverretsvilleHarold Alexander Fink DavenportHarriet Bailey MamaroneckHarry's Landmark Diner MiningvilleIsaiah J Schwartz and Company ZanesvilleJerry's Junkyard Specialties FroglineJoe Smith and Company Big FallsKate's Out of Date Dress Shop New YorkQuentin Fields ClevelandSam Johnson Bell Harbor

Bell Harbor Sam JohnsonBig Falls Joe Smith and CompanyCleveland Quentin FieldsDavenport Harold Alexander FinkEverretsville Gregory StonehavenFrogline Jerry's Junkyard SpecialtiesMamaroneck Harriet BaileyMiningville Harry's Landmark DinerNew York Alfred E Newman & CompanyNew York Corks and Bottles, Inc.New York Kate's Out of Date Dress ShopQueens Eliot RichardsTeaneck Clair ButterfieldZanesville Isaiah J Schwartz and Company

SQL Error Checking

SQR checks and reports database errors for SQL statements. When an SQRprogram is compiled, SQR checks the syntax of the SELECT, UPDATE,INSERT, and DELETE SQL statements in your program. Any SQL syntaxerror will be detected and reported at compile time, before the execution ofthe report begins.

When you use dynamic SQL, SQR cannot check the syntax until run time.In that case, the content of the dynamic variable is used to construct theSQL statement, which can allow syntax errors to occur in run time. Errorscould occur if the dynamic variables selected or used in a WHERE orORDER BY clause were incorrect.

SQR will trap any run-time error, report the error, and abort the program.If you want to change this default behavior, use the ON-ERROR option ofthe BEGIN-SELECT or BEGIN-SQL paragraphs.

Page 134: SQR User's Guide

Dynamic SQL and Error Checking SQR 4.0

120 SQR User's Guide

begin-select on-error=give_warning[$col1] &column1=char (,1)[$col2] &column2=char (,#pos) position (+1)from customersorder by [$my_order]end-select

In the above example, if a database error occurs, SQR will invoke aprocedure called give_warning instead of reporting the problem andaborting. Write this procedure as follows:

begin-procedure give_warning display 'Database error occurred' display $sql-errorend-procedure ! give_warning

This procedure displays the error message but does not abort the executionof the program. Instead, execution would continue at the statementimmediately following the SQL or SELECT paragraph. Note the use of thevariable $sql-error. This is a special SQR reserved variable. It contains theerror message text from the database and is automatically set by SQR aftera database error occurs.

SQR has a number of reserved, or predefined, variables, and they are veryuseful. For example, the variable $sqr-program has the name of theprogram that is running. The variable $username has the user name thatwas used to log on to the database. The variable #page-count has the pagenumber for the current page.

For a complete list of reserved variables, see the table "SQR ReservedVariables" in the SQR Language Reference.

SQL and Substitution Variables

SQR uses the value of this substitution variable to complete the SELECTstatement at compile time. Because the SELECT statement is complete atcompile time, SQR can check its syntax before execution begins. From thispoint on, the value of {my_order} cannot change and the SQL statement isconsidered static.

In the following program, the ASK command in the SETUP sectionprompts the user at compile time. The value that the user enters is placedin a special kind of variable called a substitution variable. This variable canbe used to substitute any command, argument, or part of a SQL statementat compile time. This example is less common, but it demonstrates thedifference between compile-time and run-time substitutions.

Page 135: SQR User's Guide

SQR 4.0 Dynamic SQL and Error Checking

SQR User's Guide 121

Program ex16c.sqr

begin-setup ask my_order 'Enter the column name to sort by (name or city)'end-setup

begin-program do list_customers_for_stateend-program

begin-procedure give_warning display 'Database error occurred' display $sql-errorend-procedure ! give_warning

begin-procedure list_customers_for_statebegin-select on-error=give_warningname (,1)city (,32) position (+1)from customersorder by {my_order}end-selectend-procedure ! list_customers_for_state

In this case, the ASK command prompts the user for the value of thesubstitution variable {my_order}, which will be used to sort the output. Ifthe argument is passed on the command line, there will be no prompt.When you run this program, enter name, city , or both (in either order andseparated by a comma). The program will produce a report sortedaccordingly.

The ASK command can only be used in the SETUP section. ASKcommands are always performed at compile time before programexecution begins. Therefore, all ASK commands are performed before anyINPUT command is performed.

INPUT is more flexible than ASK. You can use INPUT inside loops. Youcan validate the length and type of data input and reprompt if it is notvalid. We have seen an example of reprompting in the section "UsingVariables in SQL," earlier in this chapter.

ASK can be more powerful. Substitution variables set in an ASKcommand let you modify commands that are normally quite restrictive.The following code shows this technique.

Page 136: SQR User's Guide

Dynamic SQL and Error Checking SQR 4.0

122 SQR User's Guide

begin-setup ask hlines 'Number of lines for heading'end-setup

begin-program print 'Hello, World!!' (1,1)end-program

begin-heading {hlines} print 'Report Title' () centerend-heading

In this example, the substitution variable {hlines} defines the number oflines that the heading will occupy. The BEGIN-HEADING commandnormally expects a literal and does not allow a run-time variable. When asubstitution variable is used with this command, its value is modified atcompile time.

For further information on the ASK and INPUT commands, see Chapter25, "Compiling Programs and Using SQR Execute."

Summary• Dynamic variables are variables used in a SQL statement to replace

more than literals. They are enclosed in square brackets.

• You can customize SQR's run-time error handling.

• SQR has a number of reserved variables. For a full listing, see the table"SQR Reserved Variables" in the SQR Language Reference.

• Substitution variables entered by the ASK command can be used inplace of any command, argument, or SQL statement at compile time.They are enclosed in curly braces.

In the next chapter, you will learn more about SQR procedures.

Page 137: SQR User's Guide

SQR User's Guide 123

17 Procedures, Argument Passing, and

Local Variables

This chapter examines SQR procedures. It explains how to passparameters and illustrates the difference between global and localprocedures. In particular, it shows how to reference global variables fromwithin a local procedure.

The sample code in this chapter shows a procedure that spells out anumber and a program for printing checks that uses this procedure. Whenprinting checks, you normally need to spell out the dollar amount, asshown below.

In the sample program, it is assumed that the checks are preprinted andthat our program only has to print such items as the date, name, andamount.

Procedures

SQR procedures that contain variables which are visible throughout theprogram are called global procedures. These procedures can also directlyreference any program variable.

Page 138: SQR User's Guide

Procedures, Argument Passing, and Local Variables SQR 4.0

124 SQR User's Guide

In contrast, procedures that take arguments, such as the spell_numberprocedure in this chapter's check-printing sample code, are localprocedures. In SQR, any procedure that takes arguments is automaticallyconsidered local. Variables introduced in a local procedure are onlyreadable inside the procedure. This useful feature avoids name collisions.In the sample program, the spell_number procedure is placed in an includefile because other reports may also want to use it.

Local Variables

When you create library procedures that may be used in many programs,make them local. Then, if a program has a variable with the same name asa variable used in the procedure, there will not be a collision. SQR treatsthe two variables as separate.

We recommend that you declare a procedure as local even if it does nottake any arguments. Simply place the keyword LOCAL after theprocedure name in the BEGIN-PROCEDURE command.

To reference a global variable from a local procedure, insert an underscorebetween the prefix character (#, $, or &) and the variable name. Note alsothat the same technique is used to reference reserved variables such as#current-line. These variables are always global. You can reference#_current-line from a local procedure.

SQR supports recursive procedure calls, but it maintains only one copy of alocal variable. A procedure will not allocate new instances of the localvariables on a stack, as C or Pascal would.

Argument Passing

Procedure arguments are treated as local variables. Arguments may beeither numeric, date, or text variables or strings. If an argument ispreceded with a colon, its value will be passed back to the callingprocedure.

In the example below, spell_number takes two arguments. The firstargument is the check amount. This argument is a number, and theprogram passes it to the procedure. There is no need for the procedure topass it back.

Page 139: SQR User's Guide

SQR 4.0 Procedures, Argument Passing, and Local Variables

SQR User's Guide 125

The second argument is the result that the procedure passes back to thecalling program. We precede this variable with a colon, which means thatthe value of this argument will be copied back at the end of the procedure.The colon is only used when the argument is declared in theBEGIN-PROCEDURE command.

Look at the following code. It's not a complete program. It's thespell_number procedure, which is stored in the file spell.inc. The check-printing program will include this code using an #INCLUDE command.

File spell .inc

begin-procedure spell_number(#num,:$str) let $str = '' ! break the number to it's 3-digit parts let #trillions = floor(#num / 1000000000000) let #billions = mod(floor(#num / 1000000000),1000) let #millions = mod(floor(#num / 1000000),1000) let #thousands = mod(floor(#num / 1000),1000) let #ones = mod(floor(#num),1000) ! spell each 3-digit part do spell_3digit(#trillions,'trillion',$str) do spell_3digit(#billions,'billion',$str) do spell_3digit(#millions,'million',$str) do spell_3digit(#thousands,'thousand',$str) do spell_3digit(#ones,'',$str)end-procedure ! spell_number

begin-procedure spell_3digit(#num,$part_name,:$str) let #hundreds = floor(#num / 100) let #rest = mod(#num,100) if #hundreds do spell_digit(#hundreds,$str) concat 'hundred ' with $str end-if if #rest do spell_2digit(#rest,$str) end-if if #hundreds or #rest if $part_name != '' concat $part_name with $str concat ' ' with $str end-if end-ifend-procedure ! spell_3digit

Program continues on the following page.

Page 140: SQR User's Guide

Procedures, Argument Passing, and Local Variables SQR 4.0

126 SQR User's Guide

File spell .inc (continued)

begin-procedure spell_2digit(#num,:$str) let #tens = floor(#num / 10) let #ones = mod(#num,10) if #num < 20 and #num > 9 evaluate #num when = 10 concat 'ten ' with $str break when = 11 concat 'eleven ' with $str break when = 12 concat 'twelve ' with $str break when = 13 concat 'thirteen ' with $str break when = 14 concat 'fourteen ' with $str break when = 15 concat 'fifteen ' with $str break when = 16 concat 'sixteen ' with $str break when = 17 concat 'seventeen ' with $str break when = 18 concat 'eighteen ' with $str break when = 19 concat 'nineteen ' with $str break end-evaluate else evaluate #tens when = 2 concat 'twenty' with $str break when = 3 concat 'thirty' with $str break when = 4 concat 'forty' with $str break

Program continues on the following page.

Page 141: SQR User's Guide

SQR 4.0 Procedures, Argument Passing, and Local Variables

SQR User's Guide 127

File spell .inc (continued)

when = 5 concat 'fifty' with $str break when = 6 concat 'sixty' with $str break when = 7 concat 'seventy' with $str break when = 8 concat 'eighty' with $str break when = 9 concat 'ninety' with $str break end-evaluate if #num > 20 if #ones concat '-' with $str else concat ' ' with $str end-if end-if if #ones do spell_digit(#ones,$str) end-if end-ifend-procedure ! spell_2digit

begin-procedure spell_digit(#num,:$str) evaluate #num when = 1 concat 'one ' with $str break when = 2 concat 'two ' with $str break when = 3 concat 'three ' with $str break when = 4 concat 'four ' with $str break when = 5 concat 'five ' with $str break when = 6 concat 'six ' with $str break

Program continues on the following page.

Page 142: SQR User's Guide

Procedures, Argument Passing, and Local Variables SQR 4.0

128 SQR User's Guide

File spell .inc (continued)

when = 7 concat 'seven ' with $str break when = 8 concat 'eight ' with $str break when = 9 concat 'nine ' with $str break end-evaluateend-procedure ! spell_digit

The result argument is reset in the procedure, because the program beginswith an empty string and keeps concatenating the parts of the number to it.The program only supports numbers up to 999 trillion.

The number is broken into its three-digit parts: trillions, billions, millions,thousands, and ones. Another procedure spells out the three-digitnumbers such as "one hundred twelve." Note that the word and is insertedonly between dollars and cents, but not between three-digit parts. Thisformat is common for check printing in dollars.

Note the use of math functions such as floor and mod. SQR has a rich setof functions that can be used in expressions. These functions are listed anddescribed under the LET command in the SQR Language Reference.

The series of EVALUATE commands in the number-spelling proceduresare used to correlate the numbers stored in the variables with the stringsused to spell them out.

This is the full program that prints the checks.

Program ex17a.sqr

#include 'spell.inc'

begin-setup declare-layout default end-declareend-setup

Program continues on the following page.

Page 143: SQR User's Guide

SQR 4.0 Procedures, Argument Passing, and Local Variables

SQR User's Guide 129

Program ex17a.sqr (continued)

begin-program do mainend-program

begin-procedure main alter-printer font=5 point-size=15begin-selectname &namesum(d.price * c.quantity) * 0.10 &refund do print_check(&refund)from customers a, orders b, ordlines c, products d where a.cust_num = b.cust_num and b.order_num = c.order_num and c.product_code = d.product_code group by name having sum(d.price * c.quantity) * 0.10 >= 0.01end-selectend-procedure ! main

begin-procedure print_check(#amount) print $_current-date (3,45) edit 'DD-Mon-YYYY' print &_name (8,12) move #amount to $display_amt 9,999,990.99 ! enclose number with asterisks for security let $display_amt = '**' || ltrim($display_amt,' ') || '**' print $display_amt (8,58) if #amount < 1.00 let $spelled_amount = 'Zero dollars ' else do spell_number(#amount,$spelled_amount) let #len = length($spelled_amount) ! Change the first letter to uppercase let $spelled_amount = upper(substr($spelled_amount,1,1)) || substr($spelled_amount,2,#len - 1) concat 'dollars ' with $spelled_amount end-if let #cents = round(mod(#amount,1) * 100, 0) let $cents_amount = 'and ' || edit(#cents,'00') || ' cents' concat $cents_amount with $spelled_amount print $spelled_amount (12,12) print 'Rebate' (16,12) print ' ' (20) next-listing need=20end-procedure ! print_check

The main procedure starts by setting the font to 15-point Times Roman.The SELECT paragraph is a join of several tables. (A join is created whenyou select data from more than one database table in the same SELECTparagraph.) The customers table has the customer's name. The programjoins it with the orders and ordlines tables to get the customer's order details.It also joins with the products table for the price.

Page 144: SQR User's Guide

Procedures, Argument Passing, and Local Variables SQR 4.0

130 SQR User's Guide

The following expression adds up all of the customer's purchases andcalculates a 10 percent rebate:

sum(d.price * c.quantity) * 0.10

The statement groups the records by the customer name, one check percustomer. This is done with the clause:

group by namehaving sum(d.price * c.quantity) * 0.10 >= 0.01

The HAVING clause eliminates checks for less than 1 cent.

The procedure print_check is a local procedure. Note the way it referencesthe date and customer name with &_current-date and &_name, respectively.

Summary• Variables in global procedures are visible throughout the program.

• Variables in local procedures are visible only within the procedure.

• To reference a global variable from a local procedure, place anunderscore between the prefix character #, $, or & and the variablename.

• To pass an argument back to its calling procedure, preface it with acolon.

The next chapter shows how to create multiple reports simultaneouslyfrom one program.

Page 145: SQR User's Guide

SQR User's Guide 131

18 Multiple Reports

This chapter shows you how to create multiple reports from one program.This powerful feature can save a significant amount of processing time.You can create multiple reports based on common data, selecting thedatabase records only once and creating different reports simultaneously.

The alternative—writing separate programs for the different reports—would require you to perform a separate database query for each report.Repeated queries are costly because database operations are often the mostresource-consuming or time-consuming part of creating a report.

In the following example, you will see how SQR allows you to writemultiple reports with different layouts and different heading and footingsections. The sample program will print three reports—the labels fromChapter 9, the form letter from Chapter 10, and the listing report fromChapter 3. All three reports are based on exactly the same data.

Program ex18a.sqr

#define MAX_LABEL_LINES 10#define LINES_BETWEEN_LABELS 3

begin-setup declare-layout labels paper-size=(10,11) left-margin=0.33 end-declare declare-layout form_letter end-declare declare-layout listing end-declare declare-report labels layout=labels end-declare declare-report form_letter layout=form_letter end-declare declare-report listing layout=listing end-declareend-setup

Program continues on the following page.

Page 146: SQR User's Guide

Multiple Reports SQR 4.0

132 SQR User's Guide

Program ex18a.sqr (continued)

begin-program do mainend-program

begin-procedure main do init_mailing_labelsbegin-selectnameaddr1addr2citystatezip move &zip to $zip xxxxx-xxxxphone do print_label do print_letter do print_listingfrom customersend-select do end_mailing_labelsend-procedure ! main

begin-procedure init_mailing_labels let #label_count = 0 let #label_lines = 0 use-report labels columns 1 29 57 ! enable columns alter-printer font=5 point-size=10end-procedure ! init_mailing_labels

begin-procedure print_label use-report labels print &name (1,1,30) print &addr1 (2,1,30) let $last_line = &city || ', ' || &state || ' ' || $zip print $last_line (3,1,30) next-column at-end=newline add 1 to #label_count if #current-column = 1 add 1 to #label_lines if #label_lines = {MAX_LABEL_LINES} new-page let #label_lines = 0 else next-listing no-advance skiplines={LINES_BETWEEN_LABELS} end-if end-ifend-procedure ! print_label

Program continues on the following page.

Page 147: SQR User's Guide

SQR 4.0 Multiple Reports

SQR User's Guide 133

Program ex18a.sqr (continued)

begin-procedure end_mailing_labels use-report labels use-column 0 ! disable columns new-page print 'Labels printed on ' (,1) print $current-date () print 'Total labels printed = ' (+1,1) print #label_count () edit 9,999,999end-procedure ! end_mailing_labels

begin-procedure print_letteruse-report form_letterbegin-document (1,1)&name&addr1&addr2@city_state_zip.b.b $current-dateDear Sir or Madam:.b Thank you for your recent purchases from ACME Inc. We would like totell you about our limited time offer. During this month, our entireinventory is marked down by 25%. Yes, you can buy your favoritemerchandiseand save too. To place an order simply dial 800-555-ACME. Delivery is free too, sodon't wait..b.b Sincerely, Clark Axelotle ACME Inc.end-documentposition () @city_state_zipprint &city ()print ', ' ()print &state ()print ' ' ()move &zip to $zip xxxxx-xxxxprint $zip ()new-pageend-procedure ! print_letter

Program continues on the following page.

Page 148: SQR User's Guide

Multiple Reports SQR 4.0

134 SQR User's Guide

Program ex18a.sqr (continued)

begin-heading 4 for-reports=(listing)print 'Customer Listing' (1) center print 'Name' (3,1) print 'City' (,32) print 'State' (,49) print 'Phone' (,55)end-heading

begin-footing 1 for-reports=(listing) ! Print "Page n of m" in the footing page-number (1,1) 'Page ' last-page () ' of 'end-footing

begin-procedure print_listing use-report listing print &name (,1) print &city (,32) print &state (,49) print &phone (,55) position (+1)end-procedure ! print_listing

The SETUP section defines three layouts and three different reports thatuse these layouts. The labels report requires a layout that is different fromthe default. The other two reports use a layout that is identical to thedefault layout. It would be possible to save the last layout declaration anduse the form-letter layout for the listing. However, unless there is a logicalreason why the two layouts should be the same, it is better to keep separatelayouts. The name of the layout indicates which report uses it.

The main procedure performs the SELECT. Note that it is only performedonce and includes all the columns for all the reports. The phone column isonly used in the listing report and the addr2 column is only used in theform-letter report. The other columns are used in more than one report.

For each record selected, three procedures are executed. Each procedureprocesses one record for its corresponding report. The print_labelprocedure prints one label, print_letter prints one letter, and print_listingprints one line into the listing report. Each procedure begins by setting theSQR printing context to its corresponding report. SQR sets the printingcontext with the USE-REPORT command.

Page 149: SQR User's Guide

SQR 4.0 Multiple Reports

SQR User's Guide 135

SQR allows you to define HEADING and FOOTING sections for eachreport. This example only defines the heading and footing for the listingreport, because the other two reports do not use them. TheFOR-REPORTS option of the BEGIN-HEADING and BEGIN-FOOTINGcommands specifies the report name. The parentheses are required. Notethat the USE-REPORT command is not needed in the heading or thefooting. The report is implied by the FOR-REPORTS option.

Most of the code for ex18a.sqr is taken from ex9a.sqr, ex10a.sqr, andex3a.sqr. Because this program creates output with proportional fonts, youmust run it with the -KEEP or -PRINTER:xx command-line flags. (If youare running the report with SQR Workbench for Windows, you may omit-KEEP. See Chapter 9 for more information on running reports withproportional fonts.)

When you run ex18a.sqr, you get three output files that match the outputfiles for ex9a, ex10a, and ex3a, respectively. These output files will have thenames ex18a.lis (labels), ex18a.l01 (form letter), and ex18a.l02 (customerlisting). If you specify -KEEP, the output files will be named ex18a.spf,ex18a.s01, and ex18a.s02, respectively.

If you are running Workbench for Windows, the Viewer window will openautomatically after you run the programs, but only the first output file,ex18a.spf, will be displayed. You can view the other output files byselecting File→→Open.

Summary• Writing multiple reports simultaneously with one program reduces

database queries.

• You can define separate reports in the SETUP section.

• USE-REPORT sets the printing context for each report.

• The FOR-REPORTS option of BEGIN-HEADING andBEGIN-FOOTING defines headings and footings for individualreports.

The next chapter explains how to integrate SQL statements other thanSELECT with SQR.

Page 150: SQR User's Guide
Page 151: SQR User's Guide

SQR User's Guide 137

19 Using DML and DDL

SQL Statements

Although SELECT may be the most common SQL statement, you can alsoperform other SQL commands in SQR. Here are a few examples:

• If the program prints important documents such as checks, tickets, orinvoices, you may need to update the database to indicate that thedocument was printed. This is easily performed in SQR with a SQLUPDATE statement.

• You can use SQR to load data into the database. SQR can read andwrite external files and construct records. SQR can also insert theserecords into the database using a SQL INSERT statement.

• If you need to hold intermediate results in a temporary database table,you can create two SQL paragraphs in your SQR program (CREATETABLE and DROP TABLE) to create this table at the beginning of theprogram and drop the table at the end.

These are only a few examples. SQR can perform any SQL statement, andthis feature is used often.

Using BEGIN-SQL

To perform a SQL statement other than a SELECT statement you must usethe BEGIN-SQL paragraph.

The following example loads data from an external file into the database.It demonstrates two important features of SQR—handling external filesand performing database inserts. This program loads the tab-delimited filecreated by the program ex11a.sqr.

Page 152: SQR User's Guide

Using DML and DDL SQL Statements SQR 4.0

138 SQR User's Guide

Program ex19a.sqr

begin-setup begin-sql on-error=skip ! table may already exist create table customers_ext ( cust_num int not null, name varchar (30), addr1 varchar (30), addr2 varchar (30), city varchar (16), state varchar (2), zip varchar (10), phone varchar (10), tot int ) end-sqlend-setup

begin-program do mainend-program

begin-procedure main

#if {sqr-database} = 'Sybase' begin-sql begin transaction end-sql#endif encode '<009>' into $sep open 'ex11a.lis' as 1 for-reading record=160:vary read 1 into $rec:160 ! skip the first record, column headings while 1 read 1 into $rec:160 if #end-file break end-if unstring $rec by $sep into $cust_num $name $addr1 $addr2 $city $state $zip $phone $tot move $cust_num to #cust_num move $tot to #tot begin-sql insert into customers_ext (cust_num, name, addr1, addr2, city, state, zip, phone, tot) values (#cust_num, $name, $addr1, $addr2, $city, $state, $zip, $phone, #tot) end-sql end-while

Program continues on the following page.

Page 153: SQR User's Guide

SQR 4.0 Using DML and DDL SQL Statements

SQR User's Guide 139

Program ex19a.sqr (continued)

#if {sqr-database} = 'Sybase' begin-sql commit transaction end-sql#else#if {sqr-database} <> 'Informix' begin-sql commit end-sql#endif#endif close 1end-procedure ! main

The program starts by creating the table customers_ext. If the table alreadyexists you will get an error message. To ignore this error message, use theON-ERROR=SKIP option. See Chapter 16, Dynamic SQL and ErrorChecking," for more information on error handling.

The program reads the records from the file and inserts each record intothe database by using an INSERT statement inside a BEGIN-SQLparagraph. The input file format is one record per line, with each fieldseparated by the separator character. When the end of the file isencountered (if #end-file), the program branches out of the loop. Notethat #end-file is an SQR reserved variable. For a complete listing ofreserved variables, see the SQR Language Reference.

The last step is to commit the changes to the database and close the file.The changes are committed with a SQL COMMIT statement inside aBEGIN-SQL paragraph. Alternatively, you can use the SQR COMMITcommand. For Oracle databases, we recommend you use the SQRCOMMIT.

Note that the code may be database-specific. If you are using Informix, forexample, and your database was created with transaction logging, youmust add a BEGIN WORK and a COMMIT WORK, much like the SYBASEexample of BEGIN TRANSACTION and COMMIT TRANSACTION.

Page 154: SQR User's Guide

Using DML and DDL SQL Statements SQR 4.0

140 SQR User's Guide

Summary• A BEGIN-SQL paragraph can be used to perform SQL statements

other than SELECT.

• To insert database records, use SQL commands such as INSERT andCOMMIT inside the BEGIN-SQL paragraph. For Oracle databases, usethe SQR COMMIT.

The next chapter explains how to work with dates in SQR.

Page 155: SQR User's Guide

SQR User's Guide 141

20 Working with Dates

This chapter explains how to handle dates with SQR. You will learn thebest way to handle dates in a program.

SQR has powerful capabilities in date arithmetic, editing, andmanipulation. A date can be represented as a character string or in aninternal format using the SQR date datatype.

The date datatype allows you to store dates in the range of January 1, 4712B.C. to December 31, 9999 A.D. It also stores the time of day with theprecision of a microsecond. The internal date representation always keepsthe year as a four-digit value. We strongly recommend that you alwayskeep dates with four-digit year values (and not truncate to two digits) toavoid date problems at the turn of the century.

Date values can be obtained in one of five ways:

• By selecting a date column from the database.

• By using INPUT to get a date from the user.

• By referencing or printing the reserved variable $current-date.

• As a result of an SQR date function: dateadd, datediff, datenow, orstrdodate.

• By declaring a date variable using the DECLARE-VARIABLEcommand.

For most applications, it is not necessary to declare date variables. Datevariables will be discussed later in this chapter.

Date Arithmetic

Many applications require date calculations. You may need to add orsubtract a number of days from a given date, subtract one date fromanother to find a time difference, or compare dates to find if one date islater, earlier, or the same as another date. SQR allows you to easilyperform these calculations in your program.

Page 156: SQR User's Guide

Working with Dates SQR 4.0

142 SQR User's Guide

Many databases allow you to perform date calculations in SQL, but thatcan be awkward if you are trying to write portable code, because thesyntax varies between databases. Instead, perform those calculations inSQR—your programs will be portable, because they won't rely on aparticular SQL syntax.

The dateadd function adds or subtracts a number of specified time unitsfrom a given date. The datediff function returns the difference betweentwo specified dates in the time units you specify—years, quarters, months,weeks, days, hours, minutes, or seconds. Fractions are allowed—you canadd 2.5 days to a given date. Conversion between time units is alsoallowed—you can add, subtract, or compare dates using days and state thedifference using weeks.

The datenow function returns the current local date and time. In addition,SQR provides a reserved date variable, $current-date, which isautomatically initialized with the local date and time at the beginning ofthe program.

You can compare dates by using the usual operators (< , =, or >) in anexpression. The datetostr function converts a date to a string. Thestrtodate function converts a string to a date.

The following code uses functions to add 30 days to the invoice date andcompare it to the current date:

begin-selectorder_num (,1)invoice_date if dateadd(&invoice_date,'day',30) < datenow() print 'Past Due Order' (,12) else print 'Current Order' (,12) end-if position (+1)end-select

In this example, the functions dateadd and datenow are used to comparedates. The function dateadd adds 30 days to the invoice date(&invoice_date). The resulting date is then compared with the currentdate, which is returned by datenow. If the invoice is older than 30 days,the program prints the string "Past Due Order." If the invoice is 30 daysold or less, the program prints the string "Current Order."

Page 157: SQR User's Guide

SQR 4.0 Working with Dates

SQR User's Guide 143

To subtract a given number of days from a date, use the dateadd functionwith a negative argument. This technique is demonstrated in the nextexample. In this example, the IF condition compares the invoice date withthe date of 30 days before today. The condition is equivalent to that of theprevious example.

if &invoice_date < dateadd(datenow(),'day',-30)

This condition can also be written as follows using the datediff function.Note that the comparison is now a simple numeric comparison, not a datecomparison:

if datediff(datenow(),&invoice_date,'day') > 30

All three IF statements are equivalent, and they demonstrate the flexibilityprovided by these functions.

Here is another technique for comparing dates:

begin-selectorder_date if &order_date > strtodate('3/1/1996','dd/mm/yyyy') print 'Current Order' () else print 'Past Due Order' () end-iffrom ordersend-select

The IF statement has a date column on the left side and the strtodatefunction on the right side. The strtodate function returns a date type,which is compared with the column &order_date. When the order date islater than January 3, 1996, the condition is satisfied. If the date includes thetime of day, the comparison will be satisfied for orders of January 3, 1996with a time of day greater than 00:00.

In the next example, the date is truncated to remove the time-of-dayportion of a date:

if strtodate(datetostr(&order_date,'dd/mm/yyyy'),'dd/mm/yyyy') > strtodate('3/1/1996','dd/mm/yyyy')

In this example, the datetostr function converts the order date to a stringthat only stores the day, month, and year. The strtodate function thenconverts this value back into a date. With these two conversions, the time-of-day portion of the order date is omitted. Now when it is compared withJanuary 3, 1996, only dates that are of January 4 or later will satisfy thecondition.

Page 158: SQR User's Guide

Working with Dates SQR 4.0

144 SQR User's Guide

Date Formats

SQR allows you to specify date constants and date values in a specialformat that is recognized without the use of an edit mask. This is calledthe literal date format. For example, you can use a value in this format inthe strtodate function without the use of an edit mask. This format has theadvantage of being independent of any specific database or languagepreference.

The literal date format is SYYYYMMDD[HH24[MI[SS[NNNNNN]]]]. Thefirst S in this format represents an optional minus sign. If preceded with aminus sign, the string represents a date B.C. The following digits representyear, month, day, hours, minutes, seconds, and microseconds.

ØØ Note The literal date format assumes a 24-hour clock.

You may omit one or more time elements from the right part of the format.A default is assumed for the missing elements. Here are some examples:

let $a = strtodate('19960409')let $a = strtodate('19960409152000')

The first LET statement assigns the date of April 9, 1996 to the variable $a.The time portion defaults to 00:00. The second LET statement assigns 3:20in the afternoon of April 9, 1996 to $a. The respective outputs (whenprinted with the edit mask 'DD-MON-YYYY HH:MI AM') will be:

09-APR-1996 12:00 AM09-APR-1996 03:20 PM

You can also specify a date format with the environment variableSQR_DB_DATE_FORMAT. This format can be specified as anenvironment variable or specified in the SQR.INI file. For moreinformation on the SQR.INI file, see the chapter "SQR.INI" in the SQRLanguage Reference.

String to Date Conversions

If you convert a string variable or constant to a date variable withoutspecifying an edit mask that identifies the format of the string, SQR willapply a date format. This implicit conversion will take place with thefollowing commands:

Page 159: SQR User's Guide

SQR 4.0 Working with Dates

SQR User's Guide 145

• MOVE

• The strtodate function

• The commands DISPLAY, PRINT, or SHOW, when used to output astring variable as a date.

SQR will attempt to apply date formats in the following order:

1. The format specified in SQR_DB_DATE_FORMAT

2. The database-dependent format

3. The literal date format SYYYYMMDD[HH24[MI[SS[NNNNNN]]]].

Date to String Conversions

If you convert a date variable to a string without specifying an edit mask,SQR will apply a date format. This implicit conversion will take place withthe following commands:

• MOVE

• The datetostr function

• The commands DISPLAY, PRINT, or SHOW, when used to output adate variable

SQR will attempt to apply date formats in the following order:

1. The format specified in SQR_DB_DATE_FORMAT

2. The database-dependent format

Database-dependent formats are listed in the table "Default DatabaseFormats" in the SQR Language Reference.

Using Dates with the INPUT Command

The INPUT command also supports dates. A date can be loaded into adate or string variable. For string variables, use the TYPE=DATE qualifier.A format for the date should be specified. Here is an example:

input $start_date 'Enter starting date' type=dateformat='dd/mm/yyyy'

Page 160: SQR User's Guide

Working with Dates SQR 4.0

146 SQR User's Guide

In this example, the user is prompted with "Enter starting date:" (the colonis automatically added). The user then types in the value, which isvalidated as a date using the "dd/mm/yyyy" format. The value is loadedinto the variable $start_date.

Date Edit Masks

When you print dates, you can format them with an edit mask. Forexample:

print &order_date () edit 'Month dd, YYYY'

This command will print the order date in the specified format. The nameof the order date month will be printed followed by the day of the month, acomma, and four-digit year. SQR provides a rich set of date edit masks.Please refer to the table "Date Edit Format Codes" in the SQR LanguageReference for a complete listing.

If the value of the date value being edited is March 14, 1996 at 9:35 in themorning, the edit masks produce the following results:

Edit Mask Result Descriptiondd/mm/yyyy 14/03/1996

DD-MON-YYYY 14-MAR-1996

'Month dd, YYYY.' March 14, 1996. Edit mask containing blank spacemust be enclosed in single quotes.

MONTH-YYYY MARCH-1996 Name of the month in uppercasefollowed by four-digit year

HH:MI 09:35

'HH:MI AM' 09:35 AM Meridian indicators. Edit maskcontaining blank space must beenclosed in single quotes.

YYYYMMDD 19960314

DD.MM.YY 14.03.96

Mon Mar Abbreviated name of the month

Day Thursday Day of the week

DY THU Abbreviated name of day of theweek

Q 1 Quarter

Table 3. Sample Date Edit Masks

Page 161: SQR User's Guide

SQR 4.0 Working with Dates

SQR User's Guide 147

Edit Mask Result DescriptionWW 11 Week of the year

W 2 Week of the month

DDD 74 Day of the year

DD 14 Day of the month (1-31)

D 5 Day of the week (Sunday = 1)

Table 3. Sample Date Edit Masks (continued)

If the edit mask contains other text, it is also printed. For example:

print &order_date () edit 'As of Month dd, YYYY'

This command will print the string "As of March 14, 1996" if the order dateis March 14, 1996. Since the words "As of" are not recognized as date maskelements, they are simply printed.

A backslash forces the character that follows into the output. Thistechnique is useful when you want to print text that would otherwise berecognized as a date mask element. For example, a mask of "The \mo\nthis month" results in the output string of "The month is march". Without thebackslashes the output string would be "The march is march". The secondbackslash is needed because "n" is a valid date edit mask element.

In some cases, combining date edit mask elements may result in ambiguity.One example is the mask 'DDDD', which could be interpreted as variouscombinations of 'DDD' (day of year), 'DD' (day of month), and 'D' (day ofweek). To resolve such ambiguity, use a vertical bar as a delimiterbetween format elements. For example, 'DDD' followed by 'D' can bewritten as 'DDD|D'.

The masks MON, MONTH, DAY, DY, AM, PM, BC, AD, and RM are case-sensitive and follow the case of the mask entered. For example, if themonth is January, the mask Mon yields "Jan" and MON yields "JAN". Allother masks are case-insensitive and can be entered in either uppercase orlowercase.

In addition, national language support is provided for the followingmasks: MON, MONTH, DAY, DY, AM, PM, BC, and AD. See theALTER-LOCALE command or the chapter "SQR.INI" in the SQR LanguageReference for additional information.

Page 162: SQR User's Guide

Working with Dates SQR 4.0

148 SQR User's Guide

Declaring Date Variables

To hold date values in your program, use date variables. Like stringvariables, date variables are prefixed with a dollar sign ($). You mustexplicitly declare date variables using the DECLARE-VARIABLEcommand.

Date variables are useful for holding results of date calculations. Forexample:

begin-setup declare-variable date $c end-declareend-setup...let $c = strtodate('March 1, 1996 12:00','Month dd, yyyy hh:mi')print $c () edit 'dd/mm/yyyy'

In this example, $c is declared as a date variable. Later, it is assigned thevalue of noon on March 1, 1996. The variable $c is then printed with theedit mask 'dd/mm/yyyy', which yields 01/03/1996.

Date variables can be initialized with date literals as shown in thefollowing example:

begin-setup declare-variable date $c end-declareend-setup...let $c = '19960409152000'

The LET statement assigns 3:20 in the afternoon of April 9, 1996 to $c.

Summary• Obtain date values by selecting a date column from the database,

printing or referencing the reserved variable $current-date, or using anSQR date function such as dateadd, datediff, datenow, or strtodate.

• Perform date arithmetic and date comparison by using the datefunctions.

• The SQR literal date format isSYYYYMMDD[HH24[MI[SS[NNNNNN]]]]. For this format, a 24-hourclock is assumed.

Page 163: SQR User's Guide

SQR 4.0 Working with Dates

SQR User's Guide 149

• You can also specify a date format with the environment variableSQR_DB_DATE_FORMAT. This format can be specified as anenvironment variable or specified in the SQR.INI file.

• Declare date variables with the DECLARE-VARIABLE command.

The next chapter describes the SQR features for national language support.

Page 164: SQR User's Guide
Page 165: SQR User's Guide

SQR User's Guide 151

21 National Language Support

This chapter describes SQR features for national language support (NLS).This support is provided through the concept of locales. This chapterdescribes SQR locales and explains how to use them to write programs thatautomatically adapt to local preferences.

Locales

A locale is a set of local preferences for language, currency, and thepresentation of dates and numbers. For example, one locale may useEnglish, dollar currency, dates in "dd/mm/yy" format, numbers withcommas separating the thousands, and a period for the decimal place.

A locale contains default edit masks for number, money, and date. Theseedit masks are used when you specify the keywords NUMBER, MONEY,and DATE, respectively. These keywords can be specified in the INPUT,MOVE, DISPLAY, SHOW, and PRINT commands. Their use is discussedand demonstrated below.

A locale also contains settings for currency symbol, thousands separator,decimal separator, date separator, and time separator. A locale containssettings for N/A, AM, PM, BC, and AD in the language of the locale.

A locale contains a setting for names of the days of the week and names ofthe months in the language of the locale. It also contains settings for howto handle lower/upper case editing of these names.

These settings are described in detail in the reference section for theALTER-LOCALE command in the SQR Language Reference.

Available Locales

SQR provides predefined locales such as US-English, UK-English, German,French, and Spanish. You can easily define additional locales or modifyexisting locales by editing the SQR.INI file. For more information aboutthe SQR.INI file, refer to the chapter, "SQR.INI," in the SQR LanguageReference.

Page 166: SQR User's Guide

National Language Support SQR 4.0

152 SQR User's Guide

With the ALTER-LOCALE command, you can choose a locale—at thebeginning of your program or anywhere else. You can even have differentparts of your program use different locales.

You can select a locale with this command:

alter-locale locale = 'German'

The Default Locale

The SQR.INI file defines a default locale. Most or all of your programsmay use the same locale, and specifying the default locale in the SQR.INIfile will make it unnecessary to specify the locale in every program.

When you install SQR, the default locale is set to the reserved locale called"System." System is not a real locale. It defines the behavior of olderversions of SQR, before national language support was added. Thepreferences in the system locale are hard-coded in the product and cannotbe set or defined in the SQR.INI; however, 'System' settings can be alteredat run time using ALTER-LOCALE. The date preferences are dependenton the database you are using. Therefore, date format preferences in thesystem locale are different for every database you use with SQR.

Different sites may have a different locale as the default. For example, anoffice in Paris may use the "French" locale, and an office in London mayuse the "UK-English" locale. To adapt your program to any location, usethe default locale. Your program will then automatically respect the localpreferences, which are specified in the SQR.INI file of the machine onwhich it is run. For example, you may print the number 5120 using thefollowing command:

print #invoice_total () edit '9,999,999.99'

The setting of the default locale in the SQR.INI file will control the format.In London, the result may be 5,120.00, and in Paris it may be 5.120,00. Thedelimiters for thousands and the decimal—the comma and the period—will be switched automatically according to the preferences of the locale.

Page 167: SQR User's Guide

SQR 4.0 National Language Support

SQR User's Guide 153

ØØ Tip Changing the settings of the default locale may change the behavior ofexisting programs. For example, if you change the default locale to"French," programs that used to print dates in English may now print themin French. Be sure that you review and test existing programs whenmaking a change to the default locale.

Switching Locales

You can switch from one locale to another any number of times duringprogram execution. This technique is useful for writing reports that usemultiple currencies, or reports that have different sections for differentlocales.

To switch to another locale, use the ALTER-LOCALE command. Forexample, to switch to the Spanish locale:

alter-locale locale = 'Spanish'

From this point in the program, the locale will be Spanish.

Consider this example:

begin-procedure print_data_in_spanish ! Save the current locale let $old_locale = $sqr-locale ! Change the locale to "Spanish" alter-locale locale = 'Spanish' ! Print the data do print_data ! restore the locale to the previous setting alter-locale locale = $old_localeend-procedure

In this example, the locale is switched to Spanish and later restored to theprevious locale before it was switched. To do that, the locale setting beforeit is changed is read in the reserved variable $sqr-locale and stored in$old_locale. The value of $old_locale is then used in the ALTER-LOCALEcommand at the end of the procedure.

Page 168: SQR User's Guide

National Language Support SQR 4.0

154 SQR User's Guide

Modifying Locale Preferences

With the ALTER-LOCALE command, you can modify any individualpreference in a locale. The ALTER-LOCALE command only affects thecurrent program. It does not modify the SQR.INI file.

Here is an example of how you can modify default preferences in a locale:

alter-locale date-edit-mask = 'Mon-DD-YYYY' money-edit-mask = '$$,$$$,$$9.99'

To restore modified locale preferences to their defaults, you can reselect themodified locale. For example, suppose that the locale was "US-English"and the date and money edit masks were modified using the above code.The following code will reset the changed date and money edit masks:

alter-locale locale = 'US-English'

Keywords—NUMBER, MONEY, and DATE

The commands DISPLAY, MOVE, PRINT, and SHOW allow you tospecify the keywords NUMBER, MONEY, and DATE in place of anexplicit number or date edit mask. These keywords can be useful in twocases.

The first case is when you want to write programs that automatically adaptto the default locale. By using the keywords NUMBER, MONEY, andDATE, you tell SQR to take these edit masks from the default localesettings.

The second case is when you want to specify your number, money, anddate formats once at the top of your program and use these formatsthroughout your report. In this case, you define these formats with anALTER-LOCALE command at the top of your program. Then when youuse the keywords NUMBER, MONEY, and DATE later in your program,they format number, money, and date outputs with the masks defined inthe ALTER-LOCALE command.

Whether you set the locale in the SQR.INI file or in your program, thesekeywords will have the same effect. In the following example, thesekeywords are used with the PRINT command to produce output for theUS-English and French locales:

Page 169: SQR User's Guide

SQR 4.0 National Language Support

SQR User's Guide 155

let #num_var = 123456let #money_var = 123456let $date_var = strtodate('19960520152000')

! set locale to US-Englishalter-locale locale = 'US-English'print 'US-English locale' (1,1)print 'With NUMBER keyword ' (+1,1)print #num_var (,22) NUMBERprint 'With MONEY keyword ' (+1,1)print #money_var (,22) MONEYprint 'With DATE keyword ' (+1,1)print $date_var (,22) DATE

! set locale to FrenchALTER-LOCALE locale = 'French'print 'French locale' (+2,1)print 'With NUMBER keyword ' (+1,1)print #num_var (,22) NUMBERprint 'With MONEY keyword ' (+1,1)print #money_var (,22) MONEYprint 'With DATE keyword ' (+1,1)print $date_var (,22) DATE

The output will be as follows:

US-English localeWith NUMBER keyword 123,456.00With MONEY keyword $ 123,456.00With DATE keyword May 20, 1996

French localeWith NUMBER keyword 123.456,00With MONEY keyword 123.456,00 FWith DATE keyword 20 mai 1996

Page 170: SQR User's Guide

National Language Support SQR 4.0

156 SQR User's Guide

Summary• Local preferences for language, currency, and the presentation of dates

and numbers can be specified in a locale.

• Predefined locales are specified in the SQR.INI file.

• You can edit the SQR.INI file to alter predefined locales or to create newones.

• You can switch among locales by using the commandALTER-LOCALE. You can also specify individual preferences for alocale by using ALTER-LOCALE.

• You can also specify formats with the keywords NUMBER, MONEY,and DATE.

The next chapter explains how SQR can interoperate with otherapplications and how SQR can be extended with functions supplied by youor contained in a third-party library.

Page 171: SQR User's Guide

SQR User's Guide 157

22 Interoperability

This chapter describes how SQR can interoperate with other applications orbe extended with additional functions.

Applications can run SQR programs using the SQR API (applicationprogram interface). An SQR program can call also an external application'sAPI.

This interoperability is depicted in the two diagrams below:

ExternalApplication

SQRExecute

SQR API

External Application Invoking an SQR Program Using the SQR API

ExternalApplication

SQRExecute

UFUNC.C

SQR Calling an External Application's API Using UFUNC.C

This chapter will first describe how to invoke an SQR program fromanother application using the SQR API. This API is provided through aDLL on Windows and through an object library on other platforms.

Next, the chapter will explain how to invoke an external application's APIby using the UFUNC.C interface.

Page 172: SQR User's Guide

Interoperability SQR 4.0

158 SQR User's Guide

Calling SQR from Another Application

The following techniques can be used to invoke an SQR program fromanother application:

• Using the SQR command line—the application initiates a process forrunning SQR. The SQR command includes all the necessaryparameters. The SQR command line is covered in Chapter 27, "Usingthe SQR Command Line."

• Using the SQR API—the application makes a call to the SQR API. Thismethod is covered in the next section.

• Using SQR for PowerBuilder—your PowerBuilder application can callto the local or remote SQR user objects. The SQR for PowerBuilderextensions are covered in the SQR for PowerBuilder User's Guide.

Using the SQR API

The SQR API is provided on Windows through a DLL (Dynamic LinkLibrary). You can use the SQR API from any application that is capable ofcalling DLL functions. For C and C++ applications, a header file,SQRAPI.H, and an import library (SQRWIN.LIB) are provided. SQRrequires the following DLLs to run: For Windows 3.1 they areSQRWIN.DLL, BCLW.DLL, and LIBSTI.DLL. For Windows NT they areSQRW.DLL, BCLW32.DLL, LIBSTI32.DLL, and STIMAGES.DLL. Theaforementioned DLL files are located in the BINW directory.

On platforms other than Windows, the SQR API is provided as a staticlibrary (sqr.a or SQR.LIB). For C and C++ applications, a header file,SQRAPI.H (or sqrapi.h), is provided. Be sure to include the SQR APIlibrary and your database library when you link your C or C++application. Two additional libraries are required: bcl.a and libsti.a. Seethe SQR Server Installation Guide for more information about linking withSQR.

Page 173: SQR User's Guide

SQR 4.0 Interoperability

SQR User's Guide 159

The following API functions are defined for calling SQR:

Function Descriptionint sqr(char *) Runs an SQR program. Passes the address

of a null terminated string containing anSQR command line, including programname, connectivity information, flags, andarguments. This is a synchronous call. Itreturns when the SQR program hascompleted. This function returns zero (0) ifit is successful.

int sqr(char *, HANDLE) Windows 3.1 only—for Windows NT usethe normal sqr call above. The secondargument is not used—pass a 0 for thisargument.

void sqrcancel(void) Cancels a running SQR program. Theprogram may not stop immediately becauseSQR waits for any currently pendingdatabase operations to complete.

Since the sqr function does not return untilthe SQR program has completed, sqrcancelis called using another thread or somesimilar asynchronous method.

int sqrend(void) Releases memory and closes cursors.Cursors may be left open to speed uprepeated execution of the same SQRprogram. Call this function after the lastprogram execution, or optionally betweenSQR program executions.

This function always returns zero (0).

On Windows 3.1, this function has no effect.Memory is always released after each SQRprogram execution.

Table 4. The SQR API

ØØ Note On Windows 3.1, the sqr call has an extra argument.

For the benefit of C/C++ programmers, the APIs are declared in the fileSQRAPI.H. Include this header file in your source code:

#include 'sqrapi.h'

Page 174: SQR User's Guide

Interoperability SQR 4.0

160 SQR User's Guide

When you call SQR from a program, the most recently run SQR program issaved in memory. If the same SQR program is run again with either thesame or different arguments, the program is not scanned again and theSQL statements are not parsed again. This feature provides a significantimprovement in processing time. This optimization is not applicable onWindows 3.1. On this platform, memory is always released at the end ofthe sqr call.

To force SQR to release its memory and database cursors, call sqrend() atany time.

Although memory is automatically released when the program exits, youmust call sqrend before the calling program exits to ensure that SQRproperly cleans up any database resources such as database cursors andtemporary stored procedures.

Following is an example of a command that links a C application with theSQR API on a UNIX machine:

cc -o {your_prog} {your_prog}.o $SQRDIR/sqr.a $SQRDIR/bcl.a\ $SQRDIR/libsti.a (DB Libname)...

Check the make files or link scripts that are supplied with SQR Workbenchfor details. You may want to copy and modify those to link in yourprogram.

To call SQR, call sqr() and pass a command line. For example, in C:

status = sqr("myprog sammy/baker arg1 arg2 arg3");if (status != 0)

...error occurred...

Page 175: SQR User's Guide

SQR 4.0 Interoperability

SQR User's Guide 161

The following table describes error values returned by SQR, bothstandalone and callable:

Non-VMS VMS Reason0 1 Normal exit

1 0 Error exit

2 0x2622 Cannot process SQRERR.DAT

3 0x2632 Command-line flag in error

4 0x2642 Problem creating .SQT file

5 0x2652 Program did not compile

6 0x2662 Problem with .SQR/.SQT file (open/read)

7 0x2672 Problem with .LIS file (create/write)

8 0x2682 Problem with .ERR file (create/write)

9 0x2692 Problem with .LOG file (create/write)

10 0x26A2 Problem with POSTSCRI.STR file(open/read)

11 0x26B2 Cannot call SQR recursively

12 0x26C2 Problem with Windows

13 0x26D2 Internal error occurred

14 0x26E2 Problem with SQRWIN.DLL

15 0x26F2 Problem with -ZCF file

Table 5. Error Values Returned by the SQR API

The VMS codes are given in hexadecimal notation. SQR uses the 0x2600group for its error messages to avoid conflict with VMS error messages.Error codes 9 and 12 are only applicable to the Windows release.

Extending SQR—UFUNC.C

The SQR language can be extended by adding user functions written instandard languages such as C. This feature allows you to integrate yourown code and third-party libraries into SQR. For example, suppose youhad a library for communication over a serial line, with functions forinitiating the connection and sending and receiving data. SQR wouldallow you to call these functions from SQR programs.

Page 176: SQR User's Guide

Interoperability SQR 4.0

162 SQR User's Guide

To extend SQR in this way, you must prepare the functions, "tell" SQRabout them, and then link the objects (and libraries) with the SQR objectsand libraries to form a new SQR executable. The new SQR executable willthen recognize the new functions as if they were standard SQR functions.

One example of such an extension would be an initcap function. Oracleusers are familiar with this function. The function initcap changes the firstletter of every word to uppercase and changes the rest of the letters tolowercase. For example:

let $a = initcap('MR. JOSEPH JEFFERSON')

The result value in the variable $a would be "Mr. Joseph Jefferson."

Adding a User Function

The following example demonstrates how to extend SQR with an initcapfunction.

The key to the process is an SQR source file called UFUNC.C. This filecontains the list of user-defined functions. It also contains comments witha description of the process of adding a function to SQR. UFUNC.C isprovided in the LIB subdirectory (LIBW in Windows).

To add initcap to SQR, you need to add it to a global array called userfuncsin UFUNC.C.

Step 1. Add Function Prototype

Begin by adding a function prototype to the function declaration list.

static void max CC_ARGS((int, double *[], double *));static void split CC_ARGS((int, char *[], double *));static void printarray CC_ARGS((int, char*[], double *));static void initcap CC_ARGS((int, char *[], char *, int));

The code segment above is taken from the file UFUNC.C. The first threelines are part of the original UFUNC.C. The line that adds the initcapfunction is shown in bold. You can find the modified version of UFUNC.Cin the TUTORIAL directory.

This code defines a prototype for a C function called initcap. Theprototype is required by the C compiler. Note that the name of the Cfunction does not have to be the same as the name of the SQR function.The SQR name for the function is defined in the next step.

Page 177: SQR User's Guide

SQR 4.0 Interoperability

SQR User's Guide 163

The CC_ARGS macro makes your code portable between compilers thatexpect full ANSI prototyping and compilers where the argument prototypeis omitted. You could also write:

static void initcap();

Note also that the keyword STATIC means that the code for initcap willbe added in the file UFUNC.C. If you have the code in a separate file,remove the STATIC keyword.

The first argument of the C function is the argument count of thecorresponding SQR function. In the case of initcap, this argument countshould be 1 because initcap takes exactly one argument.

The second argument of the C function is an array of pointers. This arrayis the argument list. In this case, since initcap only takes one argument,only the first pointer is actually used.

The third argument of the C function is a pointer to the result buffer. Sinceinitcap returns a string, we will define it as "char *".

The last argument sets the maximum length of the result string. The lengthof this string is the size of the result buffer, which you must not overflow.You cannot return a value that is longer than the maximum length. Themaximum length is typically around 2000 bytes, depending on platform.

Step 2. Add Entry to USERFUNCS Table

The next step is to tell SQR about our initcap function. As stated before,this table exists in the UFUNC.C file. Here is the modified code:

} userfuncs[] = { /* (2) Define functions in userfuncs table: Number of Name Return_type Arguments Arg_Types Function ---- ----------- --------- --------- -------- */ "max", 'n', 0, "n", PVR max, "split", 'n', 0, "C", PVR split, "printarray", 'n', 4, "cnnc", PVR printarray, "initcap", 'c', 1, "c", PVR initcap, /* Last entry must be NULL—do not change */ "", '\0', 0, "", 0};

The userfuncs table is an array of structures. The line added is shown inbold, and it initializes one structure in the array. The line contains fivearguments, which correspond to the five fields of the structure.

Page 178: SQR User's Guide

Interoperability SQR 4.0

164 SQR User's Guide

The first argument is the name of the SQR function being added. This isthe name that you will use in the LET, IF and WHILE commands. Thesecond argument is the return type, which 'c' (enclosed in single quotationmarks) indicates is a character string. The third argument is the number ofarguments that initcap will take. Set it to 1.

The fourth argument is a string representing the types of the arguments.Since initcap has only one argument, the string contains one characterenclosed in double quotation marks, "c". This character indicates that theargument for initcap is a string. The last argument is a pointer to a Cfunction that implements the SQR function we are adding. This argumentis the initcap function for which we have provided a prototype in theprevious step. Note the PVR macro that provides proper cast for thepointer.

Step 3. Add Implementation Code

The next step is to add the implementation code for initcap. You can insertit right into the file UFUNC.C. Remember that if you want to put the codein a separate file, you will have to remove the STATIC keyword from theprototype. You may also need to include standard C header files such asCTYPE.H. Here is the code, which is inserted at the end of UFUNC.C:

static void initcap CC_ARGL((argc,argv,result,maxlen))CC_ARG(int, argc) /* Number of actual arguments */CC_ARG(char*, argv[]) /* Pointers to arguments: */CC_ARG(char*, result) /* Where to store result */CC_LARG(int, maxlen) /* Result's maximum length */{ int flag = 1; char *ptr; char *p; ptr = argv[0]; p = result; while (*ptr) { if (ptr - argv[0] >= maxlen) break; /* don't exceed maxlen*/ if (isalnum(*ptr)) { if (flag) *p = islower(*ptr)?toupper(*ptr):*ptr; else *p = isupper(*ptr)?tolower(*ptr):*ptr; flag = 0; } else { flag = 1; *p = *ptr; } p++; ptr++; } *p = '\0'; return;}

Note the use of the CC_ARGL, CC_ARG, and CC_LARG macros. You canalso write the code as follows (only the first five lines are shown).

Page 179: SQR User's Guide

SQR 4.0 Interoperability

SQR User's Guide 165

static void initcap(argc,argv,result,maxlen)int argc; /* Number of actual arguments */char* argv[]; /* Pointers to arguments: */char* result; /* Where to store result */int maxlen; /* Result's maximum length */

Step 4. Relink SQR

Once you have modified UFUNC.C, you must relink SQR. Use the makefile that is provided in the LIB (or LIBW) subdirectory of SQR. This step ishighly specific to operating systems and databases. SQR is linked with thedatabase libraries, whose names and locations tend to vary. You may haveto modify the make file for your system. Once SQR is relinked, you areready to test. Try the following program:

begin-program let $a = initcap('MR. JOSEPH JEFFERSON') print $a ()end-program

The result in the output file should be:

Mr. Joseph Jefferson

For further information on argument types in user-defined functions, seethe comments in the UFUNC.C file.

ufunc on Windows NT

On Windows NT, ufunc now resides in SQREXT.DLL. You may rebuildSQREXT.DLL using any language or tool, as long as the appropriate callingprotocol is maintained. The source code for SQREXT.DLL is included inthe shipped package (EXTUFUNC.C).

When SQRW.DLL and SQRWT.DLL are loaded, they look forSQREXT.DLL in the same directory and for any DLLs specified in the[SQR Extension] section in SQR.INI. If SQRW.DLL and SQRWT.DLL findSQREXT.DLL and the DLLs specified in the SQR.INI file, they make thefollowing calls in all the DLLs, passing the instance handle (of the callingmodule) and three function pointers:

void InitSQRExtension (HINSTANCE hInstance,FARPROC lpfnUFuncRegister,FARPROC lpfnConsole,FARPROC lpfnError);

Page 180: SQR User's Guide

Interoperability SQR 4.0

166 SQR User's Guide

Implementing New User Functions on Windows NT

You may implement new user functions in SQREXT.DLL or any otherextension DLL. All the extension DLLs must have the InitSQRExtension()function exported. If you choose to implement user functions inSQREXT.DLL, you should rebuild the DLL using the supplied make file,SQREXT.MAK. If new extension DLLs containing new user functions areto be used, they must be listed in the [SQR Extension] section in SQR.INIin the system directory.

For any ufunc, you must register it by making the following call inInitSQRExtension().

lpfnUFuncRegister(struct ufnns* ufunc);

The function pointer lpfnUFuncRegister is passed in from the callingmodule. Refer to EXTUFUNC.C for the definition of struct ufnns and thesample user functions.

Summary• Applications can run SQR programs using the SQR API (application

program interface).

• An SQR program can call also an external application's API.

• You can extend SQR with third-party libraries and functions written instandard languages such as C.

• To extend SQR, add functions to the userfuncs global array in theUFUNC.C file.

The next chapter describes techniques for testing and debugging SQRprograms.

Page 181: SQR User's Guide

SQR User's Guide 167

23 Testing and Debugging

This chapter describes the SQR functionality designed to help with thetesting and debugging of SQR programs. This chapter will focus onfacilities in the SQR language and command-line options.

Using the Test Feature

During the development of an SQR program, you frequently test it byrunning it and examining its output. In many cases, you are onlyinterested in the first few pages of the report.

To speed the cycle of running and viewing a few pages, use the -Tcommand-line flag. The -T flag lets reports finish more quickly because allBEGIN-SELECT ORDER BY clauses are ignored. The database will notsort the data and the first set of records will be selected sooner. Enter thedesired number of test pages after the -T flag. For example, -T6 will causethe program to stop after 6 pages of output have been created.

ØØ Note If your program contains break logic, the breaks may occur in unexpectedlocations because the ORDER BY clause is ignored.

To test a report file called customer.sqr, enter the following command:

sqr customer username/password -T3

The -T3 flag specifies that the program will stop running after 3 pages havebeen produced.

When the test completes successfully, check it by displaying the output fileon your screen or printing it. The default name of the output file is thesame as the program file with the extension .LIS. For example, if yourreport is named customer.sqr, the output file will be named customer.lis.

If you are using Workbench for Windows, select Limit to nn pages in theRun dialog.

Page 182: SQR User's Guide

Testing and Debugging SQR 4.0

168 SQR User's Guide

When the development of your program is complete, run it without the -Tflag. Your program will process all ORDER BY clauses and run tocompletion.

If the program creates more than one report, the -T flag restriction willapply only to the first report.

Using the #DEBUG Command

When debugging a program it is often useful to:

• Display data or show when a procedure or query executes by usingtemporary SHOW or DISPLAY commands in key places in theprogram.

• Isolate problem areas by temporarily skipping the parts of the programthat work correctly.

• Temporarily cause additional behavior in questionable areas of theprogram. For example, display or modify variables that you suspect arecausing a problem.

SQR provides the #DEBUG command to help you make temporarychanges to your code. You can use the #DEBUG command toconditionally process portions of your program.

Precede the command with #DEBUG, as shown in the following example:

#debug display $s

When #DEBUG precedes a command, that command is processed only ifthe -DEBUG flag is specified on the SQR command line. In this example,the value of $s will be displayed only when you run the program with-DEBUG.

You can achieve debug multiple commands by using up to 10 letters ordigits to differentiate between them. Indicate which command is to bedebugged on the -DEBUG flag, as shown in the following example:

sqr myreport username / password -DEBUGabc

In this example, commands preceded by #DEBUG, #DEBUGa, #DEBUGb,or #DEBUGc are compiled when the program is executed. Commandspreceded with #DEBUGd are not compiled because "d" was not specifiedin the -DEBUG command-line flag.

Page 183: SQR User's Guide

SQR 4.0 Testing and Debugging

SQR User's Guide 169

Using Compiler Directives for Debugging

You can conditionally compile entire sections of your program using thefive compiler directives:

• • #IF

• • #ELSE

• • #END-IF or #ENDIF

• • #IFDEF

• • #IFNDEF

You can use the value of a substitution variable, declared by a #DEFINEcommand, to turn on or off a set of statements, as shown in the followingexample:

#define DEBUG_SESSION Y

#if DEBUG_SESSION = 'Y'begin-procedure dump_array let #i = 0 while #i < #counter ! Get data from the array get $state $city $name $phone from customer_array(#i) print $state (,1) print $city (,7) print $name (,24) print $phone (,55) position (+1) add 1 to #i end-whileend-procedure ! dump_array#end-if

The dump_array procedure is only used for debugging. By definingDEBUG_SESSION as Y, the dump_array procedure is included in theprogram. Later, you can change DEBUG_SESSION to N and exclude thedump_array procedure from the program. The #IF command in thisexample is case-insensitive.

Common Programming Errors

The most common programming error using SQR is mistyping variablenames. Because SQR does not require variables to be declared, it will notissue an error message when variables names are mistyped. Instead, SQRconsiders the mistyped variable as if it is another variable.

Page 184: SQR User's Guide

Testing and Debugging SQR 4.0

170 SQR User's Guide

For example:

let #customer_access_code = 55print #customer_acess_code ()

This example will not print 55 because we mistyped the variable name.Can you see the typo? The "c" in "acess" on the PRINT command ismissing.

A related problem has to do with global versus local variables. If you referto a global variable in a local procedure without preceding it with anunderscore, SQR will not issue an error message. Instead, it is taken as anew local variable name. For example:

begin-procedure main let $area = 'North' do procend-procedure ! main

begin-procedure proc local print $area () ! Should be $_areaend-procedure

In this example, the local procedure proc prints the value of the localvariable $area and not the global variable $area. It will print nothingbecause the local $area variable did not receive a value. To refer to theglobal variable, use $_area.

Such small errors are hard to detect because SQR considers#customer_acess_code as simply another variable with a value of zero.

Summary• You can speed up the testing cycle by using the -T command-line flag.

• You can conditionally process sections of a program by using the#DEBUG command and the -DEBUG command-line flag.

• • You can conditionally compile entire sections of your program usingthe five compiler directives #IF, #ELSE, #END-IF, #IFDEF, and#IFNDEF.

• The most common programming error is the mistyping of variablenames.

Page 185: SQR User's Guide

SQR User's Guide 171

24 Performance and Tuning

Performance considerations are an important aspect of applicationdevelopment. This chapter examines some of the issues that affect theperformance of SQR programs. This chapter also describes certain SQRcapabilities that can help you write high-performance programs.

SQR Performance and SQL Statements

Whenever your program contains a BEGIN-SELECT, BEGIN-SQL, orEXECUTE command, it performs a SQL statement. Processing SQLstatements typically consumes significant computing resources. TuningSQL statements typically yields higher performance gains than tuning anyother part of your program.

General tuning of SQL is outside the scope of this book. Tuning SQL isoften specific to the type of database that you are using—tuning SQLstatements for an ORACLE database may be different than tuning SQLstatements for DB2. This chapter focuses on SQR tools for simplifying SQLstatements and reducing the number of SQL executions. There are severaltechniques, including:

• Simplifying a complex SELECT

• Using LOAD-LOOKUP to simplify joins

• Using dynamic SQL

• Examining cursor status

• Using an array or flat file instead of a temporary database table.

• Writing programs that create multiple reports

• Tuning SQR numerics

• Running compiled programs with SQR Execute

• Adjusting processing limits

• Buffering fetched rows

• Running programs on the server

Page 186: SQR User's Guide

Performance and Tuning SQR 4.0

172 SQR User's Guide

Simplifying a Complex SELECT

With relational database design, information is often "normalized" bystoring data entities in separate tables. To display the normalizedinformation, you must write a SELECT statement that joins these tablestogether. With many database systems, performance suffers when you joinmore than three or four tables in one SELECT.

With SQR, you can perform multiple SELECT statements and nest them aswe saw in Chapter 7, "Master/Detail Reports." In this way, you can breaka large join into several simpler SELECTS. For example, a SELECTstatement that joins orders and products tables can be broken into twoSELECTS. The first SELECT will retrieve the orders in which we areinterested. For each order retrieved, a second SELECT will retrieve theproducts that were ordered. The second SELECT is correlated to the firstSELECT by having a condition such as:

where order_num = &order_num

This condition specifies that the second SELECT will only retrieve productsfor the current order.

Similarly, if your report is based on products ordered, you can make thefirst SELECT retrieve the products, and make the second SELECT retrievethe orders for each product.

This method will improve performance in many cases, but not all. Toachieve the best performance, you may need to experiment with thedifferent alternatives.

Using LOAD-LOOKUP to Simplify Joins

Database tables often contain key columns such as a product code orcustomer number. To retrieve a certain piece of information, you join twoor more tables that contain the same column. For example, to obtain aproduct description, you may join the orders table with the products table,using the product_code column as the key.

With LOAD-LOOKUP, you can reduce the number of tables that arejoined in one SELECT. This command is used in conjunction with one ormore LOOKUP commands.

Page 187: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 173

The LOAD-LOOKUP command defines an array containing a set of keysand values and loads it into memory. The LOOKUP command looks up akey in the array and returns the associated value. In some programs, thistechnique will perform better than a conventional table join.

LOAD-LOOKUP can be used in the SETUP section or in a procedure. Ifused in the SETUP section, it is processed only once. If used in aprocedure, it is processed each time it is encountered.

LOAD-LOOKUP retrieves two fields from the database, the KEY field andthe RETURN_VALUE field. Rows are ordered by KEY and stored in anarray. The KEY field must be unique and contain no NULL values.

When the LOOKUP command is used, the array is searched (using a"binary" search) to find the RETURN_VALUE field corresponding to theKEY referenced in the lookup.

The following example illustrates LOAD-LOOKUP and LOOKUP:

begin-setup load-lookup name=prods

table=productskey=product_codereturn_value=description

end-setup...begin-selectorder_num (+1,1)product_code lookup prods &product_code $desc print $desc (,15)from orderlinesend-select

In this example, the LOAD-LOOKUP command loads an array with theproduct_code and description columns from the products table. The lookuparray is named prods. The product_code column is the key and thedescription column is the return value. In the SELECT paragraph, aLOOKUP on the prods array retrieves the description for each product_code.This technique eliminates the need to join the products table in the SELECT.

If the ordlines and products tables were simply joined in the SELECT(without LOAD-LOOKUP), the code would look like this:

Page 188: SQR User's Guide

Performance and Tuning SQR 4.0

174 SQR User's Guide

begin-selectorder_num (+1,1)ordlines.product_codedescription (,15)from ordlines, productswhere ordlines.product_code = products.product_codeend-select

Which is faster, a database join or LOAD-LOOKUP? It depends on yourprogram. LOAD-LOOKUP improves performance in the followingsituations:

• When it is used with multiple SELECTS.

• When it keeps the number of tables being joined from exceeding threeor four.

• When the number of entries in the LOAD-LOOKUP table is smallcompared to the number of rows in the SELECT, and they are usedoften.

• When most entries in the LOAD-LOOKUP table are used.

ØØ Tip You can concatenate columns if you want RETURN_VALUE to returnmore than one column. The concatenation symbol is database-specific.

Improving SQL Performance with Dynamic SQL

Chapter 16, "Dynamic SQL and Error Checking," explained how to usedynamic SQL variables. Dynamic SQL can also be used in some situationsto simplify a SQL statement and gain performance.

begin-selectorder_numfrom orders, customerswhere order.customer_num = customers.customer_numand ($state = 'CA' and order_date > $start_date or $state != 'CA' and ship_date > $start_date)end-select

In this example, a given value of $state, order_date or ship_date is comparedto $start_date. The OR operator in the condition makes such multiplecomparisons possible. With most databases, an OR operator slowsprocessing. It may cause the database to perform more work thannecessary.

Page 189: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 175

However, the same work can be done with a simpler SELECT. Forexample, if $state is 'CA,' the following SELECT would work:

begin-selectorder_numfrom orders, customerswhere order.customer_num = customers.customer_numand order_date > $start_dateend-select

Dynamic SQL allows you to check the value of $state and create the simplercondition:

if $state = 'CA' let $datecol = 'order_date'else let $datecol = 'ship_date'end-ifbegin-selectorder_numfrom orders, customerswhere order.customer_num = customers.customer_numand [$datecol] > $start_dateend-select

The substitution variable [$datecol] substitutes the name of the column tobe compared with $state_date. The SELECT is simpler and no longer usesan OR. In most cases, this use of dynamic SQL will improve performance.

Examining SQL Cursor Status

Since SQR programs select and manipulate data from a SQL database, it ishelpful to understand how SQR handles SQL statements and queries.

SQR programs may perform multiple SQL statements. Moreover, the sameSQL statement may be executed many times.

When your program executes, a pool of SQL statement handles—calledcursors—is maintained. A cursor is a storage location for one SQLstatement, for example, SELECT, INSERT, or UPDATE. Every SQLstatement uses a cursor for processing. A cursor holds the context for theexecution of a SQL statement.

The cursor pool consists of 30 cursors, and its size cannot be changed.When a SQL statement is re-executed, its cursor can be immediately reusedif it is still in the cursor pool. When your SQR program executes more than30 different SQL statement, cursors in the pool are reassigned.

Page 190: SQR User's Guide

Performance and Tuning SQR 4.0

176 SQR User's Guide

To examine how cursors are managed, use the -S command-line flag. Thisflag will cause cursor status information to be displayed at the end of arun.

The following information will be displayed for each cursor:

Cursor #nn:SQL = <SQL statement>Compiles = nnExecutes = nnRows = nn

The listing will also include the number of "compiles," which will varyaccording to the database and the complexity of the query. With Oracle,for example, a simple query is compiled only once. With SYBASE, a SQLstatement is compiled before it is first executed and recompiled for thepurpose of validation during the SQR compile phase. Therefore, you maysee two compiles for a SQL statement. Later when the SQL is re-executed,if its cursor is found in the cursor pool, it can proceed without recompiling.

Avoiding Temporary Database Tables

Programs often use temporary database tables to hold intermediate results.Creating, updating, and deleting database temporary tables is a veryresource-consuming task, however, and can hurt your program'sperformance. SQR provides two alternatives to using temporary databasetables.

The first alternative is to store intermediate results in an SQR array. Thesecond is to store intermediate results in a local flat file. Both techniquescan bring about a significant performance gain. You can use the SQRlanguage to manipulate data stored in an array or a flat file.

These two methods are explained and demonstrated in the followingsections. Methods for sorting data in SQR arrays or flat files are alsoexplained.

Using and Sorting Arrays

Chapter 8, "Cross-Tabular Reports and the Use of Arrays," introduced thearray as a means of holding data records during program execution.

Page 191: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 177

An SQR array can hold as many records as can fit in memory. During thefirst pass, when records are retrieved from the database, you can storethem in the array. Subsequent passes on the data can be made withoutadditional database access.

The following code retrieves records, prints them, and saves them into anarray named customer_array.

create-array name=customer_array size=1000 field=state:char field=city:char field=name:char field=phone:charlet #counter = 0begin-selectstate (,1)city (,7)name (,24)phone (,55) position (+1) put &state &city &name &phone into customer_array(#counter) add 1 to #counterfrom customersend-select

This example creates an array named customer_array. The array has fourfields that correspond to the four columns selected from the customerstable, and it can hold up to 1,000 rows. If the customers table had morethan 1,000 rows, it would be necessary to create a larger array.

The SELECT prints the data. The PUT command is then used to store thedata in the array. Chapter 8 showed how to use the LET command toassign values to array fields. The PUT command performs the same work,but with fewer lines of code. With PUT, you can assign all four fields inone command.

The #counter variable serves as the array subscript. It starts with zero andmaintains the subscript of the next available entry. At the end of theSELECT, the value of #counter is the number of records in the array.

The next piece of code retrieves the data from customer_array and prints it:

let #i = 0while #i < #counter get $state $city $name $phone from customer_array(#i) print $state (,1) print $city (,7) print $name (,24) print $phone (,55) position (+1) add 1 to #iend-while

Page 192: SQR User's Guide

Performance and Tuning SQR 4.0

178 SQR User's Guide

In this piece of code, #i goes from 0 to #counter-1. The fields from eachrecord are moved into the corresponding variables $name, $city, $state, and$phone. These values are then printed.

Sorting

In many cases, intermediate results must be sorted by a different field. Thefollowing program shows how to sort customer_array by name. Theprogram uses a well-known sorting algorithm called QuickSort. You cancopy this code into your program, make appropriate changes, and use it tosort your array. For further information on QuickSort, see the bookFundamentals of Data Structures by Horowitz and Sahni, 1982.

Program ex24a.sqr

#define MAX_ROWS 1000

begin-setupcreate-array name=customer_array size={MAX_ROWS} field=state:char field=city:char field=name:char field=phone:char!! Create a helper array that is used in the sort!create-array name=QSort size={MAX_ROWS} field=n:number field=j:numberend-setup

begin-program do mainend-program

Program continues on the following page.

Page 193: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 179

Program ex24a.sqr (continued)

begin-procedure mainlet #counter = 0!! Print customers sorted by state!begin-selectstate (,1)city (,7)name (,24)phone (,55) position (+1) ! Put data in the array put &state &city &name &phone into customer_array(#counter) add 1 to #counterfrom customersorder by stateend-selectposition (+2)!! Sort customer_array by name!let #last_row = #counter - 1do QuickSort(0, 0, #last_row)!! Print customers (which are now sorted by name)!let #i = 0while #i < #counter ! Get data from the array get $state $city $name $phone from customer_array(#i) print $state (,1) print $city (,7) print $name (,24) print $phone (,55) position (+1) add 1 to #iend-whileend-procedure ! main

Program continues on the following page.

Page 194: SQR User's Guide

Performance and Tuning SQR 4.0

180 SQR User's Guide

Program ex24a.sqr (continued)

!! QuickSort!! Purpose: Sort customer_array by name.! This is a recursive function. Since SQR does not allocate! local variables on a stack (they are all static), this! procedure uses a helper array.!! #level - Recursion level (used as a subscript to the helper! array)! #m - The "m" argument of the classical QuickSort! #n - The "n" argument of the classical QuickSort!begin-procedure QuickSort(#level, #m, #n) if #m < #n let #i = #m let #j = #n + 1 ! Sort key is "name" let $key = customer_array.name(#m) while 1 add 1 to #i while #i <= #j and customer_array.name(#i) < $key add 1 to #i end-while subtract 1 from #j while #j >= 0 and customer_array.name(#j) > $key subtract 1 from #j end-while if #i < #j do QSortSwap(#i, #j) else break end-if end-while do QSortSwap(#m, #j) add 1 to #level ! Save #j and #n let QSort.j(#level - 1) = #j let QSort.n(#level - 1) = #n subtract 1 from #j do QuickSort(#level, #m, #j) ! restore #j and #n let #j = QSort.j(#level - 1) let #n = QSort.n(#level - 1) add 1 to #j do QuickSort(#level, #j, #n) subtract 1 from #level end-ifend-procedure ! QuickSort

Program continues on the following page.

Page 195: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 181

Program ex24a.sqr (continued)

!!! QSortSwap!! Purpose: Swaps records #i and #j of customer_array!! #i - Array subscript! #j - Array subscript!begin-procedure QSortSwap(#i, #j) get $state $city $name $phone from customer_array(#i) let customer_array.state(#i) = customer_array.state(#j) let customer_array.city(#i) = customer_array.city(#j) let customer_array.name(#i) = customer_array.name(#j) let customer_array.phone(#i) = customer_array.phone(#j) put $state $city $name $phone into customer_array(#j)end-procedure ! QSortSwap

The QuickSort algorithm uses a recursive procedure, which means that itcalls itself. SQR maintains only one copy of the procedure's local variables.In QuickSort the variables #j and #n are overwritten when QuickSort callsitself.

For the algorithm to work properly, the program must save the values ofthese two variables before making the recursive call, then restore thosevalues when the call completes. QuickSort can call itself recursively manytimes, so the program may need to save many copies of #j and #n. To dothis, add a #level variable that maintains the depth of recursion. In thisexample, a helper array, Qsort, is used to hold multiple values of #j and #n.

The QuickSort procedure takes three arguments. The first is the recursionlevel (or depth), which is #level, as described above. The second and thirdarguments are the beginning and end of the range of rows to be sorted.Each time QuickSort calls itself, the range gets smaller. The main procedurestarts QuickSort by calling it with the full range of rows.

The QSortSwap procedure swaps two rows in customer_array. Typically,rows with a lower key value are moved up.

The procedures QuickSort and QSortSwap in ex24a.sqr refer tocustomer_array and its fields. If you plan to use these procedures to sort anarray in your applications, you'll need to change these references to theapplicable array and fields. The QuickSort procedure sorts in ascendingorder.

Page 196: SQR User's Guide

Performance and Tuning SQR 4.0

182 SQR User's Guide

QuickSort and National Language

The QuickSort procedure does not support National Language Sensitivecharacter string sort. The comparisons

while #i <= #j and customer_array.name(#i) < $key

and

while #j >= 0 and customer_array.name(#j) > $key

are simple string comparisons. They work well for US ASCII English, butthey may not sort correctly with other languages. For such languages, youmay need to write a National Language Sensitive character stringcomparison and add that to SQR. Chapter 22, "Extending SQR," explainshow to add functions to SQR. The QuickSort procedure will then bemodified as follows.

while #i <= #j and NLS_STRING_COMPARE(customer_array.name(#i),$key)while #j >= 0 and NLS_STRING_COMPARE($key,customer_array.name(#j))

Using and Sorting Flat Files

An alternative to an array is a flat file. You can use a flat file when therequired array size exceeds available memory. As is the case with anarray, you may need a sorting utility that supports NLS.

The sample code in the previous section can be rewritten to use a fileinstead of an array. The advantage of using a file is that the program is notconstrained by the amount of memory that is available. The disadvantageof using a file is that the program will perform more I/O. However, it maystill be faster than performing another SQL statement to retrieve the samedata.

This program uses the UNIX sort utility to sort the file by name. Thisexample can be extended to include other operating systems.

The following code is rewritten to use the file cust.dat instead of the array.

Page 197: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 183

Program ex24b.sqr

begin-program do mainend-program

begin-procedure main!! Open cust.dat!open 'cust.dat' as 1 for-writing record=80:varybegin-selectstate (,1)city (,7)name (,24)phone (,55) position (+1) ! Put data in the file write 1 from &name:30 &state:2 &city:16 &phone:10from customersorder by stateend-selectposition (+2)!! Close cust.datclose 1! Sort cust.dat by name!call system using 'sort cust.dat > cust2.dat' #statusif #status <> 0 display 'Error in sort' stopend-if!! Print customers (which are now sorted by name)!open 'cust2.dat' as 1 for-reading record=80:varywhile 1 ! loop until break ! Get data from the file read 1 into $name:30 $state:2 $city:16 $phone:10 if #end-file break ! End of file reached end-if print $state (,1) print $city (,7) print $name (,24) print $phone (,55) position (+1)end-while!! close cust2.datclose 1end-procedure ! main

The program starts by opening a file cust.dat

open 'cust.dat' as 1 for-writing record=80:vary

Page 198: SQR User's Guide

Performance and Tuning SQR 4.0

184 SQR User's Guide

The OPEN command opens the file for writing and assigns it file number 1.You can open as many as 12 files in one SQR program. The file is set tosupport records of varying length with a maximum of 80 bytes(characters). For this example, you could also use fixed-length records.

As the program selects records from the database and prints them, it writesthem to cust.dat.

write 1 from &name:30 &state:2 &city:16 &phone:10

The WRITE command writes the four columns into file number 1—thecurrently open cust.dat. It writes the name first, which makes it easier tosort the file by name. The program writes fixed-length fields—forexample, &name:30 specifies that the name column will use exactly 30characters. If the actual name is shorter, it will be padded with blanks.When the program has finished writing data to the file, it closes the fileusing the CLOSE command.

The file is sorted with the UNIX sort utility.

call system using 'sort cust.dat > cust2.dat' #status

The command sort cust.dat > cust2.dat is sent to the UNIX system. Itinvokes the UNIX sort command to sort cust.dat and direct the output tocust2.dat. The completion status is saved in #status; a status of 0 indicatessuccess. Since name is at the beginning of each record, the file will besorted by name.

Next, we open cust2.dat for reading. The command

read 1 into $name:30 $state:2 $city:16 $phone:10

reads one record from the file and places the first 30 characters in $name.The next two characters are placed in $state and so on. When the end of thefile is encountered, the reserved variable #end-file is automatically set to 1(true). The program checks for #end-file and breaks out of the loop whenthe end of the file is reached. Finally, the program closes the file using theCLOSE command.

Creating Multiple Reports in One Pass

Sometimes you must create multiple reports that are based on the samedata. In many cases, these reports are similar, with only a difference inlayout or summary. Typically, you can create multiple programs and evenreuse code. However, if each program is executed separately, the databasehas to repeat the query. Such repeated processing is often unnecessary.

Page 199: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 185

With SQR, one program can create multiple reports simultaneously. In thismethod, a single program creates multiple reports, making just one pass onthe data. The amount of database processing is thus greatly reduced. Themultiple report feature of SQR is described in Chapter 18, "MultipleReports."

Tuning SQR Numerics

SQR provides three types of numeric values:

• Machine floating point numbers

• Decimal numbers

• Integers

Machine floating point numbers are the default. They use the floatingpoint arithmetic provided by the hardware. This method is very fast. Ituses binary floating point and normally holds up to 15 digits of precision.

Some accuracy may be lost when converting decimal fractions to binaryfloating point numbers. To overcome this loss of accuracy, you cansometimes use the ROUND option of commands such as ADD,SUBTRACT, MULTIPLY, and DIVIDE. You can also use the roundfunction of LET or numeric edit masks that round the results to the desiredprecision.

Decimal numbers provide exact math and precision of up to 38 digits.Math is performed in software. This is the most accurate method, but alsothe slowest.

Integers can be used for numbers that are known to be integers. There areseveral benefits for using integers: They enforce the integer type by notallowing fractions, and they adhere to integer rules when dividingnumbers. Integer math is also the fastest, typically faster than floatingpoint numbers.

If you use the DECLARE-VARIABLE command, the -DNT command-lineflag, or the DEFAULT-NUMERIC entry in the [Default-Settings] sectionof the SQR.INI file, you can choose the type of numbers that SQR uses.Moreover, you can select the type for individual variables in the programwith the DECLARE-VARIABLE command. When you choose decimalnumbers, you can also specify the desired precision.

Page 200: SQR User's Guide

Performance and Tuning SQR 4.0

186 SQR User's Guide

Selecting the numeric type for variables allows you to fine-tune theprecision of numbers in your program. For most applications, however,this type of tuning will not yield a significant performance improvementsand we recommend selecting decimal. The default is machine floatingpoint to provide compatibility with older releases of the product.

Compiling SQR Programs and Using SQR Execute

Performance can be improved if you compile your SQR program. Thecompiled program is stored in a run-time (.SQT) file. You can then run itwith SQR Execute. Your program will run faster because it will skip thecompile phase. This method is explained in Chapter 25.

Processing Limits

A startup file and the [Processing-Limits] section of SQR.INI are used todefine the sizes and limitations of some of the internal structures used bySQR. An -M command-line flag can be used to specify a startup file whoseentries will override those set in SQR.INI. If the -M command-line flag isused, then corresponding sections of the file will not be processed. Manyof these settings have a direct impact on memory requirements.

Tuning of memory requirements may be significant when using 16-bitoperating systems such as Windows 3.1. Other operating systems usevirtual memory and tuning memory requirements would normally notaffect performance in any significant way. The only case where you mayneed to be concerned with [Processing-Limits] settings is with large SQRprograms that exceed default [Processing-Limits] settings. In such casesyou'll need to raise the corresponding settings.

Page 201: SQR User's Guide

SQR 4.0 Performance and Tuning

SQR User's Guide 187

Buffering Fetched Rows

When a BEGIN-SELECT command is executed, records are fetched fromthe database server. To improve performance, they are fetched in groupsrather than one at a time. The default is groups of 10 records. The recordsare buffered, and your program processes these records one at a time. Adatabase fetch operation is therefore performed after every 10 records,instead of after every single record. This is a substantial performance gain.If the database server is on another computer, then network traffic is alsosignificantly reduced.

The number of records to fetch together can be modified using the -Bcommand-line flag or for an individual BEGIN-SELECT command usingits -B option. In both cases, you specify the number of records to befetched together. For example -B100 specifies that records will be fetchedin groups of 100. This means that the number of database fetch operationsis further reduced.

This feature is currently available only when you use SQR for the Oracle orSYBASE databases.

Executing Programs on the Database Server

You can reduce network traffic and greatly improve performance byrunning SQR programs directly on the database server machine. The SQRserver product is available on many server platforms includingWindows NT and UNIX.

Summary

The following techniques can be used to improve the performance of yourSQR programs:

• Simplify complex SELECT statements.

• Use LOAD-LOOKUP to simplify joins.

• Use dynamic SQL instead of a condition in a SELECT statement.

• Avoid using temporary database tables. Two alternatives to temporarydatabase tables are SQR arrays and flat files.

• Write programs that create multiple reports with one pass on the data.

Page 202: SQR User's Guide

Performance and Tuning SQR 4.0

188 SQR User's Guide

• Use the most efficient numeric type for numeric variables (machinefloating point, decimal, or integer).

• Save compiled SQR programs and rerun them with SQR Execute.

• Adjust settings in the [Processing-Limits] section of SQR.INI or in astartup file.

• Increase buffering of rows in SELECT statements with the -B flag.

• Execute programs on the database server machine.

The next chapter will explain how to use compiled versions of SQRprograms.

Page 203: SQR User's Guide

SQR User's Guide 189

25 Compiling Programs and

Using SQR Execute

This chapter explains how to save and run compiled versions of your SQRprograms.

For the user, running an SQR program is a one-step process. For SQR,however, there are two steps—compiling the program and executing it.When compiling a program, SQR:

• Reads, interprets, and validates the program.

• "Preprocesses" substitution variables and certain commands—ASK,#DEFINE, #INCLUDE, #IF, and #IFDEF.

• Validates SQL statements.

• Performs the SETUP section.

SQR allows you to save the compiled version of a program and use it whenyou rerun a report. That way, you perform the compile step only once andskip it in subsequent runs. Note that SQR does not compile the programinto machine language. SQR creates a ready-to-execute version of yourprogram that is already compiled and validated. This file is portablebetween different hardware platforms and between some databases.

The steps are simple. Use the -RS command-line flag to save the run-timefile. SQR will create a file with a file name extension of .SQT. Use the -RTcommand-line flag to run the .SQT file. Execution will be faster becausethe program is already compiled.

The SQR product distribution includes SQR Execute (the SQRT program).This program is equivalent to running SQR with -RT. It is capable ofrunning .SQT files but does not include the code that compiles an SQRprogram.

It is important to realize that once you save the run-time (.SQT) file, SQRwill no longer perform any compile-time steps such as executing #IF,#INCLUDE, or ASK commands or performing the SETUP section. Thesewere already performed at the time that the program was compiled andthe run-time file was saved.

Page 204: SQR User's Guide

Compiling Programs and Using SQR Execute SQR 4.0

190 SQR User's Guide

You must make a clear distinction between what is performed at compiletime and what is performed at run time. Think of compile-time steps asdefining what the report is. Commands such as #IF or ASK allow you tocustomize your report at compile time. For run-time customization, youshould use commands such as IF and INPUT.

Here is a list of SQR features that apply at compile time and their possiblerun-time equivalents. In some cases, no equivalent exists and you'll haveto work your way around the limitation. For example, you may have touse substitution variables with commands that require a constant and donot allow a variable. We demonstrated this solution in Chapter 15,"Writing Printer-Independent Reports," where we worked around thelimitation of the USE-PRINTER-TYPE command, which does not accept avariable as an argument.

Compile Time Run TimeSubstitution variables. Use regular SQR variables. If you

are substituting parts of a SQLstatement, use dynamic SQLinstead. See Chapter 16.

ASK INPUT

#DEFINE LET

#IF IF

INCLUDE No equivalent

DECLARE-LAYOUT, margins No equivalent

Number of heading or footing lines No equivalent

DECLARE-CHART PRINT-CHART

DECLARE-IMAGE PRINT-IMAGE

DECLARE-PROCEDURE USE-PROCEDURE

DECLARE-PRINTER ALTER-PRINTER (where possible)

USE (SYBASE only) -DB command-line flag

Table 6. Compile-Time Commands and Run-Time Equivalents

Summary• To save a compiled version of an SQR program, use the -RS command-

line flag.

• To run a precompiled program, use the -RT command-line flag or SQRExecute.

The next chapter explains how to create different types of output files.

Page 205: SQR User's Guide

SQR User's Guide 191

26 Printing Issues

In this chapter, we will cover technical issues relevant to printing.Specifically, we will examine the SQR command-line flags that specifyoutput file type and the printer for which it is produced. We will cover theDECLARE-PRINTER command and expand on printing issues thatpertain to multiple reports. You may recall from Chapter 18, "MultipleReports," that a program can produce more than one report.

Except for the Microsoft Windows platform, SQR does not actually printthe report. SQR creates an output file that contains the report, but it doesnot print it directly. The output file may be a printer-specific file or an SQRportable file (SPF). SQR portable files have a default extension of .SPF or.Snn (for multiple reports).

The following table summarizes SQR command-line flags and the types ofoutput they produce.

Command-Line Flag

Output Fileand Extension File Format Suitable for

-PRINTER:LP .LIS ASCII Line printer

-PRINTER:HP .LIS PCL HP LaserJetprinter

-PRINTER:HT .LIS HTML Internet

-PRINTER:PS .LIS PostScript PostScript printer

-PRINTER:WP Output goesdirectly to thedefault printerwithout beingsaved to a file.You can set yourdefault printerusing theWindows ControlPanel.

Windows

Table 7. Command-Line Flags and Output Types

Page 206: SQR User's Guide

Printing Issues SQR 4.0

192 SQR User's Guide

-NOLIS .SPF or .Snn SQR PortableFormat

SQR Print andSQR Viewer canprint this file todifferent printers.

-KEEP .SPF or .Snn (inaddition to the.LIS file that isnormally created)

SQR PortableFormat and theformat of the .LISfile

SQR Print andSQR Viewer canprint this .SPFfile to differentprinters.

No flag .LIS ASCII, PCL, orPostScript

Line printer, HPLaserJet, orPostScript,respectively.

Table 7. Command-Line Flags and Output Types (continued)

ØØ Note When no flags are specified, SQR will produce a line printer output unlessotherwise set in the SQR program with DECLARE-PRINTER ,USE-PRINTER-TYPE, or the PRINTER-TYPE option of DECLARE-REPORT.

SQR Portable File (SPF) is a printer-independent file format that allows forall the SQR graphical features, including fonts, lines, boxes, shaded areas,charts, bar codes, and images.

This file format is very useful for saving the output of a report. SPF filescan be distributed electronically and read with the SQR Viewer. Producing.SPF output also allows you to decide later where to print it.

When you are ready to print the .SPF file, use SQR Viewer or SQR Print.For more information on these subjects, see the SQR Viewer User's Guide.

The DECLARE-PRINTER command is used to specify printer-specificsettings for the printers that SQR supports: line printer, PostScript, HPLaserJet, and HTML. The DECLARE-PRINTER command itself does notcause the report to be produced for a specific printer. To specify a specificformat, use one of the following three methods:

• Use the -PRINTER:xx command-line flag. For example -PRINTER:PSwill cause SQR to produce a PostScript output. If your program createsmultiple reports, such as the program ex18a.sqr from Chapter 18, the-PRINTER:xx flag will affect all the reports.

Page 207: SQR User's Guide

SQR 4.0 Printing Issues

SQR User's Guide 193

• Use the USE-PRINTER-TYPE command in your report. You must usethis command before you print anything because SQR cannot switchprinter type in the middle of a program. USE-PRINTER-TYPE PS, forexample, will cause SQR to produce PostScript output.

• Use the PRINTER-TYPE option of the DECLARE-REPORT command.The DECLARE-REPORT command is normally used when yourprogram generates more than one report, as we discussed in Chapter18. For example:

declare-report labels layout=labels printer-type=psend-declare

will cause SQR to produce PostScript output for the labels report.

The DECLARE-PRINTER command defines settings for line printers,PostScript, or HP LaserJet printers. The type of printer is specified usingthe TYPE option of the DECLARE-PRINTER command or by specifyingone of the predefined printers DEFAULT-LP, DEFAULT-PS,DEFAULT-HP, and DEFAULT-HT.

Your program may have more than one DECLARE-PRINTER command ifyou define settings for each of the printer types. The settings for aparticular printer will only take effect when output is produced for thatprinter. When your program generates multiple reports, you can definesettings for each printer for each report. To make a DECLARE-PRINTERcommand apply to a specific report, use the FOR-REPORTS option.

How is the output file named? As stated before, the output file willnormally have the same name as your program, but with a differentextension. The extension is .LIS or, if you are creating an .SPF file, .SPF. Ifyou would like SQR to use another name for the output file, you can usethe -F option on the command line. For example, if you want to usechapter1.out as the output of the program ex1a.sqr, the command to runSQR will look as follows:

sqr ex1a username / password -fchapter1.out

When your program creates more than one report, you can name theoutput file by using multiple -F flags as follows:

sqr ex20a username / password -flabel.lis -fletter.lis -flisting.lis

Note that you cannot directly name .SPF files. You can still use the -Fcommand-line flag to name the file, but you cannot control the file nameextension. For example:

sqr ex20a username / password -flabel.lis -fletter.lis -flisting.lis -nolis

Page 208: SQR User's Guide

Printing Issues SQR 4.0

194 SQR User's Guide

The -NOLIS command-line flag will cause SQR to produce .SPF filesinstead of .LIS files. The actual file names will be label.spf, letter.s01, andlisting.s02. Note that the second .SPF file is named .s01 and the third .s02.SQR supplies file extensions such as these when your program generatesmultiple reports.

Different operating systems require different techniques for printing theoutput. On platforms other than Windows, if the output is in SPF format,you first use SQR Print to create the printer-specific file. For example, thecommand will invoke SQR Print to create a PostScript file myreport.lis fromthe output file myreport.spf:

sqrp myreport -printer:ps

Note that this is a one-way conversion—an .SPF file can be turned into an.LIS file, but an .LIS file cannot be turned into an .SPF file.

The following table summarizes the commands and command-line optionsthat you may use on different systems to send your report output to theprinter.

O/S Command Command-Line OptionsUNIX SysV lp myreport.lis

lp myreport.lis -d ...Use -D for printer destinationYou may use the UNIX "at"command to schedule theprinting time.

UNIX BSD lpr myreport.lisVMS PRINT MYREPORT.lis /QUEUE for printer destination

/COPIES for number of copies/AFTER for printing time/PASSALL to resolve printingissues

Windows SQR will print directly.You can also use SQRPrint or SQRWorkbench forWindows.

Use the Print Setup dialog inSQR Print, Workbench forWindows, or the SQR Viewer tochoose a printer destination.Use SQR Print to print multiplecopies.You can also use the FileManager Copy command tocopy the file to the printerdestination (for example, lpt1).

DOS print myreport.lisOS/2 print myreport.lis

Table 8. Print Commands by Operating System

Page 209: SQR User's Guide

SQR 4.0 Printing Issues

SQR User's Guide 195

In any case, we recommend that you check with your systemsadministrator about other procedures or commands applicable to printingoutput files at your site.

Summary• Command-line flags create output files appropriate for different

platforms and printers.

• DECLARE-PRINTER is used to specify printer-specific settings, but itdoes not itself cause the report to be prepared for a specific printer.

• To prepare a report for a specific printer, use the -PRINTER:xxcommand-line flag, the USE-PRINTER-TYPE command or theDECLARE-REPORT command with the printer-type option.

• The -F command-line flag allows you to name output files, but not fileextensions.

• The -NOLIS and -KEEP command-line flags create files in SQR portableformat with an .SPF extension.

The next chapter will explain how to pass arguments and flags from theSQR command line.

Page 210: SQR User's Guide
Page 211: SQR User's Guide

SQR User's Guide 197

27 Using the SQR Command Line

This chapter explains how to use the SQR command line to specify flagsand pass arguments to your program. This technique is a good way tomodify your program at run time.

Command-line flags such as -Bnn, -KEEP, or -S can be entered on thecommand line to modify some aspect of program execution or output.Command-line arguments are typically answers to requests (made in theSQR program by ASK or INPUT commands) for user input.

The syntax of the SQR command line is as follows:

SQR [ program ] [ connectivity ] [ flags ...] [ args ...] [ @file ...]

where:

Argument Descriptionprogram The name of your program. The default file type or

extension is .SQR. If entered as "?" or omitted, SQR promptsyou for the program name. On UNIX-based systems, ifyour shell uses the question mark as a wild card character,you must precede it with a backslash (\).

connectivity The information needed by SQR to connect to the database.If entered as "?" or omitted, SQR prompts you for it.

DB2 Ssname/ SQLid is the subsystem name and SQLauthorization ID to use.

Informix Database is the name of the database to use.

Ingres Database [ / STAR][ / Username ] is the nameof the database to use and an optional username.

ODBC Data_Source_Name/[Username]/[Password] is thename you give to the ODBC driver when you setup the driver, your user name, and password forthe database.

Table 9. SQR Command-Line Arguments

Page 212: SQR User's Guide

Using the SQR Command Line SQR 4.0

198 SQR User's Guide

Argument DescriptionOracle [ Username ] / [ Password [ @Database ]] is

your user name and password for the database.You can also specify the connection string forthe database (e.g., @B:ORASERVER).

SQLBase [ Database ] / [ Username ] / [ Password ] isthe name of the database to use, your user name,and password for the database.

SYBASE Username / [ Password ] is your user name andpassword for the database.

flags Any of the flags listed in the SQR Language Reference.

args... Arguments used by SQR while the program is running.Arguments listed here are used by the ASK and INPUTcommands rather than prompting the user. Argumentsmust be entered on the command line in the same sequencethey are expected by the program—first all ASKarguments in order and then INPUT arguments in order.

@file... File containing program arguments, one argument per line.Arguments listed in the file are processed one at a time.The command-line arguments program, connectivity, andargs can be specified in this file.

Table 9. SQR Command-Line Arguments (continued)

Command-Line Flags

Command-line flags begin with a hyphen. When a flag has an argument,the argument must be entered directly after the flag with no interveningspace.

Specifying Command-Line Arguments

You can pass an almost unlimited number of command-line arguments toSQR at run time. On some platforms, the operating system will impose alimit on the number of arguments or the total size of the command line.Passing arguments is especially useful in automated reports, such as thoseinvoked by scripts or menu-driven applications.

Page 213: SQR User's Guide

SQR 4.0 Using the SQR Command Line

SQR User's Guide 199

You can pass arguments to SQR on the command line, in files, or with theenvironment variable SQR_FLAGS. When you pass arguments in a file,reference the file name on the command line and put one argument oneach line of the file. You thus avoid any limits imposed by the operatingsystem.

To reference a file on the command line, precede its name with the at sign(@) as shown in the following example:

sqr myreport sammy/baker arg1 arg2 @file.dat

In this example, arg1 and arg2 are passed to SQR, followed by the filefile.dat. Each line in file.dat has an additional argument.

How SQR Retrieves the Arguments

When the ASK and INPUT commands execute, SQR checks to see if youentered any arguments on the command line or if an argument file hasbeen opened. If so, SQR uses this input instead of prompting the user.After the available arguments are used, subsequent ASK or INPUTcommands prompt the user for input. If the INPUT command is used withthe BATCH-MODE argument, SQR will not prompt the user but willinstead return a status meaning "No more arguments."

SQR processes all ASK commands before INPUT commands.

Ø Note If you compiled your SQR program into an .SQT file, ASK commands willhave already been processed. Use INPUT instead.

Specifying Arguments and Argument Files

You can mix argument files with simple arguments, as shown in thefollowing example:

sqr rep2 sammy/baker 18 @argfile1.dat "OH" @argfile2.dat "New York"

This command line passes SQR the number 18, the contents of argfile1.dat,the value "OH", the contents of argfile2.dat, and the value "New York", inthat order.

Page 214: SQR User's Guide

Using the SQR Command Line SQR 4.0

200 SQR User's Guide

The "OH" argument is in quotes to ensure that SQR uses uppercase OH.When a command-line argument is case-sensitive or contains spaces, itmust be enclosed in quotes. Arguments stored in files do not requirequotes and cannot contain them; the actual strings with uppercasecharacters and any spaces are passed to SQR.

Using an Argument File

If you wanted to print the same report on different printers with differentcharacteristics, you could save values for the different page sizes, printerinitializations, and fonts in separate files and use a command-lineargument to specify which file to use. For example, the followingcommand line passes the value 18 to SQR:

sqr myreport sammy/baker 18

An #INCLUDE command in the report file chooses file printer18.dat basedon the command-line argument:

begin-setup ask num ! Printer number. #include 'printer{num}.dat' ! Contains #DEFINE commands for

! printer and paper width and length declare-layout report paper-size =({paper_width} {paper_length}) end-declareend-setup

In this example, the ASK command assigns the value 18 to the variablenum; 18 is a compile-time argument. The #INCLUDE command then usesthe value of num to include the file printer18.dat, which could includecommands similar to the following:

! Printer18.dat-definitions for printer in Bldg 4.#define paper_length 11#define paper_width 8.5#define bold_font LS12755#define light_font LS13377#define init HM^J73011

Passing Command-Line Arguments—Other Approaches

SQR examines an argument file for a program name, user name, orpassword if none is provided on the command line. The followingcommand line omits the program name, user name, and password:

sqr @argfile.dat

The first two lines of the argument file for this example contain theprogram name and user name/password:

Page 215: SQR User's Guide

SQR 4.0 Using the SQR Command Line

SQR User's Guide 201

myreportsammy/baker18OH...

If you do not want to specify the report name, user name, or password onthe command line or in an argument file, use the question mark (?). SQRwill prompt the user to supply these. For example:

sqr myreport ? @argfile.dat

In this example, the program prompts the user for the user name andpassword instead of taking them from the first line in the argument file.

You can use more than one question mark on the command line, as shownin the following example:

sqr ? ? @argfile.dat

In this example, the user is prompted for the program name anduser name/password.

Reserved Characters

The hyphen (-) and at sign (@) characters have special meaning on thecommand line. The hyphen precedes an SQR flag, and the at sign precedesan argument file name. To use either of these characters as the firstcharacter of a command-line argument, double the character to indicatethat it is a literal hyphen or at sign, as shown in the following example:

sqr myreport ? --17 @argfile.dat @@X2H44

In this example, the double hyphen and double at sign are interpreted assingle literal characters:

Creating an Argument File from a Report

You can create an argument file for one program from the output ofanother program. For example, you could print a list of account numbersto the file acctlist.dat, then run a second report with the followingcommand:

sqr myreport sammy/baker @acctlist.dat

End acctlist.dat with a flag such as "END," as shown in the followingexample:

Page 216: SQR User's Guide

Using the SQR Command Line SQR 4.0

202 SQR User's Guide

123344134455156664 ...END

An SQR program could use the numbers in acctlist.dat with an INPUTcommand, as shown in the following example:

begin-procedure get_companynext:input $account batch-mode status = #status if #status = 3

goto end_proc end-ifbegin-selectcust_num, co_name, contact, addr, city, state, zip do print-page ! Print page with

! complete company datafrom customerswhere cust_num = $accountend-selectgoto next ! Get next account numberend_proc:end-procedure !get_company

Using Batch Mode

SQR lets you run reports in batch in VAX/VMS, UNIX, or MS-DOSoperating systems.

VAX/VMS

You can run your SQR reports in batch using the supplied procedure,SUBMITSQR.COM. This DCL command procedure prompts you for thename of your report, your username/password, run-time arguments forthe program (if supplied), then writes a temporary command procedureand submits it to the batch queue.

UNIX, Windows NT, Windows 95, OS/2, and MS-DOS

You can create UNIX shell scripts or MS-DOS batch files to run SQR.Include the SQR command line in the file as you type it at the keyboard.

Page 217: SQR User's Guide

SQR 4.0 Using the SQR Command Line

SQR User's Guide 203

Summary• Enter a flag on the command line to modify program execution or

output.

• Specify a command-line argument to supply information requested byan ASK or INPUT command.

• Specify multiple arguments in an argument file referenced on thecommand line.

• Use a question mark on the command line to prompt a user for input.

• Use batch mode to run multiple programs.

The next chapter explains how to create HTML output and publish it on aWeb server.

Page 218: SQR User's Guide
Page 219: SQR User's Guide

SQR User's Guide 205

28 Working with HTML

This chapter explains how to generate HTML from an SQR programoutput and how to publish that output onto a Web site so that it will beavailable over the Internet or an Intranet.

This chapter also explains how to create a script that will allow usersbrowsing the Internet or an Intranet to request execution of an SQRprogram and view its output.

ØØ Note To properly utilize the HTML capabilities of SQR, you should be familiarwith HTML. There are many good books and Web sites available thatdiscuss HTML. One good HTML reference is available at the NetscapeWeb site. The Web site http://www.sandia.gov/sci_compute/elements.htmlalso describes HTML tags and their attributes in detail.

SQR Capabilities Available with HTML

The SQR language has a rich set of available features, but some of thesefeatures are not available for HTML output due to the limitations of thatformat.

The SQR features supported under HTML include:

• Images

• Font sizing. The SQR language specifies font sizes in points. HTMLspecifies font sizes in a value from one to six. A point size specified inan SQR program is mapped into an appropriate HTML font size.

• Font styles. The bold and underline font styles are supported.

• Centering

The SQR features not currently supported for HTML output include:

• Font selection

Page 220: SQR User's Guide

Working with HTML SQR 4.0

206 SQR User's Guide

• Bar codes

• Lines and boxes

• Charts and graphs

Producing HTML Output

There are three ways to produce HTML output from an SQR program.Each method provides a different level of HTML features.

• Running an unmodified SQR program with the command-line flag-PRINTER:HT makes its output viewable in a Web browser.

• Using two HTML procedures—html_set_head_tags andhtml_set_body_attributes—allows you to define a title and backgroundimage for the HTML output. With this method, you must still use thecommand-line flag -PRINTER:HT.

• Using additional HTML procedures produces output with a full set ofHTML features, including lists, tables, and hypertext links. With thismethod, you must still use the command-line flag -PRINTER:HT.

The procedures used in the last two options are contained in a file calledhtml.inc. To utilize HTML procedures, the SQR program must include thecommand:

#include 'html.inc'

The file HTML.INC is located in the SAMPLE (or SAMPLEW) directory.Use the command-line flag -I to specify its path.

HTML Output

When an SQR program is used to generate HTML output, that outputcontains HTML tags. An HTML tag is a character sequence that defineshow information is displayed in a Web browser.

HTML output looks something like this:

<HTML><HEAD><TITLE>myreport.lis</TITLE></HEAD><BODY>

This code is just a portion of the HTML output that SQR generates. Thetags it contains indicate the starting and end points of HTML formatting.

Page 221: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 207

For example, in the HTML code shown above, the tag <HTML> defines theoutput that follows as HTML output. The tags <TITLE> and </TITLE>enclose the report title—in this case, myreport.lis. The <BODY> tagindicates that the information following it comprises the body of the report.

Using -PRINTER:HT

You can generate HTML output from an SQR program by running it withthe command-line flag -PRINTER:HT. Alternatively, you can make somesimple modifications to your program. Add either DECLARE-PRINTERwith the argument TYPE=HT or USE-PRINTER-TYPE HT.

Using any of these techniques will produce output containing HTMLformatting tags such as those shown in "HTML Output," above.

With these methods, HTML output is generated as follows:

• All output is displayed as preformatted text, using the HTML <PRE>tag.

• Text is positioned on the page by the position coordinates specified inthe SQR program.

• Text is displayed using a fixed-width font such as Courier.

• Font sizes are mapped to an appropriate HTML font size.

• HTML reserved characters are mapped into the corresponding HTMLsequence. The characters <, >, &, " are mapped into the charactersequences &lt;, &gt;, &amp;, and &quot;, respectively. This prevents theWeb browser from mistaking such output as an HTML sequence.

Chapter 12 in this User's Guide contains the program ex12a.sqr, whichproduces a simple tabular report. By running it with -PRINTER:HT, youcan produce output that will appear as follows when viewed in a Webbrowser:

Page 222: SQR User's Guide

Working with HTML SQR 4.0

208 SQR User's Guide

Output for ex12a.sqr (in Web browser)

Setting Web Page Title and Body Attributes

You can use the procedures html_set_head_tags and html_set_body_attributesto define a title and background image for a report. To utilize theseprocedures, the SQR program must include the file html.inc, as described in"Producing HTML Output," above. You must also run the program usingthe command-line flag -PRINTER:HT.

These procedures must be called at the start of the program. For example:

do html_set_head_tags('<TITLE>Monthly Report</TITLE>')do html_set_body_attributes('BACKGROUND="/images/mylogo.gif"')

The first line of this code causes the title "Monthly Report" to be displayed.Specifically, the entire sequence '<TITLE>Monthly Report</TITLE>' ispassed as an argument to the procedure html_set_head_tags. Note that theargument is enclosed in single quotes.

The second line causes the background image mylogo.gif to be displayedfor the Web page. Again, an argument is passed to the procedure. Notethat the entire argument is enclosed in single quotes, while the file nameand path are enclosed in double quotes.

Together, the two lines of code above will generate the following HTMLoutput.

Page 223: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 209

<HTML><HEAD><TITLE>My Report</TITLE></HEAD><BODY BACKGROUND="/images/mylogo.gif">

Using Additional HTML Procedures

Using additional HTML procedures in the SQR program providesenhanced capabilities, including:

• Highlighting, including HTML physical tags and logical markup tags.HTML physical tags include subscript, superscript, and strikethrough.HTML logical markup tags include citation, code, keyboard, andsample.

• Headings

• Hypertext links

• Lists, including ordered lists, unordered lists, definition lists, directorylists, and menus

• Paragraph formatting, including paragraph breaks, line breaks, andhorizontal dividers

• Tables, including captions, rows, columns, and column headings

Output File Types

An SQR report named myreport.sqr will create a FRAME file (myreport.htm)and report output file(s). The report output file extensions are controlled bythe OUTPUT-FILE-MODE entry in the [Default-Setting] section of theSQR.INI file. When set to SHORT the report output files use the formmyreport.hzz and when set to LONG the files use the formmyreport_zz.htm. The value of zz ranges from 00 to 99 and reflects thereport number.

The FRAME file show a list (hypertext links) of report pages in one frameand the report text in another frame. Each report output file contains a listof pages (hypertext links) at the end of the file. If myreport.sqr createdmultiple reports then the FRAME file will contain a link to each reportoutput file. In addition, each report output file will contain links to theother report output files that were created during the program run.

Testing

HTML output produced by an SQR program can be viewed on the localsystem. This is a good way to test the output before it is published on theWeb site.

Page 224: SQR User's Guide

Working with HTML SQR 4.0

210 SQR User's Guide

To test a program's output, open the file in the Web browser. If your Webbrowser supports the HTML FRAME construct, open the FRAME file(myreport.htm); otherwise open the report output file (myreport.h00,myreport_00.htm).

Using HTML Procedures in an SQR Program

To enhance to appearance of the HTML output, use HTML procedures inan SQR program.

An SQR program with these procedures generates output as describedabove in "Using -PRINTER:HT," with the following exceptions:

• The HTML <PRE> tag is not used.

• Text is displayed using a proportional font such as Arial.

• Positioning values specified in the SQR program are ignored. Text,HTML tags, and other information are placed in the HTML output inthe order in which they are generated by the SQR program.

• White space, such as spaces between PRINT commands, is removed.

¾¾ Note See the SQR Language Reference for more information on the HTMLprocedures available with SQR.

How to Use HTML Procedures

To utilize the HTML procedures, the SQR program must include the filehtml.inc, as described in "Producing HTML Output," above. As before, youmust run the SQR program with the command-line flag -PRINTER:HT.

The SQR program must also call the procedure html_on at the start of theprogram. The command that calls this procedure is:

do html_on

Page 225: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 211

Additionally, the program must specify a large page length to preventpage breaks. SQR automatically inserts the page navigation hypertextlinks and an HTML <HR> tag at a page break. If a page break falls in themiddle of an HTML construct, such as a table, the output may displayincorrectly. Use the command DECLARE-LAYOUT with a largeMAX-LINES setting to prevent page breaks from occurring.

Positioning Objects

When HTML procedures are turned on, HTML output is generatedwithout the <PRE> tag. All position qualifiers in the SQR program areignored, and program output and HTML tags are placed in the output filein the order in which they are generated, regardless of their positionqualifiers. White space, such as spaces between PRINT commands isremoved. Thus, the HTML procedures must be used to format the report.

The following SQR code does not use the HTML procedures to format theoutput.

print 'Report summary:' (1,1)print 'Amount billed:' (3,1)print #amount_amount (3,20)print 'Total billed:' (4,1)print #total_amount (4,20)

The output from the above sample code, as displayed by the Web browser,appears below. Note that all the text appears on the same line with nospaces between the data.

With the HTML procedures for line breaks and a table, the output can beformatted properly.

The following SQR code uses the procedure html_br to separate the firsttwo lines of text. The procedures html_table, html_tr, html_td, andhtml_table_end are used to display the totals in a tabular format. Note thatan empty string is passed to each procedure as it is called. This emptystring is required if no other argument is passed.

Page 226: SQR User's Guide

Working with HTML SQR 4.0

212 SQR User's Guide

print 'Report summary:' (1,1)do html_br(2,'')

do html_table('')do html_tr('')do html_td('WIDTH=300')print 'Amount billed:' (3,1)do html_td('')print #amount_amount (3,20)do html_tr('')do html_td('WIDTH=300')print 'Total billed:' (4,1)do html_td('')print #total_amount (4,20)do html_table_end

The output from the above is displayed by the Web browser as follows:

Table Procedures

When the HTML procedures are turned on, all positioning values in theSQR program are ignored. Thus, the position values cannot be used todisplay records in a tabular format. To display records in a tabular formatuse the following procedures:

• Tables—call html_table to start a table and html_table_end to end a table.

• Captions—call html_caption to mark the start of a table caption andhtml_caption_end to mark the end of the table caption. The end istypically implied and html_caption_end is not needed, but it can be usedfor completeness.

• Rows—call html_tr to mark the start of a new row in the table andhtml_tr_end to mark the end of the row. The end is typically impliedand html_tr_end is not needed, but it can be used for completeness.

Page 227: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 213

• Column headings—call html_th to mark the start of a column headingand html_th_end to mark the end of the column heading. The end istypically implied and html_th_end is not needed, but it can be used forcompleteness.

• Columns—call html_td to mark the start of a column and html_td_end tomark the end of the column. The end is typically implied andhtml_td_end is not needed, but it can be used for completeness.

The following SQR program uses these table procedures to displayinformation in a tabular format.

Program ex28a.sqr

#include 'html.inc'

begin-program do mainend-program

! set a large page length to prevent page breaksbegin-setup declare-layout default max-lines=750 end-declareend-setup

begin-procedure main! turn on HTML proceduresdo html_on! start the table and display the column headingsdo html_table('border')do html_caption('')print 'Customer Records' (1,1)do html_tr('')do html_th('')print 'Cust No' (+1,1)do html_th('')print 'Name' (,10)! display each record

Program continues on the following page.

Page 228: SQR User's Guide

Working with HTML SQR 4.0

214 SQR User's Guide

Program ex28a.sqr (continued)

begin-select do html_tr('') do html_td('')cust_num (1,1,6) edit 099999 do html_td('')name (1,10) next-listing skiplines=1 need=1from customersend-select! end the tabledo html_table_endend-procedure

Output for ex28a.sqr

Headings

The heading procedures display text using heading levels such as thoseused in this book. The available heading levels range from one to six; afirst-level heading is the highest. To utilize the heading procedures, callthe appropriate heading procedure before the text is output. Once the textis output, call the corresponding end procedure.

Page 229: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 215

The following SQR code displays text as a second-level heading:

do html_h2('')print 'A Level 2 Heading' (1,1)do html_h2_end

Highlighting

The highlighting procedures provide the ability to display text in thevarious HTML highlighting styles. Highlighting is also called logicalmarkup.

To utilize the highlighting procedures, call the appropriate highlightingprocedure before the text is output. Once the text is output call thecorresponding end procedure.

The following highlighting procedures are available:

• Blink—call html_blink and html_blink_end.

• Citation—call html_cite and html_cite_end.

• Code—call html_code and html_code_end.

• Keyboard—call html_kbd and html_kbd_end.

• Sample—call html_sample and html_sample_end.

• Strike—call html_strike and html_strike_end.

• Subscript—call html_sub and html_sub_end.

• Superscript—call html_sup and html_sup_end.

The following SQR code displays text in the subscript style:

print 'Here is ' (1,1)do html_sub('')print 'subscript' ()do html_sub_endprint ' text' ()

Hypertext Links

The hypertext link procedures provide the ability to create hypertext linksand hypertext link anchors. When the user clicks on the hypertext link, theWeb browser switches to the top of the specified HTML document, to apoint within the specified document, or to a link anchor within the samedocument. A hypertext link can point to the home page of a Web site, forexample.

Page 230: SQR User's Guide

Working with HTML SQR 4.0

216 SQR User's Guide

To insert a hypertext link, use the procedure html_a, output the informationthat is to become the hypertext link, and use the procedure html_a_end tomark the end of the hypertext link. Two useful attributes for the procedurehtml_a, are the HREF and NAME attributes. Use the HREF attribute tospecify where the hypertext link points to. Use the NAME attribute tospecify an anchor to which a hypertext link can point. These attributes arepassed as arguments to the procedure html_a.

The following SQR code creates an anchor and two hypertext links. Theanchor is positioned at the top of the document. The first hypertext linkpoints to the HTML document home.html. The second hypertext link pointsto the anchor named TOP in the current document. Note the pound sign(#) in the argument, which indicates that the named anchor is a pointwithin a document. The third link points to an anchor named POINT1 inthe document mydoc.html.

do html_a('HREF=home.html')print 'Goto home page' ()do html_a_end

do html_a('NAME=TOP')do html_a_end

print 'At the top of document' ()do html_br(40, '')print 'At the bottom of document' ()do html_p('')

do html_a('HREF=#TOP')print 'Goto top of document' ()do html_a_end

do html_a ('HREF=mydoc.html#POINT1')print 'Goto point1 in mydoc.html' ()do html_a_end

Images

An image can be included in an HTML output with the PRINT-IMAGEcommand or the procedure html_img. Both of these produce the HTML<IMG> tag.

The PRINT-IMAGE command displays images for all printer types butonly allows you to specify the image type and source. The html_imgprocedure displays images only for HTML printer type but it allows you tospecify any of the attributes available for an HTML <IMG> tag.

Page 231: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 217

For HTML output, only files of the GIF or JPEG format can be used. WithPRINT-IMAGE, use the argument TYPE=GIF-FILE or TYPE=JPEG-FILE,respectively.

Lists

The list procedures display lists. To utilize these procedures, call theappropriate procedure before the list is output. Once the list is output, callthe corresponding end procedure.

The following list procedures are available.

• Definition (for lists of terms and their definitions)—call html_dl andhtml_dl_end.

• Directory—call html_dir and html_dir_end.

• Menus—call html_menu and html_menu_end.

• Ordered (numbered or lettered) lists—call html_ol and html_ol_end.

• Unordered (bulleted) lists—call html_ul and html_ul_end.

To display a list, except for the definition list, call the appropriate listprocedure before the list is output. Call html_li to identify each item in thelist; you can also call html_li_end for completeness. Once the list is outputcall the corresponding end procedure.

The following code displays an ordered list:

do html_ol('')do html_li('')print 'First item in list' (1,1)do html_li_end

do html_li('')print 'Second item in list' (+1,1)do html_li_end

do html_li('')print 'Last item in list' (+1,1)do html_li_enddo html_ol_end

To display a definition list call html_dl before the list is output. Call html_dtto identify a term and html_dd to identify a definition. Once the list isoutput call html_dl_end. You can also call html_dd_end and html_dt_end forcompleteness

Page 232: SQR User's Guide

Working with HTML SQR 4.0

218 SQR User's Guide

The following code displays a definition list:

do html_dl('')do html_dt('')print 'A daisy' (1,1)do html_dt_enddo html_dd('')print 'A sweet and innocent flower' (+1,1)do html_dd_enddo html_dt('')print 'A rose' (+1,1)do html_dt_enddo html_dd('')print 'A very passionate flower' (+1,1)do html_dd_enddo html_ol_end

Paragraph Formatting

The HTML procedures provide various paragraph-formatting capabilities.To utilize these procedures, call the appropriate paragraph procedurebefore the list is output.

The following procedures are available:

• Paragraph breaks—call html_p to mark the start of a paragraph andhtml_p_end to mark the end. Many HTML constructs imply an end ofparagraph; thus, the procedure html_th_end is not needed, but it can beused for completeness.

• Line breaks—call html_br to insert a line break.

• Horizontal dividers (usually a sculpted line)—call html_hr to insert ahorizontal divider.

• Prevent line wrapping—call html_nobr to mark the start of a section oftext that cannot be wrapped by the Web browser to fit the width of thebrowser window. Use the procedure html_nobr_end to mark the end.

The following code uses the paragraph-formatting procedures to formattext into paragraphs:

print 'Here is some normal text' (1,1)do html_p('ALIGN=RIGHT')print 'Here is right aligned text' (+1,1)do html_br(1,'')print 'and a line break' (+1,1)do html_p_enddo html_hr('')do html_nobr('')print 'A very long line of text that cannot be wrapped' (+1,1)do html_nobr_end

Page 233: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 219

User-Defined HTML

You can incorporate your own HTML tags into the HTML output. To doso, use the PRINT command with the argument CODE-PRINTER=HT.

Text printed with this argument is placed only in the HTML outputgenerated when the HTML printer type is specified. With all other printertypes, the text is not placed in the output. In addition, the specified text isplaced directly in the HTML output without any modifications, such as themapping of reserved characters.

The following SQR code uses the HTML <B> tag to print bold text:

print '<B>' () code-printer=htprint 'Bold text' ()print '</B>' () code-printer=ht

Modifying an Existing SQR Program

In this section, an existing SQR program is modified to use HTMLprocedures. The existing program is ex12a.sqr, which was run withoutmodifications and displayed in a Web browser in "Using -PRINTER:HT,"above.

Program ex28b.sqr

#include 'html.inc'

begin-setup declare-layout default max-lines=10000 end-declareend-setup

begin-program do mainend-program

Program continues on the following page.

Page 234: SQR User's Guide

Working with HTML SQR 4.0

220 SQR User's Guide

Program ex28b.sqr (continued)

begin-procedure main

do html_on

print $current-date (1,1) edit 'DD-MON-YYYY'do html_p('')

do html_table('BORDER')do html_tr('')do html_th('WIDTH=250')print 'Name' (3,1)do html_th('WIDTH=120')print 'City' (,32)do html_th('WIDTH=60')print 'State' (,49)do html_th('WIDTH=90')print 'Total' (,61)

begin-select do html_tr('') do html_td('')name (,1,30) do html_td('')city (,+1,16) do html_td('')state (,+1,5) do html_td('ALIGN=RIGHT')tot (,+1,11) edit 99999999.99 next-listing no-advance need=1 let #grand_total = #grand_total + &totfrom customersend-select

do html_tr('') do html_tr('') do html_td('COLSPAN=3 ALIGN=RIGHT')print 'Grand Total' (+1,40) do html_td('ALIGN=RIGHT')print #grand_total (,55,11) edit 99999999.99

do html_table_end

end-procedure ! main

In this code, a DECLARE-LAYOUT command with a large page lengthsetting specified in the MAX-LINES argument is issued to prevent pagebreaks.

The procedure html_on is used to turn on the HTML procedures.

Page 235: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 221

The procedures html_table, html_tr, html_td, and html_th are used toposition the information in a tabular format. Note the arguments passed tothe HTML procedures. BORDER produces the sculpted border seen in theoutput below. WIDTH defines the width of the columns. ALIGN right-aligns the text in the "Total" column. COLSPAN causes the label "GrandTotal" to be spanned beneath three columns of data.

Instead of using a HEADING section, the procedure tr_th is used to displaycolumn headings.

Output for ex28b.sqr

Publishing the Report

A report generated by an SQR program can be published onto the Website. Thereafter, the user of a Web browser can view the report over theInternet or an Intranet by specifying the report's URL address.

Page 236: SQR User's Guide

Working with HTML SQR 4.0

222 SQR User's Guide

To publish a report, you must:

1. Run the SQR program.

2. Determine where the report output will be stored on the Web server.The directory must be one that is pointed to by a URL on your server.See your Webmaster for more details on creating a URL.

3. Copy the generated HTML output files to the chosen directory on theWeb server. If the output is generated on a client PC, use a utility suchas FTP to transfer the HTML output files to the Web server.

4. Create hypertext links in a home page or other Web site that point tothe report files so users browsing the network can navigate to the reportand view it.

To support older Web browsers that do not support the HTML FRAMEconstruct, create two separate hypertext links – one pointing to the FRAMEfile (.htm) and labeled to indicate "frame version," and another pointing tothe report output file and labeled to indicate "non-frame version". If thereport was created with HTML procedures, however, it should onlycontain a single page. In that case, a listing of report pages contained in theFRAME file would not be needed. Only the report output file would berequired for publication on a Web site.

Viewing the Published Report

The Web browser can be used to view a report that is published onto aWeb site. To do this, specify a URL address in your Web browser, forexample http://www.myserver.com/myreport.htm.

Publishing Using an Automated Process

The Webmaster can create a program that automates the publishingprocess. The program should run the SQR program and copy the output tothe appropriate location. The program can even be launched using ascheduling utility to automatically run the program and publish it on theWeb site at specified times. See the documentation of your particularscheduling software for more details.

The Bourne shell program shown below:

• Sets the necessary environment variables.

• Runs the SQR program /usr2/reports/myreport.sqr and generates theoutput files /usr2/reports/myreport.htm and /usr2/reports/myreport.h00.

Page 237: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 223

• Specifies /dev/null as the source of standard input to prevent theprogram from hanging if it requires input.

• Redirects the standard output to /usr2/reports/myreport.out to captureany status messages. The output file can be viewed at a later time todiagnose any problems.

• Copies the generated report files to the directory /usr2/web/docs topublish it on the Web server. Use the directory name appropriate foryour server.

Here is the code:

#! /bin/sh

# set the appropriate environment valuesORACLE_SID=oracle7; export ORACLE_SIDORACLE_HOME=/usr2/oracle7; export ORACLE_HOMESQRDIR=/usr2/sqr/bin; export SQRDIR

# invoke the SQR programsqr /usr2/reports/myreport.sqr orauser/orapasswd \ -PRINTER:ht -I$SQRDIR \ > /usr2/reports/myreport.out 2>&1 < /dev/null

# copy over the outputcp /usr2/reports/myreport.htm /usr2/web/docscp /usr2/reports/myreport.h00 /usr2/web/docs

¾¾ Note The environment variables and the file names must be adjusted to fit yourparticular environment.

Publishing Using a CGI Script

In the CGI script method, the user of a Web browser can run an SQR reportand view the output. One way to allow the user to run an SQR report is byproviding a fill-out form.

Page 238: SQR User's Guide

Working with HTML SQR 4.0

224 SQR User's Guide

This method consists of the following steps:

1. The user of the Web browser navigates to a fill-out form.

2. The user enters information on the fill-out form and presses a button toinvoke the CGI script.

3. The CGI script runs the SQR program.

4. The CGI script copies the report output file to the standard output.

5. The user views the report.

The following items are required for this process:

• The fill-out form

• The CGI script

• The SQR program

Creating the Fill-Out Form

This section explains how to create an HTML fill-out form that allows theuser to enter some values and launch the request.

For more information on implementing an HTML fill-out form, see HTMLdocumentation available in print or on the Internet.

The following HTML code defines a fill-out form with three radio buttonsand a submit button. The radio buttons allow the user to specify thesorting criteria. The submit button invokes the CGI script.

Here is the code:

<HTML><TITLE>View Customer Information</TITLE><FORM METHOD=POST ACTION="/cgi-bin/myreport.sh">Select the Field to Sort By<P>Number <INPUT TYPE="radio" NAME="rb1" VALUE="cust_num" CHECKED>Name <INPUT TYPE="radio" NAME="rb1" VALUE="name">City <INPUT TYPE="radio" NAME="rb1" VALUE="city"><P><INPUT TYPE="submit" NAME="run" VALUE="Run Report"></FORM></HTML>

The FORM METHOD tag specifies that the CGI script /cgi-bin/myreport.shwill be invoked when the submit button is pressed. The URL address ofthe CGI script must be adjusted to fit your particular environment.

Page 239: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 225

In the INPUT tags, the attribute TYPE="radio" defines a radio button. TheVALUE attribute of the selected radio button is passed via the CGI script tothe SQR program, as shown below.

The fill-out form will look like this:

Creating the CGI Script

The CGI script is launched when a user makes a request from a fill-outform. A CGI script can be any executable program. We do notrecommend that SQR be called directly as a CGI script—a Perl script, ashell script, or a C program all provide simpler routines for processing as aCGI script.

For more information on implementing a CGI script, see the HTMLdocumentation available in print or on the Internet.

The CGI script performs the following tasks:

1. Reads the contents of the standard input stream and parses it to obtainthe values entered on the fill-out form. If the fill-out form has no inputfields, this step is not required.

2. Identifies the output as being in HTML format by outputting the string"Content-type: text/html" along with an extra empty line to thestandard output stream.

3. Invokes the SQR program. Values entered by the user on the fill-outform are passed to the SQR program via the CGI script and thecommand line.

Page 240: SQR User's Guide

Working with HTML SQR 4.0

226 SQR User's Guide

4. Outputs the generated .LIS file to the standard output stream. The.HTM file is not used since it points to the .LIS file with a relative URLaddress. The relative address does not tell the Web browser where tofind the .LIS file. We also recommend that you make provisions withinyour SQR program to output an error message.

The following Bourne shell is an example of a CGI script.

#! /bin/sh

# set the appropriate environment valuesORACLE_SID=oracle7; export ORACLE_SIDORACLE_HOME=/usr2/oracle7; export ORACLE_HOMESQRDIR=/usr2/sqr/bin; export SQRDIR

# identify the output as being HTML formatecho "Content-type: text/html"echo ""

# get values from fill-out form using the POST methodread TEMPSTRSORTBY=`echo $TEMPSTR | sed "s;.*rb1=;;s;&.*;;"`

# invoke the SQR programsqr7 /usr2/reports/myreport.sqr orauser/orapasswd \ -PRINTER:ht -f/tmp/myreport$$.lis -I$SQRDIR "$SORTBY" \ > /tmp/myreport$$.out 2>&1 < /dev/nullif [ $? -eq 0 ]; then # display the output cat /tmp/myreport$$.liselse # error ocurred, display the error echo "<HTML><BODY><PRE>" echo "FAILED TO RUN SQR PROGRAM" cat /tmp/myreport$$.out echo "</PRE></BODY></HTML>"fi

# remove temp filesrm /tmp/myreport$$.*

This script first sets the necessary environment variables. Next, it outputsthe string "Content-type: text/html" along with an extra empty line to thestandard output stream to identify the text as being HTML format.

The script retrieves the value of the selected radio button into the variableSORTBY. The value is passed to the SQR program on the command line.

Page 241: SQR User's Guide

SQR 4.0 Working with HTML

SQR User's Guide 227

The script runs the SQR program. The report file /usr2/reports/myreport.sqris used and the file /tmp/myreport$$.lis is generated. In addition, the scriptredirects the standard input from /dev/null to prevent the program fromhanging if the program requires any input. It also redirects the standardoutput to /tmp/myreport$$.out to capture any status messages. The $$ is theprocess ID of the program and is used as a unique identifier to prevent anymultiuser problems.

The script then copies the generated report file to the standard outputstream. If an error occurs it outputs the status message file instead to allowthe user to view the status messages. Finally, it deletes any temporaryfiles.

Passing Arguments to the SQR Program

The SQR program must be modified to accept values entered by the useron the fill-out form.

The code shown below is the procedure main from file ex28b.sqr. It hasbeen modified to use the SORT BY value passed from the CGI script. The$sortby variable is obtained from the command line with an INPUTcommand and used as dynamic variables in the ORDER BY clause. Themodified lines are shown in bold.

begin-procedure maininput $sortby 'Sort by' type=chardo html_ondo html_table('')do html_tr('')do html_th('')print 'Name' (3,1)do html_th('')print 'City' (,32)do html_th('')print 'State' (,49)begin-select do html_tr('') do html_td('')name (,1,30) do html_td('')city (,+1,16) do html_td('')state (,+1,5)next-listing no-advance need=1 let #grand_total = #grand_total + &totfrom customersorder by [$sortby]end-select

Page 242: SQR User's Guide

Working with HTML SQR 4.0

228 SQR User's Guide

Summary• Running an existing SQR program with the -PRINTER:HT command-

line flag will cause it to produce HTML output.

• Modifying an SQR program with the argument TYPE=HT of theDECLARE-PRINTER command or USE-PRINTER-TYPE HT will alsocause it to produce HTML output.

• An SQR program run that produces HTML output will create a FRAMEfile (myreport.htm) and report output file(s) (myreport.h00,myreport_00.htm).

• To enhance HTML output, use HTML procedures. These proceduresare contained in a file called html.inc.

• To utilize these HTML procedures, include the file html.inc in your SQRprogram and call the procedure html_on.

• The command PRINT-IMAGE and the HTML procedure <IMG>provide support for GIF and JPEG images.

• To publish an SQR report on a Web server, run the SQR program andcopy the output file to the Web server.

• To automate the publishing process, use a shell script or a schedulingutility.

• To allow users to request an SQR report, use a CGI script and a fill-outform.

• A fill-out form allows users to request an SQR program and specifyvalues such as sorting criteria.

• A CGI script invokes the SQR program and passes values entered in thefill-out form to it.

Page 243: SQR User's Guide

SQR User's Guide 229

Glossary

argument. A value used to control, modify, or describe the operation of a procedure.Also called parameter.

array. A unit of storage that exists in memory and consists of rows and columns. Anarray is similar to a table, but it does not exist in a database.

array subscript. A row selector for an array (0,1,2,3...).

bind variable. A variable used to represent a single value in a SQL statement.

bitmap. A representation of an image as an array of pixels.

body. The area of the page without the heading and footing. See heading and footing.

break. A change in the value of a column being printed.

buffer. A place for holding intermediate data in memory. Also used as a verb, "tobuffer."

business chart. See chart.

CGI. Common Gateway Interface. The standard interface between an HTTP serverand an external program.

character position. The space taken by one printed character.

character position n. The position on the line, n character positions from the leftmargin.

chart. A graphical representation of data such as a pie chart, a bar chart, a histogram ora line graph.

column. In a database, a column is a named field of a specific datatype in a databasetable. In a report, a column is a vertical space on the page.

column variable. A variable that names a database column being retrieved in aBEGIN-SELECT. Also referred to as database column variable.

compile. The process of reading and translating a program before executing it.

Page 244: SQR User's Guide

Glossary SQR 4.0

230 SQR User's Guide

cross-tabular report. A general name for matrix- and spreadsheet-like reports.

DCL. Data Control Language. In SQL, a class of statements used to control databaseprivileges. Examples are the GRANT and REVOKE commands.

DDL. Data Definition Language. In SQL, a class of statements that define or deletedatabase objects, such as tables. Examples are the CREATE, ALTER, and DROPcommands.

declaration. In SQR, a program statement that defines certain report characteristics orthe source and attributes of various report components, such as charts and images.

DML. Data Manipulation Language. In SQL, a class of statements that query andupdate the database data. Examples are SELECT, INSERT, UPDATE, and DELETE.

document marker. A position marker used in a document paragraph and referred towith a POSITION command.

dynamic variable. A variable used to substitute for all or part of a SQL statement atrun time.

Easy SQR. An interactive tool for creating SQR reports.

edit mask. An option of the PRINT command used for specifying the format of anumber, date, or string.

footing. The area at the bottom of the page.

form letter. A letter combining standard text for all recipients with databaseinformation for each recipient, such as name and address. Also, a program thatgenerates such a letter.

free-form reporting. Printing database records over multiple lines.

FTP. File Transfer Protocol. A standard Internet protocol for transferring files across anetwork.

function. A syntax whose result is usable in an expression.

global procedure. A procedure whose variables are visible anywhere in the program.A global procedure can also see, or access, variables it does not contain. Comparewith local procedure.

global variable. A variable visible throughout a program. Compare with local variable.

Page 245: SQR User's Guide

SQR 4.0 Glossary

SQR User's Guide 231

heading. In a report, the area at the top of the page.

HTML. Hypertext Markup Language. The markup language used for documentspublished on the World Wide Web.

HTTP. Hypertext Transfer Protocol. The Internet protocol used to allow web clients toretrieve information from web servers.

Internet. The global computer network of networks.

Intranet. A private network conforming to HTTP protocols.

invoke. To instruct a program to perform a procedure. Call is a synonym. In SQR, theDO command is used to invoke a procedure.

join. A query operation that retrieves data from multiple database tables in oneSELECT statement. Also, a common database column used to connect, or join, apair of tables.

layout. The layout of the report page including margins and orientation.

literal. A constant string of text or a constant number.

Loadall. A program provided with SQR that loads sample data into the database.

local procedure. A procedure whose variables are visible only within that procedure.A local procedure cannot ordinarily see, or access, variables it does not contain.Compare with global procedure.

local variable. A variable visible only in the procedure in which it is used. Comparewith global variable.

loop. A sequence of program instructions that are repeated until certain conditions aremet.

master/detail report. A report showing data from a primary source accompanied byrelated data from one or more secondary sources.

nested queries. When one query is performed for each row retrieved by anotherquery, the two queries are said to be nested.

Notepad. A program in Windows that allows you to edit text files.

Page 246: SQR User's Guide

Glossary SQR 4.0

232 SQR User's Guide

numeric variable. A variable that stores a number, including integers and realnumbers.

paper size. The size of the report page with its margins.

paragraph. In SQR, one of BEGIN-SELECT, BEGIN-SQL, and BEGIN-DOCUMENTparagraphs.

PCL. A page description language for HP LaserJet printers supported by SQR.

platform. A system consisting of a computer and its operating system.

porting. Moving a program that was developed for a particular system to anothersystem.

position. Location on the page.

PostScript. A page description language supported by SQR.

procedure. A sequence of commands that are named as a group and performed oneafter the other.

query. A SELECT statement that retrieves data from a database.

record. One row of data in a database table.

report. A document. The output of an SQR program.

Workbench for Windows. A Windows application for generating database reports.

reserved variable. In SQR, a predefined variable.

section. Part of an SQR program. In SQR, there are five types of sections—setup,program, heading, footing, and procedure.

SPF (or .spf) file. A report output file in the SQR Portable Format.

SQL. Structured Query Language. A standard language for relational databasemanagement systems that covers queries, data definitions, and data manipulation.

SQR Workbench. The graphical user interface for SQR for Windows.

string variable. A variable that stores text or characters.

Page 247: SQR User's Guide

SQR 4.0 Glossary

SQR User's Guide 233

substitution variable. A variable used to substitute any command, argument, or partof a SQL statement at compile time.

table. A basic unit of storage in a relational database management system consisting ofrows and columns.

URL. Uniform Resource Locator. The current addressing scheme for resources on theInternet or an Intranet.

variable. A named location for storing text or numbers that you define andmanipulate. Variables are similar to the algebraic x and y and can store text,numbers, or database column names.

Viewer. A graphical tool provided with SQR for Windows for viewing and printingSQR reports.

Web server. An HTTP server.

Page 248: SQR User's Guide
Page 249: SQR User's Guide

SQR User's Guide 235

Index

!

! (comment character), 7

#

#DEBUG, 168#DEFINE, 189#ELSE, 169#ENDIF, 169#IF, 169, 189#IFDEF, 169, 189#IFNDEF, 169#INCLUDE, 189#page-count, 120

$

$current-date, 29$sql-error, 120$sqr-locale, 153$sqr-program, 120$username, 120

.

.SQT files, 189

A

ALTER-LOCALE, 152, 153ALTER-PRINTER, 86, 105argument files, 199, 200argument passing, 123–30arguments

command-line, 198

creating file from reports, 201used with ASK or INPUT, 199

arrays, 56, 100multiple, 63performance issues, 176

ASK, 121, 189, 190, 199

B

bar codes, 92batch mode, 202BATCH-MODE argument, 199BEGIN-FOOTING, 5

FOR-REPORTS option with, 135BEGIN-HEADING, 5

FOR-REPORTS option with, 135BEGIN-PROCEDURE, 11BEGIN-PROGRAM, 1BEGIN-SELECT, 9, 49, 52

ORDER BY clause with, 20with HAVING clause, 130

BEGIN-SQL, 137ON-ERROR option with, 139

bind variables, 116bitmaps, 86, 112bmp-file, 86, 112BOLD option

with PRINT, 107BOTTOM-MARGIN option, 47break logic, 19–43breaks, nesting, 23

C

CENTER option, 106, 108CGI script, 223, 225character grid, 2, 46, 71, 105charts, 95–103CODE-PRINTER qualifier, 111, 219column variables, 15columnar data, printing, 69

Page 250: SQR User's Guide

Index SQR 4.0

236 SQR User's Guide

command lineusing reserved characters on, 201using special characters, 200

command-linearguments, 198

command-line flags, 191, 198comments, 7compiling, 189–90compiling SQR programs

performance issues, 186counters, 71CREATE-ARRAY, 59cross-tabular reports, 55–67

D

DATA-ARRAY option, 100DATA-ARRAY-COLUMN-COUNT

argument, 100DATA-ARRAY-ROW-COUNT argument,

100database inserts, 137date arithmetic, 142date variables, 148dateadd function, 142datediff function, 142datenow function, 142dates, 141

comparing, 142converting from strings, 142, 144converting to strings, 142, 145formats, 144

datetostr function, 142DB2, 197DDL (Data Definition Language), 137–40-DEBUG flag, 168debugging SQR programs, 167declarations, 45DECLARE-CHART

TITLE option with, 99DECLARE-IMAGE, 88DECLARE-LAYOUT, 46, 84

defining page width with, 71MAX-COLUMNS option with, 47MAX-LINES option with, 47ORIENTATION option with, 47

PAPER-SIZE option with, 47setting margins with, 47

DECLARE-PRINTER, 111, 191, 192, 193FOR-REPORTS option with, 193TYPE option with, 193

DECLARE-REPORTPRINTER-TYPE option with, 193

DELETE, 119DML (Data Manipulation Language), 137–

40document markers, 75, 91DOCUMENT section, 75, 91dynamic SQL, 115, 116–19dynamic variables, 118

E

edit maskscase sensitivity, 147dates, 146

ELSE, 31ENCODE, 80END-FOOTING, 6END-HEADING, 6END-IF, 31END-PROCEDURE, 11END-PROGRAM, 1, 2END-SELECT, 11END-SETUP, 45eps-file, 86, 112EVALUATE, 60exclamation mark, 7exporting data, 79–81external files, 137

F

-F command-line flag, 193FILL option, 30, 84fill-out form, 224floor function, 128FONT option, 86fonts, 105–9footing, 5, 6form letters, 75–77

Page 251: SQR User's Guide

SQR 4.0 Index

SQR User's Guide 237

FOR-REPORTS option, 135with DECLARE-PRINTER, 193

functions, 128

G

GIF format, 217global variables, 124GRAPHIC, 86graphics, 83

H

HAVING clausewith BEGIN-SELECT, 130

heading, 5, 6headings with HTML, 209, 214highlighting with HTML, 209, 215HORZ-LINE option, 85hpgl-file, 86, 112HTML, 205–28HTML FRAME construct, 209, 222hypertext links, 209, 215, 216hyphens, 31

I

IF, 31, 51images

with HTML, 216indentation, 12Informix, 197Ingres, 197initcap function, 162INPUT, 113, 121, 145, 190, 199INSERT, 119, 139interoperability, 157–66

J

joins, 129performance issues, 172

JPEG format, 217

K

-KEEP command-line flag, 192

L

LaserJet printers, 87, 112LAST-PAGE, 7LEFT-MARGIN option, 47LET, 80

use of functions in, 164LEVEL keyword, 23lists with HTML, 209, 217LOAD-LOOKUP, 172local procedures, 124local variables, 123locales, 151–56

switching, 153LOOKUP, 173loops, 12

M

mailing labels, 69master/detail reports, 49–53mod function, 128MS-DOS, 202multiple reports, 131–35

performance issues, 184

N

national language support, 151NEED argument, 29NO-ADVANCE option, 71-NOLIS command-line flag, 192, 194

Page 252: SQR User's Guide

Index SQR 4.0

238 SQR User's Guide

O

ON-BREAK, 19–43limitations, 41

ON-ERROR option, 115, 119, 139Oracle, 198ORDER BY clause, 118

with BEGIN-SELECT, 20ORIENTATION option, 47

P

page breakswith ON-BREAK, 29, 38

paragraph formatting with HTML, 209, 218passing command-line arguments, 200performance issues, 171PIE-SEGMENT-PERCENT-DISPLAY

qualifier, 103POINT-SIZE option, 86POSITION, 91position, print, 2, 7, 12, 46, 85, 86PostScript printers, 86, 87, 112PRINT, 1, 12

FILL option with, 30, 84ON-BREAK option with, 21with BOLD, 107WRAP option with, 108–9

PRINT-CHART, 95, 112DATA-ARRAY option with, 100DATA-ARRAY-COLUMN-COUNT

argument with, 100DATA-ARRAY-ROW-COUNT

argument with, 100SUB-TITLE argument with, 100TYPE option with, 100

PRINT-DIRECT, 111-PRINTER:xx command-line flag, 112, 191,

192PRINTER-DEINIT, 111printer-independent reports, 111–13PRINTER-INIT, 111PRINTER-TYPE option, 193PRINT-IMAGE, 91, 112, 216

SOURCE option with, 86

TYPE option with, 86procedures, 10, 11, 123–30, 124PROGRAM section, 2, 10

Q

queries, nesting of, 50

R

recursive procedures, 181report arguments file on command line, 198report body, 5reserved characters with HTML, 207reserved variables, 120, 124-RS command-line flag, 189-RT command-line flag, 189running SQR programs

in Windows, 1run-time

arguments, 199

S

SELECT paragraph, 11, 12, 29, 69, 118, 119SETUP section, 45–48, 189

with multiple reports, 134SKIPLINES argument, 22, 29, 71SOURCE option, 87SPF file format, 88, 191, 192, 193spreadsheets, exporting to, 79SQL

dynamic, 115SQL and substitution variables, 120–22SQL cursor status

performance issues, 175SQL error checking, 119–20SQL statements

and SQR performance, 171SQLBase, 198SQR

calling from another application, 158SQR API, 158–61SQR Execute, 189–90, 189

Page 253: SQR User's Guide

SQR 4.0 Index

SQR User's Guide 239

performance issues, 186SQR Portable Format. See SPF file formatSQR Print, 192SQR Viewer, 192SQR Workbench for Windows, 135SQR.INI, 152STATIC keyword, 164STRING, 80strtodate function, 142substitution variables, 120, 121, 122SUB-TITLE argument, 100SYBASE, 198SYMBOL-SET argument, 111

T

-T command-line flag, 167tab-delimited file, 79tables with HTML, 209temporary database tables

performance issues, 176testing SQR programs, 167text

positioning, 105TITLE option, 99TOP-MARGIN option, 47tuning issues, 171TYPE option, 86, 100, 193

U

ufunc on Windows NT, 165UFUNC.C, 161underscores, 31UNIX, 202upper function, 116USE-PRINTER-TYPE, 193user functions

with Windows NT, 166userfuncs, 162, 163, 166

V

variables, 15common error with, 169defining, 30for positioning, 75in documents, 91

variables in SQL, 115–16VMS, 202

SUBMITSQR.COM, 202

W

Windows NTuser functions with, 166

WRAP option, 108–9