0

I need to extend an app written with Embarcadero Firemonkey for Windows to Android, so I need InterBase.

Besides there is no tutorial (none found so far at least) on how to use Firebird under Android, I have found a very important difference not only in the language itself, but in the way I can trap exceptions with Firebird and InterBase (i.e. into an insert stored procedure). Here is a sample Firebird code:

ALTER PROCEDURE AD_0_LIST_UPD_ORDER (
AD_0_NAME VARCHAR(20),
AD_0_ORDER INTEGER)
RETURNS (N_ERROR INTEGER)
AS
begin
   n_error=0;
   begin
      update ad_0_list
            set ad_0_order = :ad_0_order
          where (ad_0_name = :ad_0_name);
      when any do begin
        n_error=sqlcode;
        exit;
      end
   end
end^

What's beautiful in those few lines (when any ...) is that I have an exception that traps any SQL error, while in InterBase I have to (imagine) and write situations like -803, -625, theoretically from -1 to -999 for every procedure.

I can't fine a way to translate it. Is there a way to do this in InterBase?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197

1 Answers1

0

InterBase PSQL language has had support for WHEN ANY ... for a long time. See https://docwiki.embarcadero.com/InterBase/2020/en/Handling_Errors and https://docwiki.embarcadero.com/InterBase/2020/en/Examples_of_Error_Behavior_and_Handling

Where it seems to be limited is that it does not recognize SQLCODE as a context variable that you can get a value from for assignment in your code within the WHEN ANY block. It would be a useful enhancement, I agree.

As a sample, the following code works in InterBase, albeit not knowing the exact SQLCODE generated. But, you can catch ANY exception in InterBase PSQL as well.

set echo on; 

/* run some bad statements; see exception code(s) */

/* Expected exception: SQLCODE -413 */
insert into employee (emp_no, first_name, last_name, dept_no, job_code, job_grade, job_country, salary) 
      values (2000, 'Two', 'Thousand', 2000, 'SALES', 2000, 'USA', 1); 
/* Expected exception: SQLCODE -297 */
insert into employee (emp_no, first_name, last_name, dept_no, job_code, job_grade, job_country, salary) 
      values (2000, 'Two', 'Thousand', 'ABC', 'SALES', 2000, 'USA', 1); 
      rollback;

/* Now, do the same with procedures. */
drop procedure TEST_PROC;
COMMIT;

set term ^;
CREATE PROCEDURE TEST_PROC (runcase INTEGER)
RETURNS (N_ERROR INTEGER)
AS
begin
   n_error=0;
   begin
    /* Give bad DEPT_NO value; integral instead of CHAR(3) */
    /* Expected exception: SQLCODE -413 */
    if (:runcase = 1) then
        insert into employee (emp_no, first_name, last_name, dept_no, job_code, job_grade, job_country, salary) 
            values (2000, 'Two', 'Thousand', 2000, 'SALES', 2000, 'USA', 1);

    /* Give bad SALARY value violating a value constraint */
    /* Expected exception: SQLCODE -297 */
    if (:runcase = 2) then
        insert into employee (emp_no, first_name, last_name, dept_no, job_code, job_grade, job_country, salary) 
            values (2000, 'Two', 'Thousand', 'ABC', 'SALES', 2000, 'USA', 1); 

    /* good SQL that will succeed; no exception */
    if (:runcase = 3) then
        INSERT INTO country (country, currency) VALUES ('India', 'Rupee');

    /* check for errors */
    when any do begin
        n_error = :runcase;
        exit;
    end 
   end 
end^

set term ;^
commit;

/* Now test above procedures */
/* see if any work getting done below, by setting count option on */
set count on;
execute procedure test_proc (1);
rollback;
execute procedure test_proc (2);
rollback;
execute procedure test_proc (3);
select * from country where country='India';
rollback;
execute procedure test_proc (99);
rollback;
  • Thank you for trying to answer. But I do not need a returned parameter I know myself @ time of executing the stored procedure. I mean: n_error you return is not an exception generated by Interbase itself, but an input parameter. I would like to be aware of any value (-1 .. -999) may be returned. I.e. How is a "Foreign key violation" handled in you code ? Regards – Giovanni Brambilla Sep 03 '22 at 06:48
  • my code does not specifically check for exact error codes. InterBase does not allow accessing SQLCODE values for assignment to local variables in the stored procedures; that is a known limitation. The sample code above was just to illustrate that WHEN ANY syntax works. It you want to check for specific error codes, you will need to provide "WHEN SQLCODE ", as you know already. – Sriram Balasubramanian Sep 04 '22 at 20:53