I have a Windows application written in C# using embedded firebird sql version 2.5.5.26952, which I am re-working it to update to embedded firebird sql version 4.0.0.2496. I have update the fdb file to the new version,and all the tables and sprocs, are there. When run a cmd.Fill() command for a selected statement rows are returned, if I do a update for a row in the table, I get the expected results back fine. but If I do a insert nothing is returned, and no errors are thrown, but the data is added to the database. If I run the sproc from the FireRobin application, the data is inserted, and a row is returned, so I'm at a loss to know why it is not working from my C# application. below is slimmed down version of the code.
The 2.5 version is using FirebirdSql.Data.FirebirdClient.4.10.0.0
The 4.0 version is using FirebirdSql.Data.FirebirdClient.9.0.2
using (var cmd = new FbDataAdapter("PROC_UPSERTPEOPLE", _connection)
{
DataTable data = new DataTable();
cmd.SelectCommand.Parameters.Add("SURNAME", FbDbType.Text).Value = item.Surname;
cmd.SelectCommand.Parameters.Add("FORENAMENAME", FbDbType.Text).Value = item.Forename);
var transaction = _connection.BeginTransaction();
cmd.SelectCommand.CommandType = CommandType.StoredProcedure;
cmd.SelectCommand.Transaction = transaction;
var result = cmd.Fill(data);
transaction.Commit();
}
On a update result contains 1, and data has the expected result, but on a insert result = 0, and data has no rows in.
Any help would be appreciated.
This is the simple version fo the sproc in question
CREATE OR ALTER PROCEDURE PROC_UPSERTPEOPLE_SLIM
(
RECID INTEGER,
SURNAME VARCHAR(100),
FORENAME VARCHAR(100)
)
RETURNS
(
ID INTEGER,
LSURNAME VARCHAR(100),
LFORENAME VARCHAR(100)
)
AS
DECLARE VARIABLE local_id integer;
DECLARE VARIABLE local_surname varchar(100);
DECLARE VARIABLE local_forename varchar(100);
BEGIN
select
ID,
FORENAME,
SURNAME
FROM
APA_PEOPLE
WHERE
(:RECID IS NOT NULL AND ID = :RECID)
OR (:RECID IS NULL
AND FORENAME = :FORENAME
AND SURNAME = :SURNAME)
INTO
:local_id,
:local_forename,
:local_surname;
IF (:local_id IS NULL) then
begin
UPDATE OR INSERT INTO APA_PEOPLE(FORENAME, SURNAME)
VALUES(:FORENAME, :SURNAME)
MATCHING (FORENAME, SURNAME);
end
else
begin
UPDATE APA_PEOPLE SET FORENAME = :FORENAME,
SURNAME = :SURNAME
WHERE ID = :local_id;
end
FOR
SELECT
ID,
SURNAME,
FORENAME
from
APA_PEOPLE
WHERE
(:RECID IS NOT NULL AND ID = :RECID)
OR (:RECID IS NULL
AND FORENAME = :FORENAME
AND SURNAME = :SURNAME)
INTO
:ID,
:LSURNAME,
:LFORENAME
DO
begin
suspend;
end
END;
Update
To answer my own question, being mainly a TSQL developer, DSQL seems strange, change the sproc to the following, which is simpler
CREATE OR ALTER PROCEDURE PROC_UPSERTPEOPLE_SLIM (
RECID integer,
SURNAME varchar(100),
FORENAME varchar(100)
)
RETURNS (ID integer)SQL SECURITY INVOKER
AS
BEGIN
UPDATE OR INSERT INTO APA_PEOPLE(FORENAME, SURNAME)
VALUES(:FORENAME, :SURNAME)
MATCHING (FORENAME, SURNAME)
RETURNING ID INTO :ID;
END;
but also had to change the way it was called, to use
EXECUTE PROCEDURE PROC_UPSERTPEOPLE_SLIM(@RECID, @SURNAME, @FORENAME)
This does seem counter intuitive, I had assumed a stored procedure was a stored procedure, and there are not two different flavors. Oh well it works now, so move on to getting the rest of the app to work.