Subject Re: [ib-support] Converting Interbase to Firebird
Author Helen Borrie
At 10:43 PM 4/05/2003 -0500, you wrote:
>On Sun, 2003-05-04 at 21:47, Helen Borrie wrote:
> > At 09:34 PM 4/05/2003 -0500, you wrote:
> > >Where I work we are using Interbase 7 with Delphi for a commercial
> > >product.
>
>
> > I get 'Dynamic SQL Error
> > >expression evaluation not supported.'
> > >
> > >Any ideas on what's wrong?
> >
> > It's impossible to analyse without the exact text of the DDL that is
> > failing. Post the DDL.
> >
> > heLen
> >
>Here's one of the blocks that gives this error. I did some mangling of
>the variable names in order to protect our clients product.
>
>
>
>ALTER PROCEDURE PROC_CHECK_XXX
>(
> CONTROL_XXX INTEGER,
> XXX_ID INTEGER,
> READDATE TIMESTAMP,
> XXX_VALUE FLOAT,
> HIGHLIMIT FLOAT,
> LOWLIMIT FLOAT,
> CURR_TIME TIMESTAMP
>)
>AS
>
> DECLARE VARIABLE SourceNumber varchar(65);
> DECLARE VARIABLE TrendInterval int;
> DECLARE VARIABLE AvgXXX_VALUE float;
>
> BEGIN
>
> IF ((XXX_VALUE > HighLimit) OR (XXX_VALUE < LowLimit)) THEN
> BEGIN
>
> SELECT TrendInterval
> FROM Sensor WHERE XXX_ID = :XXX_ID INTO :TrendInterval;
>
> IF (TrendInterval > 0) THEN
> BEGIN
> SELECT
> AVG(XXX_VALUE)
> FROM
> SensorLog
> WHERE
> XXX_ID = :XXX_ID AND
> CONTROL_XXX = :CONTROL_XXX AND
> LogDate BETWEEN (:Curr_Time - (((1/24) / 60) *
>:TrendInterval)) AND :Curr_Time
> INTO :AvgXXX_VALUE;
> END

Up to here, it all looks pretty right...

>
>
> IF ((AvgXXX_VALUE > HighLimit) OR (AvgXXX_VALUE < LowLimit))
>THEN
> BEGIN
> SELECT SourceNumber FROM Sensor WHERE XXX_ID = :XXX_ID INTO
>:SourceNumber;

OK

> EXECUTE PROCEDURE PROC_InsAlarm (:SourceNumber, :CONTROL_XXX,
>:ReadDate, :HighLimit, :LowLimit, :XXX_VALUE);

This one has wrong use of the :colon marker. A procedure call passes
constants, not parameters.

>
> UPDATE ControlPoint SET AlarmState = 1 WHERE CONTROL_XXX =
>:CONTROL_XXX;

This is correct use of the :colon marker, because you are using the input
variable in a DSQL statement.

> POST_EVENT 'Rebuild_xxx';
> END
> END
>
> END
> ;

This semicolon doesn't belong here. At this point, you are still using
your alternative terminator, which you would have set before the beginning
of the ALTER statement, e.g.

SET TERM ^ ;

Thereafter, until you reset the terminator, statements inside the SP are
terminated with semicolons and the "wrapping" ALTER statement is terminated
with ^.

...so you would have
AS
BEGIN
...
BEGIN
<procedure body statements> ;
END
END ^

COMMIT WORK ^

SET TERM ; ^

Another thing - don't trust float types for equivalence comparisons. You
are almost guaranteed to get "false negatives" because of precision errors
in the internal calculations.

Use scaled numerics for this kind of logic.

heLen