Use SQL commands to solve report problems and speed Crystal Reports

9/2/2014
Use SQL commands to solve report problems and speed Crystal Reports
Hex Central: For software and website professionals
Use SQL commands to solve report problems and speed Crystal Reports
Adding SQL commands to Crystal Reports can cut network traffic, improve efficiency and help you create
complex reports that might otherwise not be possible.
By Mike Lewis
In an earlier article, I showed you how SQL expressions can be used to speed up Crystal Reports. This time, we'll switch the focus
from SQL expressions to SQL commands. What's the difference? In a nutshell:
A SQL expression is used in place of (or combined with) a Crystal formula. You can place it directly in a report, or you can use it
in sorting, selection and grouping criteria.
A SQL command is more like a data source. It defines the data that you want to get from the server. Once you've set up the
command, you can use it just like a table or view.
Like SQL expressions, SQL commands can greatly speed up your reports. But they have another important advantage: They open the
door to all kinds of complex reporting tasks that might otherwise be difficult or impossible to achieve.
In general, a SQL command can consist of any query that the database understands. So it can contain unions, sub-queries,
projections, aggregations and groupings, TOP N clauses, and even calls to functions or stored procedures on the server.
Drawbacks
The obvious disadvantage of SQL commands is that you need to be familiar with Structured Query Language - and with the particular
flavor of SQL that your back-end database understands. If you've never coded a SELECT statement before, using these commands in
CR will be a challenge. On the other hand, it could also be an excellent incentive to start learning SQL, given the ability it will give
you to develop more complex reports.
Example 1: Grouping and aggregation
To give you an idea of how to use SQL commands - and how effective
they can be - let's look at a simple example. We'll create a report that
shows customer IDs, along with the total order value for each
customer (Figure 1). We'll assume that all the required data can be
obtained from the Orders table.
To create this report without using SQL commands, you would place
the customer IDs and the individual order values in the Details band.
You would then group the report by customer ID, add a summary field
(of type "sum") to the Group 1 Header band, and finally hide the Details
band so that only the IDs and sums were visible.
To create the same report with the help of a SQL command, you would
define the grouping and summary, not in the report, but as a query. In
other words, you would write a SELECT statement that looks
something like this:
SELECT CustomerID, SUM(Order_Amount) AS Total
FROM Orders
GROUP BY CustomerID
Figure 1: A report showing grouping and aggregation.
Because the query is executed by the database server, only the total rows - that's one row per customer - will be sent across the
network. By contrast, if you weren't using a SQL command, the grouping and totaling would be done in the report, so the server
would have to send every order across the network. Since network traffic is usually a major bottleneck, the performance benefit of
using a SQL command can be dramatic.
The mechanics
How do you go about adding a SQL command to your report? Here are the steps:
1.
Start, as usual, in either the Database Expert or the Data page of the Standard Report
Wizard.
2.
Choose your data source in the usual way, for example by drilling down into Favorites,
Current Connections or Create New Connection. Log onto the data source if necessary.
3.
Under the database's node, double-click on Add Command (Figure 2).
4.
You will now see an editing window, like the one in Figure 3. Type (or paste) your SQL
command in the large edit box in the left of this window. Then click OK.
At this point, Crystal Reports will send the command to the database server, which will try to
execute it. If the server detects an error, it will send a message back to CR, which will display
the message and refrain from saving the command. You must deal with the error before you
can go any further. (Keep in mind that CR sends the command exactly as you enter it, so be
sure that the syntax is correct for the specific database you are using.)
http://www.hexcentral.com/articles/crystal-sql-commands.htm
Figure 2: Double-click Add Command
to open the editing window.
1/3
9/2/2014
Use SQL commands to solve report problems and speed Crystal Reports
Figure 3: The SQL command editing window.
If the command is error-free, the server will send a result set back to the report. The result set will appear under the Database Fields
node in the Field Explorer. It appears as a virtual table, named Command, which contains exactly the rows and columns that your
query requested (Figure 4).
You can now treat this virtual table just like any other table. In particular, you can drag its fields onto the report, and use them in
sorting, grouping and selection criteria, in Crystal formulas, or anywhere else where CR expects a field name.
Editing a command
After you've set up your SQL command in this way, you can go back and edit it at any time. To do so,
open the Database Expert, right-click on the Command node in the Selected Tables box, and choose
Edit Command.
Example 2: Using a UNION
In the example we just looked at, the main reason to use a SQL command was to speed up the report.
But SQL commands have another major benefit: They allow us to perform complex reporting tasks that
might not otherwise be possible.
To illustrate, let's assume that you have two customer tables: one for your current customers, and
another for your archived customers. You want to create a report that shows the names and phone
numbers of all customers, regardless of whether they are current or archived.
These tables aren't related in any way, so you can't simply bring them into the report and link them
together. One solution would be to create two sub-reports, one for each of the tables. But that would
only work if you were happy to keep the two sets of customers separate. It would be no good if you
wanted to produce a single customer list, for example showing all customers in customer name order.
With a SQL command, the problem is easy to solve. You use a UNION clause to combine the two tables.
Your query would look something like this:
Figure 4: The query results
appear as a virtual table.
SELECT Lastname, Firstname, Phone
FROM CurrentCustomers
UNION SELECT Lastname, Firstname, Phone
FROM ArchivedCustomers
ORDER BY Lastname, Firstname
The result is a virtual table that contains both types of customer, in the required order. Crystal Reports won't know or care whether
the customers are current or archived; it simply sees a single, unified table.
Adding parameters to a SQL command
In many cases, you will want to parameterize your SQL command, that is, you will want to prompt the user for values that are to be
used in the query. As an example, in the totals per customer report we looked at earlier, you might want to only show customers
whose total order value exceeds a certain amount, that amount to be supplied by the user when viewing the report.
To achieve that, go back to the command editing window shown in
Figure 3. Click the Create button to the right of the Parameter List box.
You will see a dialog like the one in Figure 5. This asks for four items of
information: a name for the parameter, the text that the user will see
when prompted for a value, the data type of the value, and a default
value (only the first and third of these are mandatory).
When done, click OK. The parameter will now appear in the Parameter
List box within the editing window.
The next step is to edit the command (in the left-hand box) so that it
includes the parameter. To do so, place the insertion point where you
want the parameter to appear. Then double-click on the name of the
parameter in the box to the right. The parameter will appear in the
command in the usual CR parameter syntax, that is, preceded by a
question mark and enclosed in braces.
So, staying with our total orders per customer example, if we assume the
http://www.hexcentral.com/articles/crystal-sql-commands.htm
2/3
9/2/2014
Use SQL commands to solve report problems and speed Crystal Reports
parameter is named Cutoff, the query would look like this:
Figure 5: Setting up a parameter.
SELECT CustomerID, SUM(Order_Amount) AS Total
FROM Orders
GROUP BY CustomerID
HAVING SUM(Order_Amount) > {?Cutoff}
When the user runs or refreshes the report, they will see the standard CR parameter prompt, inviting them to enter a value for the
cutoff figure. The value they enter will then be passed to the command, which will in turn pass it to the server.
You can have as many parameters as you like in a command. Once you've created a parameter, you can edit it by clicking on its
name in the SQL Command window and then clicking the Modify button. The parameter will also appear under the Parameter Fields
node in the Field Explorer, from where it can be modified just like any other report parameter.
Example 3: A more complex query
To finish, let's look as something a little more complicated. In an earlier article, I showed a SQL Server query that will find all
addresses within a given radius of a given UK postcode (although the technique is specific to the UK, the principle can be adapted for
other countries). Using this technique, you could produce a report that shows, for example, all customers within 25 km. of a given
branch office, or all suppliers within 100 miles of your base.
The query is complicated by the fact that it calls a user-defined function (dbo.GetDistance) to determine the distance between a pair
of addresses. It also calls a couple of built-in T-SQL functions to extract the relevant part of the target address's postcode.
However, those complications are hidden within the SQL command and are therefore of no concern of Crystal Reports. The program
simply sees a virtual table containing the addresses that are to be shown in the report.
To produce this report, you need to create two parameters: one for the outcode of the starting point (the branch office, or
whatever) and one for the required radius. Remember, the radius must be expressed in the same units as the eastings and northings
in the postcode lookup table. (Outcodes, eastings and northings are all explained in the earlier article.)
You can now write the SQL command, which will look something like this (I simply pasted this code from the earlier article,
substituting the parameters for the hard-coded values):
DECLARE @Start char(5), @StartE int, @StartN int, @Radius int
SET @Start = '{?StartPoint}' -- outcode of start point
SET @Radius = {?Radius} -- radius (same precision as the parameters)
-- Get easting and northing of start point
SELECT @StartE = x, @StartN = y
FROM Postcodes
WHERE @Start = Outcode
-- Get addresses within @Radius units of start point
SELECT a.Address
FROM Addresses a
JOIN Postcodes p
ON p.Outcode = LEFT(a.Postcode, CHARINDEX(' ', a.Postcode))
WHERE dbo.GetDistance(@StartE, p.x, @StartN, p.y) <= @Radius
As you can see, this query is more like a SQL Server script, with variable declarations, SET statements, two separate SELECTs, and
the various functions calls. None of this is a problem. Provided the server can execute the code and return a result set, you can use
the code in a SQL command.
Final word
One of the best things about SQL commands is that they can be used with virtually all databases. Provided your database
understands SQL - and the vast majority of them do - you'll get the benefits. If you're using a file-based database, like Access or
Visual FoxPro, you won't necessarily see the same performance boost, but you will still be able to use SQL commands to perform
complex queries and therefore simplify your reports.
If you're comfortable writing SQL code - or if you're willing to learn - you'll find that SQL commands are a very powerful tool. Used
properly, they let you delegate complicated data-handling tasks to the database where they belong, and to focus your efforts on
using CR for what it does best: producing great-looking reports.
February 2012
Please note: The information given on this site has been carefully checked and is believed to be correct, but no legal liability can be accepted for its
use. Do not use code, components or techniques unless you are satisfied that they will work correctly with your sites or applications.
Home | What is Hex Central? | Full disclosure | Privacy policy | Contact us
© Copyright Hex Central and contributors. All rights reserved.
http://www.hexcentral.com/articles/crystal-sql-commands.htm
3/3