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;

我使用

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

如果我将名字更改为另一个,该函数会将正确的结果插入数据库。但如果我更改姓氏并保持名字与数据库数据相同,它将不起作用。我猜函数中的 select 语句 WHERE 条件中有问题,但我找不到任何错误..

4

2 回答 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
$$

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;

我认为你做得不好MAX(passengerid)+1,为什么不使用bigserial数据类型?如果您这样做只是为了不丢失该字段的顺序,那么您做得不对。

也许您需要通过以下方式为您的字段添加顺序:

CREATE SEQUENCE passengerid_seq;
ALTER TABLE passenger ALTER COLUMN passengerid SET DEFAULT NEXTVAL('passengerid_seq');
于 2013-04-06T19:58:41.763 回答
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;
  • 在变量中使用列的名称可能会有问题。只需在前面加上下划线。
  • 声明要插入值的列。
  • 简单的 SQL 将满足您的所有需求。
  • 不要count检查是否存在行,因为它将读取整个表。相反exists,它会在找到的第一个行中停止读取。
  • 注意合并来处理还没有行的情况。
  • returning *将返回插入的行。
于 2013-04-06T23:26:03.620 回答