Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PL/SQLをPL/pgSQLにした話を同人誌にした話

540 views

Published on

第10回PostgreSQLアンカンファレンス@東京で発表した資料です。OracleのPL/SQLで書かれたストアドをPostgreSQLのPL/pgSQLにした話をネタに、同人誌にした話を紹介しています。

Published in: Data & Analytics
  • Be the first to comment

  • Be the first to like this

PL/SQLをPL/pgSQLにした話を同人誌にした話

  1. 1. PL/SQLをPL/PGSQLに した話 を同人誌にした話 目黒 聖(めぐろ・た かし)
  2. 2. 自己紹介 名前  目黒聖(めぐろ・たかし) 職業  某都内中小SI勤務  PostgreSQL歴3年 趣味  アニメ見ること  漫画読むこと  居合道 Twitter  まぐろ @tameguro  アイコン通りオタクです
  3. 3. 案件 Oracle 10gからPostgreSQL 9.2への移行 既存のPL/SQLを活かしたい そもそも移行できるのか? 移行できるとして工数はどのくらいかかるのか? 検証!!
  4. 4. PL/SQLをPL/PGSQLにする PL/SQLとPL/pgSQLは何が違う?  書き方が似ているが、似ているだけ  PostgreSQLにはパッケージやボディという概念がない  ファンクション間で共通する変数・関数がない  ファンクション内でトランザクション制御ができない  Oracle独自の機能を呼び出されているとPostgreSQLの基本機能では対応で きない
  5. 5. 書き方は似ているだけ CREATE FUNCTIONも構文が違う  RETURNではなく、RETURNS  関数本文の扱いが文字列 データ型を書き換える  数値型、文字列型、日付型などは、比較的単純に置き換えればよい  TABLE型やEXCEPTION型(ユーザ定義例外)などは、単純には置き換えられな い  余計な処理を追加するか、諦める PL/SQL独自の構文も書き換える  %NOTFOUND  よく似たFOUND変数を参照  %ROWCOUNT  GET DIAGNOSTIC構文を使用して、直前のSQLの結果件数を取得
  6. 6. パッケージとボディ パッケージ内で共有できるグローバル変数  変数用の一時テーブルを作成して、そこに保持すれば擬似的にグローバル変 数ができるのでは?  わざわざファンクションのためだけにテーブルを追加するのは…  変数の型は?異なるデータ型の変数は、全部別テーブル?  グローバル変数はやめて、ファンクション内のローカル変数にする  受け渡しは引数で渡す パッケージはスキーマで代用  スキーマにパッケージと同じ機能はないが、書き方が同じだから パッケージに変数が定義されて、ボディには定義されていな い場合もあるので両方とも確認  関数のソースを読みたいがためにボディだけ見ていると、たまに痛い目を見 ます
  7. 7. サブプログラム ファンクション内ファンクション、プロシージャ内ファンク ション  PL/pgSQLにはサブプログラムはないので、ファンクションはすべて別々の ファンクションとして、CREATEする必要あり  サブプログラム間で共有していた変数は、引数として渡すように変更 異なるファンクションに、同じ名前のサブプログラムがある 場合に注意  場合によってはファンクションを統合したり分割したりしなければならず、 もとのソースから大きく変わることもある
  8. 8. トランザクション制御不可 PL/pgSQLではファンクション内でCOMMITまたはROLLBACK は実行できません!! でも、PL/SQLのバッチでは結構頻繁にやってます!! どう対応する?  仕様を精査して、COMMIT不要だったら削除する  COMMITが必要な場合、そこで別ファンクションに分け、ファンクションの 呼び出し元でCOMMITする  もともとのソースとはどんどんかけ離れた姿に 正直、PL/pgSQLで作成したファンクションでバッチ処理は向 いていない
  9. 9. POSTGRESQL 11では? PostgreSQL 11でストアド・プロシージャが実装され、プロシー ジャ内でCOMMIT/ROLLBACKができるようになりました しかし、まだ制限が… このプロシージャを動かすと CREATE OR REPLACE PROCEDURE transaction_test() AS $$ DECLARE r RECORD; BEGIN BEGIN FOR r IN SELECT * FROM test2 ORDER BY x LOOP INSERT INTO test1 (a) VALUES (r.x); COMMIT; END LOOP; EXCEPTION WHEN others THEN RAISE NOTICE 'SQLSTATE=%,MESSAGE=%', SQLSTATE, SQLERRM; ROLLBACK; END; END; $$ LANGUAGE plpgsql;
  10. 10. POSTGRESQL 11では? こうなります EXCEPTION区が存在するブロック内では、 COMMIT/ROLLBACKができません わりとありそうなロジックなので、ちょっと残念です # call transaction_test(); NOTICE: SQLSTATE=2D000,MESSAGE=サブトランザクションの実行中はコミットできません CALL
  11. 11. ORACLE独自の機能 たとえばDBMS_OUTPUTのような機能を一から作るのか? Orafce  Oracleと互換性のあるインタフェースで、Oracleの機能をPostgreSQLでも 実行できるようにする拡張機能  すごく便利  DBMS_OUTPUT.PUT_LINE  UTL_FILE.GET_LINE  ファイルの最終行まで読み込むと、NO_DATA_FOUND例外を投げるので、EXCEPTIONでCATCH してファイル読み込みを終了させる、不思議な仕様  ただし、PL/pgSQLでは例外を投げるとBEGIN~EXCEPTIONの処理はアボートされるので、ファイ ルを1行ずつ読み込んで、テーブルにINSERTするような処理ではすべてが水の泡  UTL_FILE.GET_NEXTLINE  Oracleには存在しない、Orafce独自の関数  最終行まで読み込むとNULLを返すので、NULL判定してEXITすれば、処理がアボートされずに済む
  12. 12. 検証結果 相当無理すればPL/SQLをPL/pgSQLに移行可能 性能は、PL/SQLよりPL/pgSQLのほうが劣る それなら最初から別の言語にしても同じくらいの労力では? 別のDBMSに移行するなら、今までの資産をすべては有効活用 できないことも伝える 結果的にこの案件は諸事情があって検証のみで終了してし まったが、もしも移行を行うなら、既存のシステムに詳しい 人、Oracleに詳しい人、PostgreSQLに詳しい人が絶対に必要  孤軍奮闘して疲れ果てました…
  13. 13. 話は変わりますが オタクなので同人誌を買いに行くこともあります 技術書典という、技術系同人誌のみの即売会に 行ったのですが、RDBMSについての同人誌はほと んどありませんでした  ネットで探す情報は断片的なものが多く、体系的ではない印 象  本を読んで勉強したい  自分が知りたいことが書いてあるPostgreSQLの本がない なければ自分で作ればいいじゃない  ちょうど技術書典でいい本が…  「Re:VIEW」という書籍執筆支援ツールで、テキストを書い てビルドすればいい感じのPDFを出力してくれるすぐれもの の紹介
  14. 14. 意外に作れるものです 私は残念ながらオタクで、そして、友人もオタクです 同人誌を出している友人も多数います やり方は教えてもらえる  印刷所を紹介してもらえたのは非常にラッキーでした
  15. 15. というわけで作りました • 2017年12月29日の冬コ ミで初めて頒布 • 30部(+予備10部)作成し、 なんと完売!! • その後再版の希望の声があ り、調子に乗って100部再 版 • まだまだ在庫あります!
  16. 16. 同人誌というアウトプット ブログ等、ネットでのアウトプットのほうが、無料でいつで も気軽にできますし、広範囲に公開できますが、直接反応を もらえるのはやはり貴重 なにより自分で作ったものが形になってそこにあるというの は代えがたい感慨がある 皆さんの知識と経験を本にして読みたい 一度、やってみましょう!! いえ、やってください!!

×