views:

377

answers:

3

If you create a Crystal Report using the built in wizard, tables are linked, etc. What determines whether a parameter makes it into the actual SQL statement? Also, why does it enclose everything in double quotes?

For example:

Here would be my base SQL Statement as generated by CR:

SELECT "poitem"."fpono"
,      "pomast"."fcompany"
,      "pomast"."fvendno"
,      "poitem"."fpartno"
,      "poitem"."fitemno"
,      "poitem"."frelsno"
,      "poitem"."fordqty"
,      "poitem"."frcpqty"
,      "poitem"."fucostonly"
,      "poitem"."flstpdate"
FROM "M2MDATA01"."dbo"."pomast" "pomast"
     INNER JOIN "M2MDATA01"."dbo"."poitem" "poitem"
     ON "pomast"."fpono" = "poitem"."fpono"

Now, watch what happens when I add the following into the select expert editor:

{poitem.fcategory} = "INV" and
not ({poitem.fmultirls} = "Y" and
{poitem.frelsno} = "  0") and
{poitem.fordqty} > {poitem.frcpqty} and
cdate({poitem.flstpdate}) = {?LastPromDate} and
{poitem.forgpdate} = DateTime (2010, 10, 05, 00, 00, 00) and 
{pomast.fstatus} = "OPEN"

I added the forgpdate for comparison since I'm asking for dates two different ways.

Here is the SQL I get:

 SELECT "poitem"."fpono"
,      "pomast"."fcompany"
,      "pomast"."fvendno"
,      "poitem"."fpartno"
,      "poitem"."fitemno"
,      "poitem"."frelsno"
,      "poitem"."fordqty"
,      "poitem"."frcpqty"
,      "poitem"."fucostonly"
,      "poitem"."flstpdate"
,      "poitem"."fcategory"
,      "poitem"."fmultirls"
,      "pomast"."fstatus"
,      "poitem"."forgpdate"
FROM "M2MDATA01"."dbo"."pomast" "pomast"
     INNER JOIN "M2MDATA01"."dbo"."poitem" "poitem"
     ON "pomast"."fpono" = "poitem"."fpono"
WHERE     "poitem"."fcategory" = 'INV'
      AND("poitem"."fmultirls" <> 'Y'
          OR "poitem"."frelsno" <> '  0')
      AND "poitem"."fordqty" > "poitem"."frcpqty"
      AND("poitem"."forgpdate" >= {TS '2010-10-05 00:00:00'}
          AND "poitem"."forgpdate" < {TS '2010-10-05 00:00:01'})
      AND "pomast"."fstatus" = 'OPEN'

Most of it is transferred directly, however it converted my "Not" statement.

Also, notice how my cdate line was not sent at all, but is resolved within Crystal itself.

Does anyone know exactly how Crystal decides what to do? I work with some large databases and need my criteria in the SQL statement otherwise Crystal returns huge datasets which waste time, memory, and processing.

TIA.

+1  A: 

why does it enclose everything in double quotes?

Double quotes are the ansi standard way to enclose object names. It's the safe, cross-platform way to make sure your company's table and column names won't conflict with a reserved keyword somewhere.

The main part of question seems to be why it does your variable comparision client side. There I'm afraid I can't help you. My best guess is that it's something to do with what indexes are available, except it'd be odd for Crystal to know too much about that.

Joel Coehoorn
+1  A: 

The format of the SQL it generates is partly dependent on the version of Crystal and the data provider. If you use ODBC, it will always put quotes around everything as this syntax is the ansi standard. The same will generally apply when reporting against SQL Server and other data sources. However, if for example you create a report in Crystal 8.5 and use the SQL Server datasource provider, it will generate SQL without the quotation marks (ie just a plain SELECT MyTable.MyField FROM MyTable). I believe this behaviour was changed in version 9 for any SQL Server datasource, but it is not an across the board change. In Crystal 11, using the native provider rather than ODBC for an Informix datasource will not generate the quoted SQL as above.

As for how it evaluates what to do in the SQL, that is dependent on how much it can rewrite in the data source's SQL. Any formula using a Crystal function (such as the CDate one you've used) can usually only ever be evaluated within Crystal itself. To maximize the work the server does, don't use any Crystal functions, summary fields or Switch statements. The exact amount it can convert again depends on the provider. Sometimes it's simply not possible to convert it all. There's also an option to Use Indexes On Server For Speed which can make things quicker, but doesn't really help much with what gets executed where.

CodeByMoonlight
+1  A: 

You will have more control over the SQL statement if you use a Command object, rather than individual tables. Database | Database Expert..., expand the desired database server's root nood, then click 'Add Command'. Enter desired SQL statement. Add parameters as required.

The parameters that are created in the Command object are much less flexible than the ones that you define in the report itself. You can choose to have parameters defined in the Command object (which will be automatically added to the report) and additional parameters defined in the report, which will be applied as the report reads record from the database (obviously less efficient).

Craig
Only available in Crystal 9 upwards, of course. And not as quick as a server-side stored procedure.
CodeByMoonlight
I appreciate that and would normally do it that way. I write all of my SQL outside of Crystal and use the command object. However, I was trying to convince an associate about the efficiency of doing so rather than using the Crystal Wizard. That's how this problem arose. Do you know how Crystal decides what to add to the original SQL statement?
DavidStein
@CodeByMoonlight: Assuming that the SQL statement is the same, I doubt that the performance difference between the stored procedure and the 'raw' SQL is terribly significant. One also needs to consider the extra cost and experience required in developing and maintaining a SP. I prefer views myself, at least they tend to be reused across multiple reports.
Craig
@David: I don't know why they choose to re-write the SQL, though I've seen it myself on many occasions.I never use the Crystal Wizard--I think it is for amateurs. I used to teach the 'official' Crystal Reports classes and was required to tell students about it. Personally, I would strip that waste of space...
Craig
The question that you are really asking is: Does the Database 'Expert' generate SQL that is as efficient as hand-coded SQL? Clearly, hand-coded is going to be more efficient and flexible. Inline-views, UNIONs, CTEs (WITH statements) are some of the many benefits of hand-coded SQL. The of the more significant downside of using hand-coded SQL (via the Command object), of course, is the difficultly working with multi-select and range parameters. While there are work arounds, they tend to limit your design frequency.
Craig
As far as the Record Selection Formula is concerned, if you can work within the bounds of the product, you will have well-performing and more maintainable code.
Craig
The stored procedure has an advantage because it is precompiled and therefore some of the server-side optimization work is already taken care of. A command object in Crystal gets less benefit from this, although the difference is generally minimal.
CodeByMoonlight
I like views too, with the caveat that Crystal can't pick up the indices on the underlying tables (and views aren't indexable on SQL Server except in the Enterprise/Developer editions).
CodeByMoonlight
And a view is purely for ease of use and controlling the fields exposed, no performance benefit over a direct query to the table.
CodeByMoonlight
What you said is true. It would be interesting to see what the time differential is between a report using a SP and one using a 'raw' SQL (assuming the same query).My biggest gripe with database developers that get involved with report development is their tendency to use SP for everything--using a sledge hammer when a hammer will do. In my 15 years of developing reports, I can say that I've used SPs for < 1% of the reports.
Craig
I try and avoid using an SP for Crystal whenever possible as it inhibits the adaptability of the report. You can't join SPs to other objects without a massive performance hit - you end up writing another SP
CodeByMoonlight