0
CREATE OR REPLACE FUNCTION heckANDinsert(
    first VARCHAR(20), surname VARCHAR(20),
  No VARCHAR(30), nation VARCHAR(30), dob DATE
) RETURNS SETOF passenger AS $$
DECLARE 

name VARCHAR(20);
Sname VARCHAR(20);
Pass VARCHAR(30);
nation VARCHAR(30);
birthdate DATE;

BEGIN

SELECT first, same,passportNo, nationality,dob 
INTO fname,sname, PassportN, nation, birthdate 
FROM passenger
WHERE 
    firstname = $1 
    AND surname = $2 
    AND passportNo = $3 
    AND nationality = $4 
    AND dob = $5;

IF NOT FOUND THEN
    INSERT INTO passenger 
    SELECT MAX(passengerid)+1, $1,$2,$3,$4,$5 
    FROM passenger;
ELSE 
    RAISE EXCEPTION 'passenger record already exists.';
END IF; 

END;
$$ LANGUAGE plpgsql;

I called the function using

SELECT passenger_checkANDinsert( 
    'john', 'levis', 'v39949455', 'British', '1990-07-23'
);

the function will insert the right result into database if i change the first name to another. but it won't work if i change the surname and remain the first name same as database data. i guess there is something wrong within the select statement WHERE condition in the function, but i can't find any error for that..

4
  • sorry for the typing mistake.. firstname is a column in the database passenger table. Commented Apr 6, 2013 at 19:37
  • Why use a function instead of setting the passengerid to SERIAL and putting a unique constraint on the table? Commented Apr 6, 2013 at 20:06
  • Because the passengerid type was given INTEGER. i am not allow to change the data type for some reason. Commented Apr 6, 2013 at 20:09
  • 2
    @johnnily: you don't need to change the datatype. serial isn't a real datatype, it's just an alias for an integer which takes the default from a sequence. You can do that "manually" any time you want without the need to modify the datatype: sqlfiddle.com/#!12/e8548/1 Creating a unique value based on max() is a very bad idea. It will not work correctly and it will not scale at all. Commented Apr 6, 2013 at 20:29

2 Answers 2

1
create or replace function passenger_checkandinsert(
    _firstname varchar(20), _surname varchar(20),
    _passportno varchar(30), _nationality varchar(30), _dob date
) returns setof passenger as $$

insert into passenger (
    passengerid, firstname, surname, passportNo, nationality, dob
)
select coalesce(max(passengerid)+1, 1), $1, $2, $3, $4, $5
from passenger
where not exists ( 
    select 1
    from passenger
    where
        firstname = $1
        and surname = $2
        and passportno = $3
        and nationality = $4
        and dob = $5
    )
returning *
;
$$ language sql;
  • Using the name of columns in variables can be problematic. Just prepend an underline.
  • Declare the columns you are inserting values into.
  • Simple SQL will do all you need.
  • Don't do count to check for the existence of a row as it will read the whole table. In instead use exists as it will stop reading in the first found row.
  • Notice the coalesce to deal with the case of no rows yet.
  • returning * will return the inserted row.
1
CREATE OR REPLACE FUNCTION passenger_checkANDinsert

(firstname VARCHAR(20),surname VARCHAR(20),

passportNo VARCHAR(30),nationality VARCHAR(30),dob DATE)

RETURNS SETOF passenger AS
$$

DECLARE 

_exists boolean;    

BEGIN

SELECT count(*)>0 INTO  _exists FROM passenger      
WHERE firstname = $1 AND surname = $2 AND passportNo = $3 AND nationality = $4 AND dob = $5;

IF NOT _exists THEN

    INSERT INTO passenger SELECT MAX(passengerid)+1, $1,$2,$3,$4,$5 FROM passenger;

    ELSE 

    RAISE EXCEPTION 'passenger record already exists.';

    END IF; 

END;

$$

   LANGUAGE plpgsql;

I think you are doing bad with MAX(passengerid)+1, why don't you use the bigserial data type ? If you are doing so just to not lose sequency of this field, you are not doing right.

Perhaps you need to add sequency to your field by:

CREATE SEQUENCE passengerid_seq;
ALTER TABLE passenger ALTER COLUMN passengerid SET DEFAULT NEXTVAL('passengerid_seq');
2
  • Because the type for the passengerid was given INTEGER..i can't change it. Commented Apr 6, 2013 at 20:05
  • @johnnily See how you can add sequency without modifying the data type of passengerid field Commented Apr 6, 2013 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.