スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PL/pgSQLで動的なORDER BY句の作成

追記:2012/4/7
複数バージョンのものを作成しました。記事

PL/pgSQLの動的SQLを使っていると、ソートの部分がだいたい同じような構造をしてきます。
例えばこんな感じ。
w_sort_content := ' ORDER BY ' ||
CASE p_sort_kbn
WHEN '02' THEN
' t1.login_ts '
WHEN '03' THEN
' t1.name '
WHEN '04' THEN
' t1.mail '
WHEN '05' THEN
' t1.user_kbn '
ELSE
' t1.insert_ts '
END ||
CASE WHEN p_asc_flag THEN ' ASC ' ELSE ' DESC ' END ||
' OFFSET ' || p_offset::TEXT ||
' LIMIT ' || p_limit::TEXT;

ということで、生成する関数を作成しました。
-- ORDER BYを生成する
-- 引数
-- p_kbn_ary : 区分値の配列
-- p_column_ary : カラムの配列
-- p_kbn : 区分値
-- p_asc_flag : TRUEの時ASC
-- p_offset : オフセット
-- p_limit : リミット
-- 戻り値
-- エスケープされた文字列
CREATE OR REPLACE FUNCTION dyn_order_by(
p_kbn_ary TEXT[]
,p_column_ary TEXT[]
,p_kbn TEXT
,p_asc_flag BOOLEAN DEFAULT TRUE
,p_offset BIGINT DEFAULT 0
,p_limit BIGINT DEFAULT NULL
) RETURNS TEXT AS $$
DECLARE
w_column TEXT;
w_postfix TEXT;
BEGIN
w_postfix :=
CASE WHEN p_offset IS NOT NULL AND p_offset > 0
THEN ' OFFSET ' || p_offset::TEXT ELSE '' END ||
CASE WHEN p_limit IS NOT NULL
THEN ' LIMIT ' || p_limit::TEXT ELSE '' END || ' ';
FOR i IN 1..array_length(p_kbn_ary, 1) LOOP
IF p_kbn_ary[i] = p_kbn THEN
w_column = p_column_ary[i];
EXIT;
END IF;
END LOOP;
IF w_column IS NULL THEN
RETURN w_postfix;
END IF;
RETURN ' ORDER BY ' || w_column ||
CASE WHEN p_asc_flag THEN ' ASC ' ELSE ' DESC ' END ||
w_postfix;
END;
$$ LANGUAGE plpgsql;

使用例
select dyn_order_by('{01,02,03}','{t1.insert_ts,t1.name,t1.mail}','02',false, 10, 100);
→ ORDER BY t1.name DESC OFFSET 10 LIMIT 100
スポンサーサイト

COMMENTS

COMMENT FORM

TRACKBACK


この記事にトラックバックする(FC2ブログユーザー)

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。