• 締切済み

PL/PGSQL

pl/pgsql にて。 select avg(price) into wk_price from uriage_tbl where ymdtm <= current_timestamp and ymdtm >= current_timestamp + '-4 hour'; と4時間前から直近まで価格の平均を求める構文があったとして、この-4 を、希望する任意の数字で変動したいと思っています。 -4 部分を変数にするには、どのようにすればよいか、お分かりの方がいらっしゃればお教え願います。 日付型の計算だと、上記のようにシングルクオーテーション内に引数を持たせるので、その中で変数を持たせるところでつまづいてます。

みんなの回答

回答No.2

考え方としては、時間型の変数を定義して加減算します。 例えば、 current_timestamp + time '04:00:00' を変数で行う場合、以下のようにします。 declare vTime time; vTime:='04:00:00'; current_timestamp + vTime 以下に例を示します。 (1)表定義例 create table uriage_tbl (ymdtm timestamp without time zone, price int); (2)プロシジャ定義例 create or replace function avg_price (pPM char(1), -- '+' or '-' pHour time without time zone) -- 'hh:mm:ss' returns dec(10,2) as $$ declare wAvg dec(10,2); begin raise info 'pPM=%,pHour=%',pPM,pHour; if pPM='+' then select into wAvg -- 標準SQLと語順が異なっている avg(price) from uriage_tbl where ymdtm>=current_timestamp and ymdtm<=current_timestamp + pHour; elseif pPM='-' then select into wAvg -- 標準SQLと語順が異なっている avg(price) from uriage_tbl where ymdtm>=current_timestamp - pHour and ymdtm<=current_timestamp; else wAvg:=null; end if; raise info 'wAvg=%',wAvg; return wAvg; end; $$ language 'plpgsql' ; (3)プロシジャ実行例 select avg_price('+','04:00:00'); select avg_price('-','04:00:00'); <注意> PostgreSQL 8.2前後で、select intoの語順が変更になっているようです。 PostgreSQL 8.0では、「select into 変数 avg(列名) from 表名」、 PostgreSQL 8.2では、「select avg(列名) into 変数 from 表名」 上記の例題は、PostgreSQL 8.0での記述になっています。

全文を見る
すると、全ての回答が全文表示されます。
  • Dodonpa2
  • ベストアンサー率82% (19/23)
回答No.1

こんにちは。 動的にSQLステートメントを作成してはいかがでしょう。 CREATE OR REPLACE FUNCTION fn_getavg(integer) RETURNS NUMERIC AS $$ DECLARE wk_price NUMERIC := -1; BEGIN EXECUTE 'SELECT avg(price) ' || 'FROM public.uriage ' || 'WHERE ymdtm <= current_timestamp ' || 'AND ymdtm >= current_timestamp + interval ''' || to_char($1,'9') || ' hour''' INTO wk_price; return wk_price; END; $$LANGUAGE plpgsql; ------------------------------------------------------------- こんな感じの関数をつくって、 SELECT public.fn_getavg(-4); を実行。

TAI_0824
質問者

お礼

回答案ありがとうございます。なるほどですね、これを参考に作成してみます。 私のこの質問でこのレベルの回答が頂けるとは、とても嬉しい限りです!仕事を手伝って欲しいくらいです。笑。 COBOL上がりでSQL、PL/PGSQL的な考え方が若干苦手であります。。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PL/pgSQLについて

    お世話になっております。 PL/pgSQLでPostgreSQLのあるテーブルにinsertがかかったら、別のテーブルをtriggerを使ってupdateする構文を書いていますが、上手くいきません。 insertを実行すると、変数が割り当てられていない旨が表示されます。 サンプルは以下の通り DROP FUNCTION k_trig(); CREATE FUNCTION k_trig() RETURNS OPAQUE AS' DECLARE ov1 RECORD; ov2 RECORD; BEGIN SELECT * FROM 個別集計 INTO ov1 WHERE id = new.id; UPDATE 個別集計 SET a1 = ov1.a1 + new.a1, a2 = ov1.a2 + new.a2, a3 = ov1.c + new.a3 WHERE id = new.id; *****以下省略 insert実行 ↓ 「record ov1 is unassigned yet」と表示されます。 declareで宣言しているのですが・・・ 何が原因か教えてください

  • PL/SQLの変数について

    困っています。 ホスト引数で :NAME = "あいうえお" としてoracleに渡し、 PL/SQLでNAMEという変数で受け取った後、 Xという変数にその"あいうえお"を'あいうえお' のように、シングルクォーテーションで囲んで入れたいのです。 ですが、 NAME = 'X' としたら文字列として認識してしまい、 NAME = ''X'' としたらPLS-00103のエラーが出てしまいます。 シングルクォーテーションで囲んだ文字列を変数にセットする場合はどのように書いたら宜しいのでしょうか??

  • 引数について

    すみません・・・。 ACCESSを使用してSQL構文を作成しているのですが 下記のようなテーブルを作成してpriceがnullのものだけ抜き出して ’ヌル値’と表示させたいと思っておりますが 「(tbl3.price,'ヌル値')の関数で使用されている引数の数が正しくない」というエラーとなってしまいます。 こちら原因は何によるものか教えて頂けないでしょうか・・・。 よろしくお願い致します。 id1,name id3,name 1 a     1  300 2 b     2  500 3 c     4  500 4 d     6  1200 5 e     8  1500 6 f     9  1500 7 g     10  10000 8 f 9 h 10 i select tbl1.id ,name ,price ,isnull(tbl3.price,'ヌル値') from tbl1 LEFT JOIN tbl3 ON tbl1.id=tbl3.id where price is null

  • PL/pgSQLの使い方

    PL/pgSQLについて質問させてください。 以下のような2つのテーブルAとBがあります。 テーブルA: aid | fall0 | fall1 -----+-------+------- 001 | 0 | 0 002 | 0 | 0 テーブルB: bid | aid | fall --------+-----+------ 000001 | 001 | 0 000002 | 001 | 0 000003 | 002 | 0 000004 | 002 | 0 テーブルAとテーブルBの関係は1:nの関係です。 以下のような2つのことがやりたいです。 テーブルAのfall0,fall1,テーブルBのfallはフラグです。 今、テーブルBのaid=001であるすべての行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall1が0から1にかわる。またテーブルBのaid=001である少なくとも一つの行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall0が0から1にかわるようなプログラムを作りたいのですが、なかなかうまくいきません。今aid=001のときをやりましたが、aidは任意のときを想定しています。もし、ご存知の方がいらっしゃいましたら教えていただけないでしょうか? よろしくお願いいたします。以下は自分が書いたプログラムです。 drop table b; drop table a; create table A ( aid text primary key, fall0 integer, fall1 integer ); create table B ( bid text primary key, aid text not null references A(aid), fall integer ); insert into A values ('001',0,0); insert into A values ('002',0,0); insert into A values ('003',0,0); insert into B values ('000001','001',0); insert into B values ('000002','001',0); insert into B values ('000003','002',0); insert into B values ('000004','002',0); /* 関数の定義 */ create function tri_test() returns trigger as ' begin declare aid_rec if old.fall=0 and new.fall=1 then update a set fall1=1 where a.aid = select b.aid from b where b.fall = 1); end if; return new; end; ' language 'plpgsql'; /* トリガーの定義 */ create trigger tri_b after update or insert on b for each row execute procedure tri_test(); /* B テーブルへのデータ操作 */ update b set fall=1 where aid='001';

  • pearの認証(Auth)ができません。

    下記のサイトを参考にして認証サンプルを作成しました。 http://blueeyesblue.cocolog-nifty.com/technote/2007/09/pearauthmdb2-e2.html 下記のコマンドを実行してインストール済みかを確認しました。 pear list -------------------------------------------------- Auth 1.6.4 stable MDB2 2.5.0b3 beta MDB2で正常にデータベースに接続できるかを確認しました。 問題なく接続できました。 下記のテキストボックスに値を入力して[Login]ボタンをクリックしたら下記のエラーが出力されました。 ・Username ・Password ※ログイン画面はAuthのデフォルト画面を使用しています。 [エラー] login failed テーブルは下記のように作成しています。 CREATE TABLE TBL_USER (  no BIGSERIAL PRIMARY KEY,  name VARCHAR(64) NOT NULL,  mail VARCHAR(128) NOT NULL,  password VARCHAR(128) NOT NULL,  del VARCHAR(1) DEFAULT '0' NOT NULL,  ins_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  ins_name VARCHAR(64) NOT NULL,  upd_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  upd_name VARCHAR(64) NOT NULL ); ※テーブルのpasswordフィールドに格納している値は下記のように生成して追加しました。 mkpasswd -l 7 php -r 'echo md5(*******);' ※md5に指定している値はmkpasswdで出力された値を指定しました。 サンプルコードは下記の個所のみを変更しました。 $options = array(  "dsn" => "pgsql://ユーザー名:パスワード@localhost/データベース名",  "table" => "TBL_USER",  "usernamecol" => "name",  "passwordcol" => "password", ); 正直、何が原因なのかわからず困っています。 どうかご存知の方がいましたらアドバイスいただけませんでしょうか。 また今まで認証は1から自作していましたがpearの認証は使いやすいみたいな記事を読んだので使用しようと思いましたが・・・ 自作の認証とpearの認証ではどちらがいいのでしょうか。 ご意見等、何でも構いませんので教えていただけませんでしょうか。 宜しくお願いします。

    • 締切済み
    • PHP
  • ストアドプロシージャの引数にフィールド名を指定したい

    以下のようにストアドプロシージャを作成し、 ------------------------------------------------------------ CREATE FUNCTION test(integer) RETURNS integer AS'  DECLARE   aaa ALIAS FOR $1;  BEGIN   IF aaa BETWEEN 1 AND 5 THEN    RETURN 5;   ELSIF aaa BETWEEN 6 AND 10 THEN    RETURN 10;   ELSIF aaa BETWEEN 11 AND 15 THEN    RETURN 15;   END IF;  END;' LANGUAGE 'plpgsql'; ------------------------------------------------------------ 以下のようなSQL構文でこのプロシージャを使用したいと思っています。 ------------------------------------------------------------ select test(フィールド名) from テーブル名; ※「フィールド名」のフィールドにはinteger型のデータが入っています。 ------------------------------------------------------------ が、このSQLを実行すると以下のようなエラーが出ます。(CSE使用) ------------------------------------------------------------ WARNING: Error occurred while executing PL/pgSQL function test WARNING: at END of toplevel PL block WARNING: Error occurred while executing PL/pgSQL function test WARNING: at END of toplevel PL block SQL実行中に以下のエラーが発生しました。 WARNING: at END of toplevel PL block ------------------------------------------------------------ このように、ストアドプロシージャの引数にフィールド名を指定することはできないのでしょうか。 どなたかご教示ください。

  • PL/SQLとPL/pgSQLの違い

    こんにちは。 現在の環境がOracle8iで、次のシステムがPostgreSQLで構築されることになりました。 今後に向けてPL/SQLを勉強しようと思ったのですが、PostgreSQLにはPL/pgSQLというストアドプロシージャが有ると言うことを知りました。 そこで質問なのですが、PL/SQLとPL/pgSQLは何か大きな違いは有るのでしょうか? PL/SQLの勉強をすれば、PL/pgSQLも出来るようになるのかを教えていただけますでしょうか。

  • PL/pgSQL 引数の数

    PL/pgSQL を使用し更新処理を行いたいのですが、 パラメータの数が多すぎるのか 以下のエラーでデータベースにファンクションを定義出来ません。 ERROR: functions cannot have more than 100 arguments SQLステート:54023 可変長引数で作成すると、データベースに定義は出来るのですが ファンクション実行時に同様のエラーが発生し更新処理が行えません。 PL/pgSQL の引数を100以上使用出来る様にする設定等、存在するのであれば 教えて頂きたいです。 環境は以下の内容です。 CentOS-6.2-x86_64 Apache/2.2.15 PostgreSQL 9.1.3 PHP Version 5.3.3 (PDOを使用しています)

  • pl/pgsqlで変数の扱い

    pl/pgsqlで変数が文字列として扱われてしまうのですがどうすればいいのでしょうか。 具体的には以下のような感じです。 CREATE OR REPLACE FUNCTION test_func() RETURNS VOID AS $$ DECLARE test_val TEXT ; ofs_num INTEGER := 0; lmt_num INTEGER := 0; t_name TEXT := 'schema1.table1'; BEGIN SELECT INTO ret_val * FROM t_name OFFSET ofs_num LIMIT lmt_num; END; $$ LANGUAGE plpgsql; 上記のofs_numやlmt_numは変数として認識してくれるのですが FROMに続く「t_name」が変数ではなくそのままの文字列として認識されてしまいます。 t_nameを変数として認識させる方法はありませんでしょうか。 教えていただけると助かりますm(_)m

  • pl/pgsqlで再帰呼び出しは可能でしょうか。

    pl/pgsqlで再帰呼び出しは可能でしょうか。 PostgreSQLのバージョンは9.2.3です。 作成しているファンクションは正方形の中心座標を求めてInsertするものです。 指定した回数だけ、再帰的に正方形を4分割にどんどん細分化していき、 それぞれの正方形の中心座標をInsertします。 4分割にした正方形をそれぞれ以下のように番号を振って説明します。  左上・・・(1)  右上・・・(2)  左下・・・(3)  右下・・・(4) 元の正方形を求めた後、(1)→(2)→(3)→(4)の順に再帰的にファンクションを呼び出します。 パラメータを「3回」以上にした場合は、(1)についてもまた4分割していきます。 ここで、パラメータを「1回」とした場合は、元の正方形の中心座標は当然Insertできます。 パラメータを「2回」とした場合、(1)の正方形の中心座標も求まりますが、 (1)の正方形については再帰の最終処理のため、Insert後にRETURNすることで エラーとなっているのか、1つ目の正方形のレコードも(2)の正方形のレコードも Insertされていません。 さらにはその「RETURN句」が元のファンクションすら「終了」させているようで、 (2)、(3)、(4)の正方形の処理が行われません。 このように再帰呼び出しをしたいと思っても、再帰中の処理を終わらせ、 呼び出し元に戻らせるはずのRETURN句が、一番最初のファンクションの「終了」と 理解されてしまい、pl/pgsqlでは再帰呼び出しは実現できないのでしょうか。 ファンクションのイメージは以下の通りです。 CREATE OR REPLACE FUNCTION Insert_squre( IN kaisuu INT, --再帰的に呼び出す回数 IN count INT, --再帰回数をカウント IN X1 INT, --正方形の左上の頂点のX座標 IN Y1 INT, --正方形の左上の頂点のY座標 IN X2 INT, --正方形の右下の頂点のX座標 IN Y2 INT --正方形の右下の頂点のY座標 ) RETURNS void AS $$ DECLARE /* 変数定義 */ ・・・・・ BEGIN /* 中心座標を求める */ ・・・・・ /* 中心座標をInsert */ ・・・・・ /* kaisuu=countならばRETURN */ ・・・・・ /* (1)の正方形について再帰処理 */ select Insert_squre( IN kaisuu INT, --再帰的に呼び出す回数 IN count+1 INT, --再帰回数をカウント IN X1 INT, --正方形の左上の頂点のX座標 IN Y1 INT, --正方形の左上の頂点のY座標 IN X3 INT, --正方形の右下の頂点のX座標 IN Y3 INT --正方形の右下の頂点のY座標 ); /* (2)の正方形について再帰処理 */ ・・・・・ /* (3)の正方形について再帰処理 */ ・・・・・ /* (4)の正方形について再帰処理 */ ・・・・・ RETURN; END; $$ LANGUAGE PLpgSQL;

祖父のお世話について
このQ&Aのポイント
  • 都内の家から2時間半程度の距離に住む入院中の祖母のお世話に、脳梗塞を患っていて自宅で一人暮らしをしている祖父が頼んできました。
  • 私は仕事をしていないため時間に余裕はありますが、旅行や友人との約束もあり、それらをキャンセルしたくありません。
  • 私自身、障害者手帳持ちで精神疾患があり、疲れやすいため、ヘルパーさんを呼ぶ方向で考えています。
回答を見る