通常、保存された機能を使用し、複雑なチェック制約のために。
便利な方法でそれを作るために私の試みがあります:すべての
まず:ここ
create type post as (
title varchar(100),
content varchar(10000)
);
create function is_filled(post) returns bool immutable language sql as $$
select $1.title is not null and $1.content is not null
$$;
with t(x) as (values(('a','b')::post), (('a',null)::post), ((null,null)::post))
select *, is_filled(x), (x).is_filled from t;
╔═══════╤═══════════╤═══════════╗
║ x │ is_filled │ is_filled ║
╠═══════╪═══════════╪═══════════╣
║ (a,b) │ t │ t ║
║ (a,) │ f │ f ║
║ (,) │ f │ f ║
╚═══════╧═══════════╧═══════════╝
あなたは個人的に、私は二番目に好き(関数呼び出しの2つの構文を見ることができます - それはより多くのOOPのような)
次です:
create function is_filled(post[]) returns bool immutable language sql as $$
select bool_and((x).is_filled) and $1 is not null from unnest($1) as x
$$;
with t(x) as (values(('a','b')::post), (('a',null)::post), ((null,null)::post))
select (array_agg(x)).is_filled from t;
名前は同じだがパラメータが異なる関数を使用できることに注意してください。PostgreSQLではOkです。
最後に:
create table blogs (
one_post post check ((one_post).is_filled),
posts post[] check ((posts).is_filled)
);
insert into blogs values(('a','b'), array[('a','b'),('c','d')]::post[]); -- Works
insert into blogs values(('a','b'), array[('a','b'),(null,'d')]::post[]); -- Fail
insert into blogs values(('a',null), array[('a','b')]::post[]); -- Fail
PS:私たちの実験をクリアするためのスクリプト:
/*
drop table if exists blogs;
drop function if exists is_filled(post);
drop function if exists is_filled(post[]);
drop type if exists post;
*/
ありがとう!非常にエレガントなソリューション。 –