Firebird Documentation IndexFirebird 2.5 リリースノート → データ操作言語(DML)
Firebird Home Firebird Home Prev: データ定義言語(DDL)Firebird Documentation IndexUp: Firebird 2.5 リリースノートNext: 手続き型SQL(PSQL)

データ操作言語(DML)

Table of Contents

クイックリンク

この章では、Firebird 2.5でSQLのデータ操作言語サブセットに施された追加と改善を扱います。

クイックリンク

SIMILAR TOを用いた正規表現検索のサポート

Adriano dos Santos Fernandes

トラッカー・リファレンス CORE-769

新たなSIMILAR TO句の導入により、正規表現がサポートされました。この演算子には、与えられたSQL標準の正規表現が引数の文字列にマッチするか検証する機能があります。これは、WHERE句やCHECK制約、PSQLのIF() test文など、ブール式を受け付ける任意の文脈で有効となります。

構文パターン

<similar句> ::=
	<値> [ NOT ] SIMILAR TO <similarパターン> [ ESCAPE <エスケープキャラクタ> ]

<similarパターン> ::= <キャラクタ値表現: 正規表現>

<正規表現> ::=
      <正規項>
    | <正規表現> <バーティカルバー> <正規項>

<正規項> ::=
      <正規因子>
    | <正規項> <正規因子>

<正規因子> ::=
      <正規一次子>
    | <正規一次子> <アスタリスク>
    | <正規一次子> <正符号>
    | <正規一次子> <疑問符>
    | <正規一次子> <繰り返し因子>

<繰り返し因子> ::=
    <左波括弧> <下限値> [ <上限指定> ] <右波括弧>

<上限指定> ::= <コンマ> [ <上限値> ]

<下限値> ::= <符号なし整数>

<上限値> ::= <符号なし整数>

<正規一次子> ::=
      <キャラクタ指定子>
    | <パーセント記号>
    | <正規キャラクタ・セット>
    | <left paren> <正規表現> <右括弧>

<キャラクタ指定子> ::=
      <エスケープされないキャラクタ>
    | <エスケープされたキャラクタ>

<正規キャラクタ・セット> ::=
      <アンダースコア>
    | <左角括弧> <キャラクタ列挙>... <右角括弧>
    | <左角括弧> <サーカムフレックス> <キャラクタ列挙>... <右角括弧>
    | <左角括弧> <包含するキャラクタの列挙>... <サーカムフレックス> <除外するキャラクタの列挙 exclude>... 
        <右角括弧>

<包含するキャラクタの列挙> ::= <キャラクタ列挙>

<除外するキャラクタの列挙> ::= <キャラクタ列挙>

<キャラクタ列挙> ::=
      <キャラクタ指定子>
    | <キャラクタ指定子> <負符号> <キャラクタ指定子>
    | <左角括弧> <コロン> <キャラクタクラス識別子> <コロン> <右角括弧>

<キャラクタ指定子> ::=
      <エスケープされないキャラクタ>
    | <エスケープされたキャラクタ>

<キャラクタクラス識別子> ::=
      ALPHA
    | UPPER
    | LOWER
    | DIGIT
    | SPACE
    | WHITESPACE
    | ALNUM
      

Note

  1. <エスケープされないキャラクタ>とは、<左角括弧>、<右角括弧>、<左括弧>、<右括弧>、<バーティカルバー>、<サーカムフレックス>、<負符号>、<正符号>、<アスタリスク>、<アンダースコア>、<パーセント記号>、<疑問符>、<左波括弧>、<エスケープキャラクタ>を除く任意のキャラクタです。

  2. <エスケープされたキャラクタ>とは、<左角括弧>、<右角括弧>、<左括弧>、<右括弧>、<バーティカルバー>、<サーカムフレックス>、<負符号>、<正符号>、<アスタリスク>,<アンダースコア>、<パーセント記号>、<疑問符>、<左波括弧>、<エスケープキャラクタ>のいずれか一つが続く<エスケープキャラクタ>です。

Table 10.1. キャラクタクラス識別子

識別子 説明 注意
ALPHA 単純なラテン文字の全てのキャラクタ(a-z, A-Z) アクセントを無視したコレーションを使う場合はアクセント付きラテン文字を含む
UPPER 単純なラテン文字で大文字の全てのキャラクタ(A-Z) 大文字小文字を区別しないコレーションを使う場合は小文字を含む
LOWER 単純なラテン文字で小文字の全てのキャラクタ(a-z) 大文字小文字を区別しないコレーションを使う場合は大文字を含む
DIGIT 数字の全てのキャラクタ(0-9)  
SPACE スペースキャラクタである全てのキャラクタ(ASCII 32)  
WHITESPACE ボワイトスペースである全てのキャラクタ(垂直タブ(9)、改行(10)、水平タブ(11)、キャリッジリターン(13)、改頁(12)、スペース(32))  
ALNUM 単純なラテン文字(ALPHA)または数字(DIGIT)である全てのキャラクタ  


使用ガイド

<正規表現>または<正規項>にマッチする文字列に true を返します:

      <正規表現> <バーティカルバー> <正規項>
       
    'ab' SIMILAR TO 'ab|cd|efg'   -- true
    'efg' SIMILAR TO 'ab|cd|efg'  -- true
    'a' SIMILAR TO 'ab|cd|efg'    -- false
       

<正規一次子>のゼロ回以上の繰り返しにマッチします:<正規一次子> <アスタリスク>

    '' SIMILAR TO 'a*'     -- true
    'a' SIMILAR TO 'a*'    -- true
    'aaa' SIMILAR TO 'a*'  -- true
       

<r正規一次子>の一回以上の繰り返しにマッチします:<正規一次子> <正符号>

    '' SIMILAR TO 'a+'     -- false
    'a' SIMILAR TO 'a+'    -- true
    'aaa' SIMILAR TO 'a+'  -- true
       

ゼロ個または一個の<正規一次子>にマッチします:<正規一次子> <疑問符>

    '' SIMILAR TO 'a?'     -- true
    'a' SIMILAR TO 'a?'    -- true
    'aaa' SIMILAR TO 'a?'  -- false
       

<正規一次子>のきっかり<下限値>回の繰り返しにマッチします:<正規一次子> <左括波括弧> <下限値> <右波括弧>

    '' SIMILAR TO 'a{2}'     -- false
    'a' SIMILAR TO 'a{2}'    -- false
    'aa' SIMILAR TO 'a{2}'   -- true
    'aaa' SIMILAR TO 'a{2}'  -- false
       

<正規一次子>の<下限値>以上の繰り返しにマッチします:<正規一次子> <左波括弧> <下限値> <コンマ> <右波括弧>

    '' SIMILAR TO 'a{2,}'     -- false
    'a' SIMILAR TO 'a{2,}'    -- false
    'aa' SIMILAR TO 'a{2,}'   -- true
    'aaa' SIMILAR TO 'a{2,}'  -- true
       

<正規一次子>の<下限値>回以上<上限値>回以下の繰り返しにマッチします:<正規一次子> <左波括弧> <下限値> <コンマ> <上限値> <右波括弧>

    '' SIMILAR TO 'a{2,4}'       -- false
    'a' SIMILAR TO 'a{2,4}'      -- false
    'aa' SIMILAR TO 'a{2,4}'     -- true
    'aaa' SIMILAR TO 'a{2,4}'    -- true
    'aaaa' SIMILAR TO 'a{2,4}'   -- true
    'aaaaa' SIMILAR TO 'a{2,4}'  -- false
       

(空ではない)任意のキャラクタにマッチします:<アンダースコア>

    '' SIMILAR TO '_'    -- false
    'a' SIMILAR TO '_'   -- true
    '1' SIMILAR TO '_'   -- true
    'a1' SIMILAR TO '_'  -- false
       

任意の長さの文字列(空の文字列を含む)にマッチします:<パーセント記号>

    '' SIMILAR TO '%'         -- true
    'az' SIMILAR TO 'a%z'     -- true
    'a123z' SIMILAR TO 'a%z'  -- true
    'azx' SIMILAR TO 'a%z'    -- false
       

<正規表現>を部分式としてグループ化し、一つの<正規一次子>として使います:<左括弧> <正規表現> <右括弧>

    'ab' SIMILAR TO '(ab){2}'    -- false
    'aabb' SIMILAR TO '(ab){2}'  -- false
    'abab' SIMILAR TO '(ab){2}'  -- true
       

<キャラクタ列挙>中の一つのキャラクタにマッチします:<左角括弧> <キャラクタ列挙>... <右角括弧>

    'b' SIMILAR TO '[abc]'    -- true
    'd' SIMILAR TO '[abc]'    -- false
    '9' SIMILAR TO '[0-9]'    -- true
    '9' SIMILAR TO '[0-8]'    -- false
       

<キャラクタ列挙>中のものを除くキャラクタにマッチします:<左角括弧> <サーカムフレックス> <キャラクタ列挙>... <右角括弧>

    'b' SIMILAR TO '[^abc]'    -- false
    'd' SIMILAR TO '[^abc]'    -- true
       

<除外するキャラクタの列挙>中のキャラクタを除く<包含するキャラクタの列挙>中の一つのキャラクタにマッチします:<左角括弧> <包含するキャラクタの列挙>... <サーカムフレックス> <除外するキャラクタの列挙>...

    '3' SIMILAR TO '[[:DIGIT:]^3]'    -- false
    '4' SIMILAR TO '[[:DIGIT:]^3]'    -- true
       

<キャラクタクラス識別子>に含まれる一つのキャラクタにマッチします。上掲のキャラクタクラス識別子の一覧表を参照して下さい。<サーカムフレックス>と一緒に使い、ロジックを反転させることもできます(上記):<左角括弧> <コロン> <キャラクタクラス識別子> <コロン> <右角括弧>

    '4' SIMILAR TO '[[:DIGIT:]]'  -- true
    'a' SIMILAR TO '[[:DIGIT:]]'  -- false
    '4' SIMILAR TO '[^[:DIGIT:]]' -- false
    'a' SIMILAR TO '[^[:DIGIT:]]' -- true
       

create table department (
  number numeric(3) not null,
  name varchar(25) not null,
  phone varchar(14) 
  check (phone similar to '\([0-9]{3}\) [0-9]{3}\-[0-9]{4}' escape '\')
);

insert into department 
  values ('000', 'Corporate Headquarters', '(408) 555-1234');
insert into department 
  values ('100', 'Sales and Marketing', '(415) 555-1234');
insert into department 
  values ('140', 'Field Office: Canada', '(416) 677-1000');

insert into department
  values ('600', 'Engineering', '(408) 555-123'); -- 制約違反をチェック

select * from department
  where phone not similar to '\([0-9]{3}\) 555\-%' escape '\';
      

16進数リテラルのサポート

Bill Oliver

Adriano dos Santos Fernandes

トラッカー・リファレンス CORE-1760

16進数値とバイナリ文字列リテラルのサポートが導入されました。

構文パターン

<16進数リテラル> ::=
    { 0x | 0X } <hexit> [ <hexit>... ]

<バイナリ文字列リテラル> ::=
    { x | X } <クオート> [ { <hexit> <hexit> }... ] <クオート>

<数字> ::=
    0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

<hexit> ::=
    <数字> | A | B | C | D | E | F | a | b | c | d | e | f
      

16進数リテラル

  • 文字列中の<hexit>の数字は16を超えることはできません。

  • <hexit>の数字が8を超えた場合、定数データ型は符号付BIGINTとなります。8以下の場合のデータ型は符号付INTEGERです。

    Tip

    つまり、0xF0000000は-268435456であり、また0x0F0000000は4026531840である、ということです。

バイナリ文字列リテラル

結果として生じる文字列は、CHAR(n/2) CHARACTER SET OCTETSとして定義されます。nは<hexit>の数字です。

select 0x10, cast('0x0F0000000' as bigint)
  from rdb$database;
select x'deadbeef'
  from rdb$database;
      

GEN_UUID()関数に対する重要な変更

Adriano dos Santos Fernandes

Firebird 2.5.2より前のバージョンでは、組み込み関数GEN_UUID()は完全にランダムな文字列を返しており、RFC-4122(UUID仕様)非対応となっていました。2.5.2以降、GEN_UUID()はUUIDバージョン4に準拠した文字列を返します。一部のbitは予約されており、それ以外はランダムとなります。

Note

UUIDに準拠した文字列フォーマットは、次のようなものです。

XXXXXXXX-XXXX-4XXX-YXXX-XXXXXXXXXXXX

4は固定(バージョンを示す)で、Yは8、9、AまたはBです。

トラッカー・アイテム CORE-3238参照。

新しいUUID変換関数

Adriano dos Santos Fernandes

トラッカー・リファレンス CORE-1656 および CORE-1682

新しい組み込み関数UUID_TO_CHARとCHAR_TO_UUIDにより、UUID CHAR(16) OCTETS文字列の形式とRFC4122-compliantの形式との相互の変換が可能になりました。

ビッグエンディアンのサーバーに関する注意点

ビッグエンディアンのサーバー上のFirebird 2.5と2.5.1で、CHAR_TO_UUIDとUUID_TO_CHARは正しく動作しませんでした。変換の際にバイトやキャラクタが入れ替わり、誤った位置に置かれてしまうという不具合がありました。このバグはバージョン2.5.2以上では修正されています:トラッカー・アイテム CORE-3887を参照して下さい。ただし、このことは、バージョン2.5.2以降のCHAR_TO_UUIDとUUID_TO_CHARが、同じ入力パラメータに対して、以前のバージョンとは異なる値を返すということを意味します。

CHAR_TO_UUID()

CHAR_TO_UUID()関数はUUID(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)に対するCHAR(32) ASCII表現をストレージに最適化されたCHAR(16) OCTETS表現に変換します。

構文モデル

CHAR_TO_UUID( <文字列> )
        

select char_to_uuid('93519227-8D50-4E47-81AA-8F6678C096A1')
  from rdb$database;
        

UUID_TO_CHAR()

UUID_TO_CHAR()関数は、CHAR(16) OCTETS UUID(GEN_UUID()関数で返されるもの)をCHAR(32) ASCII表現(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)に変換します。

構文モデル

UUID_TO_CHAR( <文字列> )
        

select uuid_to_char(gen_uuid())
  from rdb$database;
        

SOME_COL = ? OR ? IS NULL句

Adriano dos Santos Fernandes

トラッカー・リファレンス CORE-2298

特に多くのDelphiプログラマからの要望を受け、カラムとパラメータが同値であるか、また、パラメータに渡された値がNULLかどうかの両方について“OR”テストを行うことができる演算子のサポートが実装されました。この構造体は、一つのクエリをプリペアしてフィルタを用いた結果のセットをリクエストし、同じクエリでフィルタを用いない別の結果のセットをリクエストするというような状況を避けるための手段としてしばしば要望されていました。

Delphiなどのプログラミング・インターフェースはパラメータにクライアントサイドのオブジェクト名を適用するため、それらのユーザーは、DSQLエンジンが以下のような使い方を認めてくれるような機能を求めていました:

  WHERE col1 = :param1 OR :param1 IS NULL
      

APIレベルでは、言語インターフェースはこのクエリを次のように翻訳します。

  WHERE col1 = ? OR ? IS NULL
      

これには二つの問題がありました:

  1. プログラマはパラメータ:param1を、二つの参照を持つ単一の変数のように扱いますが、APIにはそれができません:これは二つのパラメータで与えられます

  2. 第二のパラメータのデータ型は未知のものとなり、プログラムがこれに割り当てる方法はありません。

この問題の解決に必要だったのは、条件句“? is NULL”を扱える新しいデータ型を導入し、このようなリクエストを受け取った時に正しい処理を行えるようにFirebirdに仕込むことでした。

この実装は、次のように動作します。第一の問題の解決のため、リクエストは二つのパラメータ(われわれのDelphiの例では)を与える必要があります:

  WHERE col1 = :param1 OR :param2 IS NULL
      
  • param1”がNULLでない場合、言語インターフェースは第一のパラメータに正しい値を割り当て、XSQLVAR.sqlindをNOT NULLに設定する必要があります。XSQLVAR.sqldataはNULLのままとします。

  • param2”がNULLの場合、言語インターフェースは両方のパラメータのXSQLVAR.sqlindをNULLに設定する必要があります。XSQLVAR.sqldataはNULLのままとします。

言い換えると、 ? IS NULL中のパラメータ( ? )について:

  • XSQLVAR.sqlindは、パラメータのNULL/NON-NULLの状態に応じて設定される必要があります。これは新しい定数SQL_NULLによって記述されるパラメータの型です。

  • パラメータのSQL_NULL型のXSQLVAR.sqldataは、常にクライアントのアプリケーションからNULLポインタとして渡される必要があり、決してアクセスされることはありません。

出力セットに指定されたNULL

NULLが出力定数として指定された場合(select NULL from ...)は、SQL_NULLによってではなく、当面はCHAR(1)として記述されることになります。これは将来のバージョンで変更される可能性があります。

LIST()関数の拡張

Adriano dos Santos Fernandes

トラッカー・リファレンス CORE-1453

LIST()関数の区切り文字引数として文字列表現が認められるようになりました。

SELECT
  DISCUSSION_ID,
  LIST(COMMMENT, ASCII_CHAR(13))
FROM COMMENTS
  GROUP BY DISCUSSION_ID;
      

DATEADD()およびDATEDIFF()関数の拡張

Adriano dos Santos Fernandes

関数DATEADDとDATEDIFFにWEEKユニットが導入されました。

MILLISECOND、SECOND.MINUTE.HOURユニットはもう無効なユニットではなく、DATE引数と一緒に使用できます。

BIN_NOT()関数の追加

Adriano dos Santos Fernandes

新しい関数BIN_NOT()はその引数で実行されるbitごとのNOT演算の結果を返します。これで、バージョン2.1で追加された組み込みバイナリ関数のセットが揃ったことになります。

構文パターン

  BIN_NOT( <数字> )
      

select bin_not(flags) from x;
      

読み取り専用データベースでの一時表への書き込み

Vladyslav Khorsun

(バージョン2.5.1)読み取り専用データベースでのグローバル一時表への書き込み操作が可能になりました。

トラッカー・リファレンス CORE-3399

オプティマイザの改善

認識済みの問題に対処するオプティマイザロジックの変更には以下のものを含みます:

CROSS JOINのロジック(D. Yemanov)

CROSS JOINが空のテーブルを含んでいる場合でも、オプティマイザには、クエリが無効であることを検出してすぐに空のセットを返すための特別なロジックがありませんでした。そのショートカット・ロジックが実装されました。

トラッカー・リファレンス CORE-2200

Note

同様の変更はv.2.1.2で実装されています。

派生テーブル(A. dos Santos Fernandes)

派生テーブルの使用中に利用できるコンテキスト数の上限が拡大されました。

トラッカー・リファレンス CORE-2029

DEFAULT評価のタイミング(A. dos Santos Fernandes)

まれな状況ですが、カラムに定義されたDEFAULTの値または式に対する評価が早いと、そのカラムに与えられた入力値の評価に関して、混乱した状況を引き起こす可能性があります。この可能性については、DEFAULTの評価を延期し、実際の必要がない限り、実際には全く評価を実行しないことによって対処します。

トラッカー・リファレンス CORE-1842

NOT IN検索でのインデックスの使用(A. dos Santos Fernandes)

NOT IN句でインデックスの使用を可能にすることにより、パフォーマンスが改善されました。

トラッカー・リファレンス CORE-1137

Undoログのメモリ消費(D. Yemanov)

一度のトランザクションで長く続いた更新の後の、Undoログによる過剰なメモリ消費が回避されました。

トラッカー・リファレンス CORE-1477

その他の改善点

小さなイライラを解消するその他の変更点は、以下のものを含みます:

FREE_ITエラー検出(A. dos Santos Fernandes)

従来は、FREE_ITを使って宣言されたUDFが、返されたポインタがib_util_malloc()関数によって割り当てられなかった場合にクラッシュすることがありました。現在は、そのような状況が検出されると、例外がスローされ、ポインタは割り当てられた状態を維持します。

トラッカー・リファレンス CORE-1937

メッセージ“式の評価はサポートされていません”の改善(C. Valderrama)

多くのセカンダリGDSコードが導入されました。これにより、“式の評価はサポートされていません”の例外がスローされて失敗していた操作に関して、詳細情報が与えられるようになりました。例えば:

  'Argument for @1 in dialect 1 must be string or numeric(ダイアレクト1での@1の引数は文字列か数値でなければなりません)'
  'Strings cannot be added to or subtracted from DATE or TIME types(文字列を追加したり、DATE型やTIME型から取り去ることはできません)'
  'Invalid data type for subtraction involving DATE, TIME or TIMESTAMP types(DATE、TIME、TIMESTAMP型が必要な減算に対する無効なデータ型です)'
   など
            

これらの詳細メッセージは、ステータスベクターでのisc_expression_eval_err(式の評価はサポートされていません)エラー用のGDSコードに従っています。

トラッカー・リファレンス CORE-1799

Prev: データ定義言語(DDL)Firebird Documentation IndexUp: Firebird 2.5 リリースノートNext: 手続き型SQL(PSQL)
Firebird Documentation IndexFirebird 2.5 リリースノート → データ操作言語(DML)