キムラデービーブログ

オープンソースデータベースを加速する「キムラデービー」のブログです。カレー日記を兼ねてます。なお著者は2010-06-01より日本オラクルに在籍していますが、本サイト(ブログ、またはウェブサイト)において示されている見解は、私自身の見解であって、オラクルの見解を必ずしも反映したものではありません。
2018年の木村明治
0
    去年はこんな抱負を出していましたが、まぁまあできたのは1.くらいですかね :)

    今年の抱負は以下。

    1.出している本で、できるものは改訂作業を行う。(本にならなくてもブログで補足)
    2.分散処理の読書会に継続して出る。参照されている本をできるだけ読む。
    3.各種成果をブログで出す
    4.スケートをまじめに練習する(冬季)
    5.体重を減らす。(月一キロ目標)

    がんばりまっす。

    JUGEMテーマ:日記・一般



    | meijik | 日々 | 11:41 | comments(0) | trackbacks(0) | - | - |
    2018年のFirebird
    0
      2018年のFirebird

      本エントリはFirebird Advent Calendar 2017の25日目です。

      さて、2018年のFirebird ! といえば、まずは次版のFirebird 4.0の話になります。

      ....と書いてこれは去年のエントリと同じ! うーん。

      話としては昨日naagamiさんの書いてくれた以下のとおりなのです。

      Firebird4.0 Planning Board 2017 update(ある nakagami の日記)

      今年はちょっと補足もないですが、以下の二つの事柄を。。。。

      1.Firebird Tour 2017: Performance seminars
      去年はカンファレンスが行われましたが、今年はFirebird Tourの2017年度版ということで行われました。
      # 2012までは毎年カンファレンスが行われていましたが、それ以降は隔年になっています。

      Firebird Tour 2017: Performance Optimization
      Firebird Conference 2016
      Firebird 2015 Tour: Big Databases
      Firebird 2015 Spring Tour
      Firebird Conference 2014
      Firebird 2013 Tour
      Firebird Conference 2012

       以下のページからそれぞれ二つずつのプレゼンテーションが公開されていますので、チェックしてみてください。

      Presentations from Firebird Tour 2017: Firebird Performance and Tuning Linux and Windows

      Presentations from Firebird Tour 2017: Firebird 3 Statistics and Plans and Advanced Trace API

       木村も最後に参加したのは2008年のイタリア開催なので、来年は久しぶりに参加してみたいですね。

      2.2018のデータベースが進む道とFirebird
       これまでのRDBMSはオンプレで、いかに性能をあげるか、HAを担保するのか、を競っていたように思えますが、
      ここ数年、主戦場はオンプレからクラウドに移行してきているように感じます。そして「世の中の "マネージド" を名乗るサービスがやってくれること」が徐々に進化して、開発者がオンプレでちまちまやるよりも、そこに「丸投げ」したほうがいい(楽?)な部分が徐々に増えていると思います。と、思ったのは以下のエントリ。

      最近MySQLをやめて別のRDBMSにしたときの話(MySQL Casual Advent Calendar 2017 12日目)

      DBAをある程度極めた人が超絶技巧的にチューニングするのであれば、オンプレでエンタープライズ要素の高いRDBMSを使えばよいのですが、そこらへんは適当でよくて、各種運用をしたくない人には"マネージド"を名乗るサービスを使ったほうが幸せになれる気がします。

       さて、Firebirdはどうでしょうか? Firebird自体はオンプレで超絶技巧的にチューニングするのには向いてないし、また"マネージド"のサービスに乗ったり、Amazon Auroraに使われているMySQLやPostgreSQLのように、先進的なエンジンを利用しやすくするフロントエンド的なI/Fとして使われることもなさそうです。

      Amazon Auroraの先進性を誰も解説してくれないから解説する(武蔵野 Advent Calendar 2017 13日目)

      使いどころはやはり手間のかからないオンプレ、と組み込みだと思うので、この観点でまた地道に活動していきたいと思います。十年前から変わってないですが、エバーグリーンということで。

      適材適所のデータベース選択が重要--Firebird日本ユーザー会(ZDNet Japan)

      では、またオープンソースRDBMSの世界で!

      メリークリスマス & ハッピーニューイヤー !!

      JUGEMテーマ:コンピュータ



      | meijik | Firebird/InterBase | 05:23 | comments(0) | trackbacks(0) | - | - |
      古いFirebirdとWindows 10 Fall Creators Update
      0
        本エントリはFirebird Advent Calendar 2017の23日目です。

        ちょっと追いついていませんが、それはおいおい。。。

        さて、首記の件ですが、ちょっと前にメーリングリストで話題になっていて、
        IBPhoenixのドキュメントでもでました。現象は既存のものがアンインストールされ
        再インストールできない、というものです。

        Firebird-jp-general 2017年12月 保存書庫 スレッド

        とりあえずはインストーラ名をSetup.exeに変更することで再度案ストールはできるそうです。

        Firebird and Windows 10 Fall Creators Update(IBPhoenix)

        ご参考まで。

        JUGEMテーマ:コンピュータ



        | meijik | Firebird/InterBase | 13:50 | comments(0) | trackbacks(0) | - | - |
        FirebirdでFLOATを使(う|わない)理由
        0
          FirebirdでFLOATを使(う|わない)理由

          本エントリはFirebird Advent Calendar 2017の22日目です。

          私の本業(=家のローン払いに一番貢献している収入)はMySQLなので、最近以下のエントリを読んでモヤっとしてました。

          MySQLで6桁までの小数点を丸めずに扱うならFLOAT型を使うべき理由(Qiita)

          時間があったらコメントしないとなー、と思ってたら、すでに以下のエントリができてました。多謝。

          MySQLのFLOAT型を使う理由が見つからない件(hnwの日記)

          結論としてMySQLではFLOATがいろんなところで丸まっているので使うべきではないです。
          ではFirebirdはどうか、ということで上記エントリのFirebird版を以下に記述します。

          不思議な挙動(1)...は起こらない。INSERT時に0.9以外になる。

          CREATE TABLE a (f FLOAT, d DOUBLE PRECISION);
          INSERT INTO a VALUES(0.9,0.9);
          SELECT * FROM a;

          F D
          ============== =======================
          0.89999998 0.9000000000000000

          不思議な挙動(2)...も起こらない。f=0.9でもSELECT可能

          SELECT * FROM a WHERE f=0.9;

          F D
          ============== =======================
          0.89999998 0.9000000000000000

          SELECT * FROM a WHERE d=0.9;

          F D
          ============== =======================
          0.89999998 0.9000000000000000

          不思議な挙動(3)...も起こらない。見た数字(INSERTしてSELECTした結果)のとおりの動作です。

          CREATE TABLE b (f1 FLOAT, f2 FLOAT);
          INSERT INTO b VALUES(0.9,0.8999996); -- 8と6の間に9が五個
          INSERT INTO b VALUES(0.9,0.89999996); -- 8と6の間に9が六個

          SELECT * FROM b;

          F1 F2
          ============== ==============
          0.89999998 0.89999962
          0.89999998 0.89999998

          SELECT * FROM b WHERE f1=f2;

          F1 F2
          ============== ==============
          0.89999998 0.89999998

          結果Firebirdでは不思議な挙動はおきないのですが、おきないから、といって積極的に利用をすすめるか、
          といわれると私の答えは"No"ですね。上記ブログのまとめにもありますし、以前私が書いたブログエントリにも記述しましたが、FLOAT型を採用するメリットはサイズが小さいことだけなので、大量に使う場合(==カラムとして複数定義かつ行数が多い場合)の領域削減、時のみ検討すべきで、普通小数を含む場合: 誤差OKならDOUBLE, 誤差NGならNUMERICにすべきです。

          Firebirdで他のRDBMSから来た人に奇妙に見える振る舞いは、計算時の小数点以下の有効範囲の取り扱いでしょうか。
          以下のブログと、そこから参照しているブログ(英語)で、その振る舞いの一端がわかります。

          Firebird のお勉強 計算時の小数点以下の有効範囲(布団が俺を呼んでいる)

          P.S. Firebirdはdoubleではだめでdouble precisionと書かないとエラーです。。。。

          create table c(d double); -- NG
          Statement failed, SQLSTATE = 42000
          Dynamic SQL Error
          -SQL error code = -104
          -Token unknown - line 1, column 24
          -)
          create table c(d double precision); -- OK

          JUGEMテーマ:コンピュータ



          | meijik | Firebird/InterBase | 23:24 | comments(0) | trackbacks(0) | - | - |
          DISTINCT, COUNT, そしてNULL
          0
            本エントリはFirebird Advent Calendar 2017の14日目です。

            DISTINCT, COUNT, そしてNULL

            唐突ですが、次の文章のうち間違っているものは? SELECT文で。。。。

            (1) 行数を数えるときにはCOUNT(*)
            (2) 行数を数えるときにはCOUNT(カラム名)でも(1)と同じ
            (3) カラムのユニークな行数を数えるときはCOUNT(DISTINCT カラム名)
            (4) 複数カラムのユニークな行数を数えるときはCOUNT(DISTINCT カラム名1, カラム名2)

            じゃ確認してみましょう。

            create table t1(i1 int, i2 int);
            insert into t1 values(1,1);
            insert into t1 values(1,2);
            insert into t1 values(2,3);
            select count(*) from t1;

            COUNT
            =====================
            3

            select count(i1) from t1;

            COUNT
            =====================
            3

            (1),(2)ともによさそうに見えますね。。。。ってちょっと待ったー! もう一行nullを含む行を追加してみましょう。

            insert into t1 values(null,3);

            select count(*) from t1;

            COUNT
            =====================
            4

            select count(i1) from t1;

            COUNT
            =====================
            3

            そう、実は集約関数はNULLを除外します。ただし「COUNT(*)」は例外的にNULLを除外しないのです。
            そのため、上記のような違いが現れます。Firebirdに限らず、標準SQLに準拠しているものはすべてそうなります。

            SQLのCOUNT(*)とCOUNT(列名)では結果が異なる(山本隆の開発日誌)

            select count(distinct i1) from t1;

            COUNT
            =====================
            2

            これはまず、distinctで1,2,nullの三行になり、count(列名)はnullを除外するので、2となります。
            これはcountを除いた以下のクエリで一目両全です。(3)はOKそうですね。

            select distinct i1 from t1;

            I1
            ============
            <null>
            1
            2

            次に(4)にトライしてみると。。。。エラーですね。

            select count(distinct i1,i2) from t1;
            Statement failed, SQLSTATE = 42000
            Dynamic SQL Error
            -SQL error code = -104
            -Token unknown - line 1, column 25
            -,

            そう、Firebirdを含めたほとんどのRDBMSではCOUNT(DISTINCT マルチカラム)は許されていないのです。
            そのため、よく代案として利用されるのが、DISTINCTをサブクエリにした以下のクエリや、DISTINCTの代わりにGROUP BYを使うものです。

            select count(*) from (select distinct i1,i2 from t1);

            COUNT
            =====================
            4

            もう一つはカラムを、そのカラムに出てこないデリミタを入れてCONCATするものです。

            select count(distinct i1 || '-' || i2) from t1;

            COUNT
            =====================
            3

            OK, って一行減ってますね。。。。これもcountを除くと意味がわかります。

            select distinct i1 || '-' || i2 from t1;

            CONCATENATION
            =======================
            <null>
            1-1
            1-2
            2-2

            NULLをCONCATするとNULLになり、それはCOUNTに計上されません。そのため巷のDISTINCTをサブクエリに
            する方法は、データにNULLがあると正しくないのです。厳密にいうと、こうなります。

            select count(*) from (select distinct i1,i2 from t1 where i1 is not null and i2 is not null);

            COUNT
            =====================
            3

            本ブログエントリの最初のほうで「ほとんどのRDBMSではCOUNT(DISTINCT マルチカラム)は許されていない」
            と記述しましたが、唯一許されているのがMySQLです。

            create table t1(i1 int, i2 int);
            insert into t1 values(1,1);
            insert into t1 values(1,2);
            insert into t1 values(2,3);
            insert into t1 values(null,3);

            select count(distinct i1,i2) from t1;
            +-----------------------+
            | count(distinct i1,i2) |
            +-----------------------+
            | 3 |
            +-----------------------+
            1 row in set (0.03 sec)

            ということで、正しくでるのですが、DISTINCTしたマルチカラムそれぞれにIS NOT NULLをANDでつけていないクエリで
            NULLを含むデータを投入して「結果が違う〜」という向きがいるので、それはこのような違いがある、ということを
            覚えておいてください!

            結果(1),(3)はOK, (2)は違う(カラムがnot nullならOK), (4) はMySQLだけ、ということになります。

            JUGEMテーマ:コンピュータ



            | meijik | Firebird/InterBase | 19:55 | comments(0) | trackbacks(0) | - | - |
            プログラマのためのSQL第四版読書会(12)11.時間型 (p.225)
            0
              読書会はゆるゆると続けていましたが、なかなかアウトプットができず。。。。
              とりあえず最新回から順にさかのぼってアウトプットします。。。

              プログラマのためのSQL 読書会(12) - connpass

              [Typo]
              (1) p.226
              ユリウス暦は4年につき1日の閏年をもっており、

              ユリウス暦は4年につき1日の閏日をもっており、
              (2) p.230
              ランダムに近いデータ作る簡便な方法ではある。

              ランダムに近いデータを作る簡便な方法ではある。
              (3) p.234
              11.3 INVERVAL型の冒頭
              「以下にこのデータ型のBNF定義を示す」の後のBNF定義がない。
              英語版にはある。
               ただ、その後のINTERVAL型は期間をあらわすデータ型だ〜の部分は原著4thにはなく、
              5thの冒頭部分なので、中途半端に間違えている原著をミックさんがつかまされて :)
              原著はしれっとなおしている可能性もあり。。。。

              [原著の??な点]
              p.227 「英語話者においては、年は4桁、月は3文字、日は2桁であらわすのがもっとも誤読誤記が少なくソートするときも便利だとい

              うことを発見した」ですが、月を3文字(例: 12月はDec)とすると、ソートには便利ではないのでは? という話がでた。確かに文字列
              としては月の3文字はソートすると1->2->3月というわけではないので。
               ただ、日付や日付時刻型だと三文字月は入出力のときだけで、内部では別に英字で格納されているわけではないので、特に問題とはならない気もしてきた。後で考えると。

              [用語]
              EDIFACT


              [人物]
              p.228の訳注とp.237
              アリゾナ大学のリチャード・T・スノッドグラス
              Richard Snodgrass

              アレサンドロ・メサ
              →Alejandro Mesa , Microsoft SQLサーバのMVPらしい。SQL Server関連からよく参照されている。

              [ドキュメント・書籍]
              p.237で紹介している二冊
              (1) Developing Time-Oriented Database Applications in SQL (Richard Snodgrass著, Morgan Kaufmann, 1999)
              (2) How to Design, Update and Query Temporal Data (Tom Johnston, Randall Weis著, Morgan Kaufmann, 2010)

              前者はpdfで公開されているので、まず読みたい。(2)は未読。また、アマゾンで検索してみるとTom Johnstonの別の著作と
              Dateの著作がヒットした。これらも購入して、時間がみつけて、読んでみたい。

              (3) Bitemporal Data: Theory and Practice (Tom Johnston著, Morgan Kaufmann, 2014)
              (4) Time and Relational Theory, Second Edition: Temporal Databases in the Relational Model and SQL (C.J. Date,‎ Hugh Darwen,‎ Nikos Lorentzos 著 Morgan Kaufmann 2014)

              [所感]
              暦の細かい説明や、Septemberの語源などは「へぇー」の連続でしたが、その部分は特にSQLには役立たなさそう。トリビア的な感じです。

              読書会の次回は年明け(2018年) 1/15 or 22の月曜日となりそうです。
              [2018-01-02 追記]
              2018-01-22(mon)となりました。ご参加お待ちしております。

              プログラマのためのSQL 読書会(13) 12.文字列型 (p.243)

              JUGEMテーマ:コンピュータ



              | meijik | SQL | 00:37 | comments(0) | trackbacks(0) | - | - |
              FirebirdでPostgreSQL(標準SQL?)のCURRENT_TIMESTAMPを模倣
              0
                本エントリはFirebird Advent Calendar 2017の14日目です。

                FirebirdでPostgreSQL(標準SQL?)のCURRENT_TIMESTAMPを模倣


                現在セルコ著、ミックさん翻訳のプログラマのためのSQLを絶賛読書会中(参加者絶賛募集中!)なのですが

                プログラマのためのSQL 読書会(12)

                その「11章時間型」にも記述がありますし、(プログラマのためのSQL第四版(日本語版と英語版からの引用))

                →ここから引用
                タイムスタンプはシステムの時計を一度だけ読み、同一トランザクション内のすべての項目に同じ時間を適用する。
                Remember that a TIMESTAMP will read the system clock once and use that same time on all the items involved in a transaction.
                ←ここまで引用

                去年のFirebird Advent Calendar 2016でとりあげましたが他とは違うPostgreSQL(とVertica)の実装が正しいように見えます。

                使い慣れたSQLに潜む実装依存: Firebirdの場合(5) CURRENT_TIMESTAMP

                今回はその動作をFirebirdで模倣する方法について考えてみました。

                基本的には以下の考えでいけるはずです。

                (1) トランザクションの開始時刻をシステムから取得する。
                (2) (1) をコンテキスト変数に格納する。
                (3) トランザクション内のCURRENT_TIMESTAMPを参照する部分を(2)に置き換える。

                (1)
                トランザクションの開始時刻を知るにはモニタリングテーブルのうち、以下のテーブルを使います。

                MON$TRANSACTION

                現在のトランザクションIDはcurrent_transaction, 現在の接続はcurrent_connectionで取得できますので、
                MON$TRANSACTIONから、トランザクション開始時刻を求めるクエリは以下になります。

                select mon$timestamp from mon$transactions where current_connection = mon$attachment_id and current_transaction=mon$transaction_id;

                MON$TIMESTAMP
                =========================
                2017-12-13 22:56:49.3670

                (2)
                これをユーザコンテキスト変数'CurrentTS'にrdb$set_contextを使って値を設定します。以下のクエリとなります。

                select rdb$set_context('USER_TRANSACTION', 'CurrentTS', (select mon$timestamp from mon$transactions where current_connection = mon$attachment_id and current_transaction=mon$transaction_id)) from rdb$database;

                RDB$SET_CONTEXT
                ===============
                1

                (3)
                 (2)で格納した値をrdb$get_contextを使って利用します。
                たとえば以下のようにtimestamp列に現在時刻を挿入していた場合、

                insert into ts1 values(current_timestamp);

                以下のように変更すれば、トランザクション中は、トランザクション開始時刻を設定することが可能です。

                insert into ts1 values((select rdb$get_context('USER_TRANSACTION', 'CurrentTS') from rdb$database));

                JUGEMテーマ:コンピュータ



                | meijik | Firebird/InterBase | 09:05 | comments(0) | trackbacks(0) | - | - |
                Firebird CTEでFizzBuzz
                0
                  Firebird CTEでFizzBuzz

                  本エントリはFirebird Advent Calendar 2017の13日目です。

                  DEKOさんが以下のエントリを書いていたので、それのCTE(Common Table Expression)版を作ってみました。

                  Firebird SQL のストアドプロシージャで FizzBuzz(FizzBuzz Advent Calendar 2017)

                  WITH RECURSIVE my_cte AS
                  (
                  SELECT 1 AS i from rdb$database
                  UNION ALL
                  SELECT 1+i FROM my_cte WHERE i<20
                  )
                  SELECT CASE
                  WHEN (mod(i,3)=0) AND (mod(i,5)=0) THEN 'Fizz Buzz'
                  WHEN mod(i,3)=0 THEN 'Fizz'
                  WHEN mod(i,5)=0 THEN 'Buzz'
                  ELSE i END
                  FROM my_cte;

                  実行するとこんな感じ。

                  CASE
                  ==========
                  1
                  2
                  Fizz
                  4
                  Buzz
                  Fizz
                  7
                  8
                  Fizz
                  Buzz
                  11
                  Fizz
                  13
                  14
                  Fizz Buzz
                  16
                  17
                  Fizz
                  19
                  Buzz

                  CTEの再帰クエリで連番を生成し、それを検索CASE式で分岐しています。

                  連番の生成の説明は以下をご覧ください。

                  MySQL 8.0 Lab版: MySQLの (再帰)共通テーブル式(CTE)(Yakst)

                  検索CASE式については以下をご覧ください。

                  CASE式のススメ(リレーショナル・データベースの世界)

                  JUGEMテーマ:コンピュータ



                  | meijik | Firebird/InterBase | 02:17 | comments(0) | trackbacks(0) | - | - |
                  Firebirdでカジュアルに再帰クエリでUPDATE/DELETE
                  0
                    Firebirdでカジュアルに再帰クエリでUPDATE/DELETE

                    本エントリはFirebird Advent Calendar 2017の12日目です。

                    さて、CTEはOSSのRDBMSの中でも、わりと早い時期(Firebird 2.1)に実装したFirebirdですが、
                    最近のCTEのようにUPDATE, DELETE, INSERTなどには対応せず、SELECTのみの対応になります。
                    そのFirebirdで、先日紹介したPostgreSQLのようにUPDATEやDELETEをする方法をお知らせします。

                    PostgreSQLでカジュアルに再帰クエリ実行with共通表式(CTE:Common Table Expression)

                    1.前準備
                    UPDATEのためにあらかじめtimestamp列を追加しておきます。

                    CREATE TABLE shain(empid INT PRIMARY KEY, name VARCHAR(20), mgrid INTEGER,ts timestamp);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 1, 'みやはら', NULL);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 2, 'きむら', 1);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 3, 'かまたき', 1);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 4, '加藤', 2);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 5, '林', 2);
                    INSERT INTO shain(empid,name,mgrid) VALUES ( 6, '三浦', 5);

                    UPDATE shain SET mgrid = (SELECT empid FROM shain WHERE name='かまたき') WHERE name = '林';

                    2.UPDATE/DELETE

                    CTEのSELECTをUPDATE条件の副問い合わせの中にいれてUPDATEです。

                    UPDATE shain SET ts = CURRENT_TIMESTAMP WHERE empid IN (
                    WITH RECURSIVE n AS
                    (
                    SELECT empid, name FROM shain WHERE name = 'かまたき'
                    UNION ALL
                    SELECT nnext.empid, nnext.name FROM shain as nnext, n WHERE n.empid= nnext.mgrid
                    )
                    SELECT empid FROM n);

                    FirebirdではUPDATE ... FROMができないため、結合してのUPDATEはできません。

                    Update a table with join?(Stack Overflow)

                    DELETEはUPDATEと同様に、以下のとおりです。

                    DELETE FROM shain WHERE empid IN (
                    WITH RECURSIVE n AS
                    (
                    SELECT empid, name FROM shain WHERE name = 'かまたき'
                    UNION ALL
                    SELECT nnext.empid, nnext.name FROM shain as nnext, n WHERE n.empid= nnext.mgrid
                    )
                    SELECT empid FROM n);

                    JUGEMテーマ:コンピュータ



                    | meijik | Firebird/InterBase | 06:31 | comments(0) | trackbacks(0) | - | - |
                    Firebirdでデータの歯抜けを探す(NULLあり、の続き)
                    0
                      Firebirdでデータの歯抜けを探す(NULLあり、の続き)

                      本件はFirebird Advent Calendar 2017の11日目です。

                      一昨日のブログ書いてから気づいたんですが、以下の条件に加えてもうひとつ条件がありました。

                      条件1: seqは整数
                      条件2: seqは1からはじまり、1ずつ増えていく連番
                      条件3: seqはNULLではない。
                      条件4: (seq+1)はオーバーフローしない
                      条件5: seqは重複しない

                      つまり、seqをINTEGERで宣言すると条件1を満たし、さらにUNIQUE制約をつけると条件5、
                      さらにPRIMARY KEYにすれば条件条件3, ダメ押しでMySQLでいう「AUTO_INCREMENT」的な
                      機能をつけると条件4以外を満たすことになります。

                      ただしAUTO_INCREMENTはMySQL特有の機能でFirebirdにはないので

                      3.6.9 AUTO_INCREMENT の使用(MySQL 5.6 日本語マニュアル)

                      Firebirdでは以下のブログやそこから参照している"Firebird Generator Guide"を参考にしてみてください。

                      FirebirdでSEQUENCEを使う。(山本隆の開発日誌)

                      さて、一昨日はWindow関数を使わない解法でしたが、Window関数を使った場合でNULLが含まれているとどうでしょう?
                      表の状態は一昨日の状態(つまり2017-12-08の表に、null行を二行追加したもの)で、2017-12-08の解法をそのまま使うと
                      どうなるでしょうか?

                      select coalesce(max(seq), 0) + 1 as gap
                      from (select seq, Row_Number() over(order by seq) as Rn
                      from SeqTbl) a
                      where seq = Rn;

                      GAP
                      =====================
                      9

                      あれ、正しい4でなく、9が戻りました。2017-12-08のように、副問い合わせの中身だけで確認すると以下のとおりです。

                      select seq, Row_Number() over(order by seq) as Rn from SeqTbl;

                      SEQ RN
                      ============ =====================
                      <null> 1
                      <null> 2
                      1 3
                      2 4
                      3 5
                      5 6
                      6 7
                      8 8 <- たまたま一致した行のmax(seq) + 1で9が戻る

                      これを避けるためには、NULLを省いて、SEQの先頭を1にそろえる必要があります。
                      簡単な方法はorder byにnulls lastを加えて、nullの行をソートした結果の最後においやる方法です。

                      select coalesce(max(seq), 0) + 1 as gap
                      from (select seq, Row_Number() over(order by seq nulls last) as Rn
                      from SeqTbl) a
                      where seq = Rn;

                      GAP
                      =====================
                      4

                      これで無事正しい値が求まりました。Firebirdのnulls lastについては以下のブログ記事をご参照ください。

                      使い慣れたSQLに潜む実装依存: Firebirdの場合(10) ORDER BY でのNULLの扱い

                      JUGEMテーマ:コンピュータ



                      | meijik | Firebird/InterBase | 00:11 | comments(0) | trackbacks(0) | - | - |
                       123456
                      78910111213
                      14151617181920
                      21222324252627
                      28293031   
                      << January 2018 >>
                      + RECOMMEND
                      100人のプロが選んだソフトウェア開発の名著 君のために選んだ1冊
                      100人のプロが選んだソフトウェア開発の名著 君のために選んだ1冊 (JUGEMレビュー »)

                      100人のうちの一人としてミックさんの本を推薦しています。
                      + RECOMMEND
                      MySQL 5.1 Plugin Development
                      MySQL 5.1 Plugin Development (JUGEMレビュー »)
                      Andrew Hutchings,Sergei Golubchik
                      MySQL 5.1 のプラグインを作るならこれ!
                      + RECOMMEND
                      AWKを256倍使うための本 (Ascii 256倍)
                      AWKを256倍使うための本 (Ascii 256倍) (JUGEMレビュー »)
                      志村 拓,鷲北 賢,西村 克信
                      ここにきてまさかの復刊。15〜16年前の本ですが、いまでも十分役立ちますよ!!
                      + RECOMMEND
                      Linux-DB システム構築/運用入門 (DB Magazine SELECTION)
                      Linux-DB システム構築/運用入門 (DB Magazine SELECTION) (JUGEMレビュー »)
                      松信 嘉範
                      Linux-DB システム構築の新スタンダード。DB Magazine人気連載、待望の書籍化です!!
                      + RECOMMEND
                      + RECOMMEND
                      超・極める!MySQL
                      超・極める!MySQL (JUGEMレビュー »)
                      坂井 恵,志村 和彦,ひろせ まさあき,松信 嘉範
                      内容は少々古くなりましたが、内部説明があり、いろいろ面白いです。
                      + RECOMMEND
                      The Root of .NET Framework
                      The Root of .NET Framework (JUGEMレビュー »)
                      荒井 省三
                      .NETの根っこをつかむ、か?
                      + RECOMMEND
                      エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド
                      エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド (JUGEMレビュー »)
                      奥野 幹也
                      これまでにない構築、そして構築後のMySQLのための本。
                      + RECOMMEND
                      Database Management Systems
                      Database Management Systems (JUGEMレビュー »)
                      Raghu Ramakrishnan,Johannes Gehrke
                      ミックさん連載の参考書籍です。
                      + RECOMMEND
                      Advanced Programming in the UNIX Environment: Paperback Edition (2nd Edition) (Addison-Wesley Professional Computing Series)
                      Advanced Programming in the UNIX Environment: Paperback Edition (2nd Edition) (Addison-Wesley Professional Computing Series) (JUGEMレビュー »)
                      W. Richard Stevens,Stephen A. Rago
                      必読! といいつつ私が読んだのは初版の日本語訳です。差分はチェックしないといけませんね。
                      + RECOMMEND
                      + RECOMMEND
                      + RECOMMEND
                      Western Digital Scorpio Blue 2.5inch 5400rpm 320GB 8MB PATA WD3200BEVE
                      Western Digital Scorpio Blue 2.5inch 5400rpm 320GB 8MB PATA WD3200BEVE (JUGEMレビュー »)

                      DELL SX260の換装用に購入。今はコチラのほうが安いですね。
                      + RECOMMEND
                      情熱プログラマー ソフトウェア開発者の幸せな生き方
                      情熱プログラマー ソフトウェア開発者の幸せな生き方 (JUGEMレビュー »)
                      Chad Fowler
                      OSC2010神戸に出展されたジュンク堂で買いました。
                      + RECOMMEND
                      Software Design 総集編 【2000~2009】(DVD付)
                      Software Design 総集編 【2000~2009】(DVD付) (JUGEMレビュー »)

                      メガトン級の過去記事。売り切れる前にお店に急げ!
                      + RECOMMEND
                      + RECOMMEND
                      玄人志向 2.5型HDDケース SATA対応USB2.0接続 GW2.5AI-SU2
                      玄人志向 2.5型HDDケース SATA対応USB2.0接続 GW2.5AI-SU2 (JUGEMレビュー »)

                      Aspire 1410 HDD換装後、昔のHDDはこれにいれます。
                      + RECOMMEND
                      + RECOMMEND
                      acer Aspire Timeline AS1410 11.6型ノートPC Windows7搭載 250GB ブラック AS1410-KK22
                      acer Aspire Timeline AS1410 11.6型ノートPC Windows7搭載 250GB ブラック AS1410-KK22 (JUGEMレビュー »)

                      色違い黒(他に青と白があります): メモリは最大4GBとあるが、がんばれば8GBいけるらしい。
                      + RECOMMEND
                      Firebird 徹底入門
                      Firebird 徹底入門 (JUGEMレビュー »)
                      木村 明治,はやし つとむ,坂井 恵
                      Firebird日本ユーザ会のはやしさん、そしてMyNAから拝借(?) してきた坂井さんとともに書きました。まだ誰も知らないFirebird 2.5や、いままでドキュメントのなかったツール類についてもソースを確認してとりあげた本です。是非ご活用ください。
                      + SELECTED ENTRIES
                      + RECENT COMMENTS
                      • 使い慣れたSQLに潜む実装依存: Firebirdの場合(6) 文字列との結合演算子
                        noname (12/10)
                      • 毎月日経SYSTEMSが届くたびに?が増え続ける: 日経SYSTEMSのコラム「ITアーキテクチャーの真髄」と「第7正規化」
                        Moriaki_ (01/05)
                      • 毎月日経SYSTEMSが届くたびに?が増え続ける: 日経SYSTEMSのコラム「ITアーキテクチャーの真髄」と「第7正規化」
                        Moriaki_ (01/05)
                      • 2015年版 InterBaseの歩み
                        nakagami (12/06)
                      • 毎月日経SYSTEMSが届くたびに?が増え続ける: 日経SYSTEMSのコラム「ITアーキテクチャーの真髄」と「第7正規化」
                        meijik (11/22)
                      • 分散DB本読書会第46回メモ「STOP AFTER 10」
                        masudahidehiko (09/01)
                      • Windows上でのMySQLビルド方法
                        kinoyasu (03/31)
                      • 気軽に新しいMySQLを試してみる: MySQL Sandboxのススメ
                        MeijiK (09/19)
                      • 伝わらない曲シリーズ: 川島恵「ミスター不思議」
                        96 (07/05)
                      • 気軽に新しいMySQLを試してみる: MySQL Sandboxのススメ
                        MeijiK (02/17)
                      + RECENT TRACKBACK
                      + CATEGORIES
                      + ARCHIVES
                      + MOBILE
                      qrcode
                      + LINKS
                      + PROFILE