WHILE
WHILE ステートメントを使用して、フローを制御します。これによって、WHILE 条件が真である限り繰り返しコードを実行することができます。オプションで、DO および END WHILE を付けて WHILE ステートメントを使用することができます。
メモ: WHILE ステートメントの構文を混合して使用することはできません。DO および END WHILE 付きの WHILE 構文または WHILE のみの構文のいずれかを使用できます。
WHILE 条件で複数のステートメントを使用する場合は、BEGIN と END を使ってステートメント ブロックの始まりと終わりを示す必要があります。
構文
[ラベル名:] WHILE プロシージャ検索条件 [DO] [プロシージャ ステートメント[; プロシージャ ステートメント]]...
[END WHILE] [ラベル名]
備考
WHILE ステートメントは開始ラベルを持つことができ、そのような場合は、ラベル付き WHILE ステートメントと呼ばれます。
例
次の例では、変数 vInteger の値が 10 になってループが終了するまで、変数の値が 1 ずつ増加します。
WHILE (:vInteger < 10) DO
SET :vInteger = vInteger + 1;
END WHILE
関連項目
文法要素の定義
以下は、文法構文で使用される要素定義のアルファベット順一覧です。
変更オプション ::= 変更オプション-リスト1 | 変更オプション-リスト2
変更オプション-リスト1 ::= 変更オプション | (変更オプション[, 変更オプション]...)
変更オプション ::=
ADD [
COLUMN]
列定義 | ALTER [COLUMN] 列定義
| DROP [COLUMN] 列名
| DROP CONSTRAINT 制約名
| MODIFY [COLUMN] 列定義
変更オプション-リスト2 ::= PSQL_MOVE [COLUMN] 列名 TO [[PSQL_PHYSICAL] PSQL_POSITION] 新しい列位置 | RENAME COLUMN 列名 TO 新しい列名
as またはセミコロン ::= AS | ;
before/after ::= BEFORE | AFTER
呼び出し引数 ::= 位置引数[, 位置引数]...
列制約 ::= NOT NULL
| NOT MODIFIABLE
| UNIQUE
| PRIMARY KEY
| REFERENCES テーブル名 [(列名)] [参照アクション]
照合順序名 ::= '文字列'
列制約定義 ::= [CONSTRAINT 制約名] 列制約
列定義 ::=
列名 データ型 [
DEFAULT 式] [
列制約定義 [
列制約定義]...[
CASE |
COLLATE 照合順序名]
列名 ::= ユーザー定義名
コミット ステートメント ::= COMMIT ステートメント参照
比較演算子 ::= < | > | <= | >= | = | <> | !=
制約名 ::= ユーザー定義名
相関名 ::= ユーザー定義名
カーソル名 ::= ユーザー定義名
データ型 ::=
データ型名 [(
桁数[,
小数位])]
データベース名 ::= ユーザー定義名
式 ::= 式 - 式
| 式 + 式
| 式 * 式
| 式 / 式
| 式 & 式
| 式 | 式
| 式 ^ 式
| (式)
| -式
| +式
| ~式
| ?
| リテラル
| スカラー関数
| {fn スカラー関数}
| USER
リテラル ::= '文字列' | N'文字列'
| 数字
| {d '日付リテラル'}
| {t '時刻リテラル'}
| {ts 'タイムスタンプ リテラル'}
式またはサブクエリ ::= 式 | (クエリ スペック)
フェッチ方向 ::= NEXT
グループ名 ::= ユーザー定義名
インデックス定義 ::= (インデックス セグメントの定義[, インデックス セグメントの定義]...)
インデックス名 ::= ユーザー定義名
インデックス番号 ::= ユーザー定義の値(0 から 118 までの整数)
インデックス セグメントの定義 ::= 列名 [ASC | DESC]
挿入/更新/削除 ::= INSERT | UPDATE | DELETE
挿入値 ::= values句
| クエリ スペック
結合定義 ::= テーブル参照 [INNER] JOIN テーブル参照 ON 検索条件
| テーブル参照 CROSS JOIN テーブル参照
| 外部結合の定義
ラベル名 ::= ユーザー定義名
リテラル ::= '文字列' | N'文字列'
| 数字
| {d '日付リテラル'}
| {t '時刻リテラル'}
| {ts 'タイムスタンプ リテラル'}
order-by式 ::= 式 [CASE | COLLATE 照合順序名] [ASC | DESC]
外部結合の定義 ::= テーブル参照 外部結合タイプ JOIN テーブル参照 ON 検索条件
外部結合タイプ ::= LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]
パラメーター ::= パラメーター タイプ名 データ型 [DEFAULT プロシージャ式 | = プロシージャ式] | SQLSTATE
パラメーター タイプ名 ::= パラメーター名
| パラメーター タイプ パラメーター名
| パラメーター名 パラメーター タイプ
パラメーター タイプ ::= IN | OUT | INOUT | IN_OUT
パラメーター名 ::= [:] ユーザー定義名
パスワード ::= ユーザー定義名 | '文字列'
位置引数 ::= 式
桁数 ::= 整数
述部 ::= 式 [NOT] BETWEEN 式 AND 式
| 式 比較演算子 式またはサブクエリ
| 式 [NOT] IN (クエリ スペック)
| 式 [NOT] IN (値[, 値]...)
| 式 [NOT] LIKE 値
| 式 IS [NOT] NULL
| 式 比較演算子 ANY (クエリ スペック)
| 式 比較演算子 ALL (クエリ スペック)
| EXISTS (クエリ スペック)
プロシージャ式 ::= 通常の式と同様。ただし、IF 式とスカラー関数は使用できない
プロシージャ検索条件 ::= 通常の検索条件と同様。ただし、サブクエリを含む式は使用できない
プロシージャ ステートメント ::= [ラベル名:] BEGIN [ATOMIC] [プロシージャ ステートメント[; プロシージャ ステートメント]...] END [ラベル名]
| CALL プロシージャ名(プロシージャ式[, プロシージャ式]...)
| CLOSE カーソル名
| DECLARE カーソル名 CURSOR FOR 選択ステートメント [FOR UPDATE | FOR READ ONLY]
| DECLARE 変数名 データ型 [DEFAULT プロシージャ式 | = プロシージャ式] | DELETE WHERE CURRENT OF カーソル名
| 削除ステートメント
| FETCH [フェッチ方向 [FROM]] カーソル名 [INTO 変数名[, 変数名]]
| IF プロシージャ検索条件 THEN プロシージャ ステートメント[; プロシージャ ステートメント]...[ELSE プロシージャ ステートメント[; プロシージャ ステートメント]...] END IF
| IF プロシージャ検索条件 プロシージャ ステートメント [ELSE プロシージャ ステートメント]
| 挿入ステートメント
| LEAVE ラベル名
| [ラベル名:] LOOP プロシージャ ステートメント[; プロシージャ ステートメント]... END LOOP [ラベル名]
| OPEN カーソル名
| PRINT プロシージャ式[, '文字列']
| RETURN [プロシージャ式]
| トランザクション ステートメント
| into 付き選択ステートメント
| 選択ステートメント
| SET 変数名 = プロシージャ式
| SIGNAL [ABORT] sqlstate値
| START TRANSACTION [トランザクション名]
| 更新ステートメント
| UPDATE SET 列名 = プロシージャ式[, 列名 = プロシージャ式]... WHERE CURRENT OF カーソル名
| [ラベル名:] WHILE プロシージャ検索条件 DO [プロシージャ ステートメント[; プロシージャ ステートメント]]... END WHILE [ラベル名]
| [ラベル名:] WHILE プロシージャ検索条件 プロシージャ ステートメント
| テーブル変更ステートメント
| インデックス作成ステートメント
| テーブル作成ステートメント
| ビュー作成ステートメント
| インデックス削除ステートメント
| テーブル削除ステートメント
| ビュー削除ステートメント
| 権限付与ステートメント
| 権限取消ステートメント
| 設定ステートメント
プロシージャ名 ::= ユーザー定義名
public またはユーザー/グループ名 ::= PUBLIC | ユーザー/グループ名
[
limit句] [
ORDER BY order-by式[,
order-by式]...] [
FOR UPDATE]
クエリ スペック ::= (クエリ スペック)
FROM テーブル参照[, テーブル参照]...
[WHERE 検索条件]
参照エイリアス ::= OLD [AS] 相関名 [NEW [AS] 相関名]
| NEW [AS] 相関名 [OLD [AS] 相関名]
参照アクション ::= 参照更新アクション [参照削除アクション]
| 参照削除アクション [参照更新アクション]
参照更新アクション ::= ON UPDATE RESTRICT
参照削除アクション ::= ON DELETE CASCADE
| ON DELETE RESTRICT
リリース ステートメント ::= RELEASE ステートメントを参照
結果 ::= ユーザー定義名 データ型
ロールバック ステートメント ::= ROLLBACK WORK ステートメントを参照
セーブポイント名 ::= ユーザー定義名
スカラー関数 ::= スカラー関数の一覧を参照
小数位 ::= 整数
検索条件 ::= 検索条件 AND 検索条件
| 検索条件 OR 検索条件
| NOT 検索条件
| (検索条件)
| 述部
選択項目 ::= 式 [[AS] エイリアス名] | テーブル名.*
選択リスト ::= * | 選択項目[, 選択項目]...
セット関数 ::=
AVG ([
DISTINCT |
ALL]
式)
|
COUNT (<* | [
DISTINCT |
ALL]
式>)
|
COUNT_BIG (<* | [
DISTINCT |
ALL]
式>)
|
MAX ([
DISTINCT |
ALL]
式)
|
MIN ([
DISTINCT |
ALL]
式)
|
STDEV ([
DISTINCT |
ALL]
式)
|
STDEVP ([
DISTINCT |
ALL]
式)
|
SUM ([
DISTINCT |
ALL]
式)
|
VAR ([
DISTINCT |
ALL]
式)
|
VARP ([
DISTINCT |
ALL]
式)
sqlstate値 ::= '文字列'
テーブル制約定義 ::= [CONSTRAINT 制約名] テーブル制約
テーブル制約 ::= UNIQUE (列名[, 列名]...)
| PRIMARY KEY (列名[, 列名]...)
| FOREIGN KEY (列名 [, 列名])
REFERENCES テーブル名
[(列名[, 列名]...)]
[参照アクション]
テーブル要素 ::= 列定義
| テーブル制約定義
テーブル式 ::=
FROM テーブル参照[, テーブル参照]...
[WHERE 検索条件]
[GROUP BY 式[, 式]...
[HAVING 検索条件]
テーブル名 ::= ユーザー定義名
テーブル権限 ::= ALL
| SELECT [(列名[, 列名]...)]
| UPDATE [(列名[, 列名]...)]
| INSERT [(列名[, 列名]...)]
| DELETE
| ALTER
| REFERENCES
テーブル参照 ::= {OJ 外部結合の定義}
| [データベース名.]テーブル名 [[AS] エイリアス名]
| 結合定義
| (結合定義)
テーブル サブクエリ ::=
クエリ スペック [[
UNION [
ALL]
クエリ スペック]...] [
limit句] [
ORDER BY order-by式[,
order-by式]...]
limit句 ::= [LIMIT [オフセット,] 行数 | 行数 OFFSET オフセット | ALL [OFFSET オフセット]]
オフセット ::= 数値 | ?
行数 ::= 数値 | ?
トランザクション ステートメント ::= コミット ステートメント
| ロールバック ステートメント
| リリース ステートメント
トリガー名 ::= ユーザー定義名
ユーザーおよびパスワード ::= ユーザー名[:]パスワード
ユーザー/グループ名 ::= ユーザー名 | グループ名
ユーザー名 ::= ユーザー定義名
値 ::= リテラル | USER | NULL | ?
値リスト ::= (値[, 値]...)
values句 ::= DEFAULT VALUES | VALUES (式[, 式]...)
変数名 ::= ユーザー定義名
ビュー名 ::= ユーザー定義名
SQL ステートメント リスト
SqlStatementList は次のように定義されます。
SqlStatementList
ステートメント ';' | SqlStatementList ';'
ステートメント ::= ステートメント ラベル ':' ステートメント
| BEGIN ... END ブロック
| CALL ステートメント
| CLOSE CURSOR ステートメント
| COMMIT ステートメント
| DECLARE CURSOR ステートメント
| DECLARE 変数ステートメント
| DELETE ステートメント
| FETCH ステートメント
| IF ステートメント
| INSERT ステートメント
| LEAVE ステートメント
| LOOP ステートメント
| OPEN ステートメント
| PRINT ステートメント
| RELEASE SAVEPOINT ステートメント
| RETURN ステートメント
| ROLLBACK ステートメント
| SAVEPOINT ステートメント
| SELECT ステートメント
| SET ステートメント
| SIGNAL ステートメント
| START TRANSACTION ステートメント
| UPDATE ステートメント
| WHILE ステートメント
述部
述部は次のように定義されます。
式 比較演算子 式
| 式 [NOT] BETWEEN 式 AND 式
| 式 [NOT] LIKE 文字列リテラル
| 式 IS [NOT] NULL
| NOT 述部
| 述部 AND 述部
| 述部 OR 述部
| '('述部')'比較演算子 ::= '=' | '>=' | '>' | '<=' | '<' | '<>' | '!='
| [NOT] IN 値リスト
式
式は次のように定義されます。
数字
| 文字列リテラル
| 列名
| 変数名
| NULL
| CONVERT '(' 式 ',' データ型 ')'
| '-' 式
| 式 '+' 式
| 式 '-' 式
| 式 '*' 式
| 式 '/' 式
| 式 '&' 式
| '~' 式
| 式 '|' 式
| 式 '^' 式
| 関数名 '(' [式リスト] ')'
| '(' 式 ')'
| '{' D 文字列リテラル '}'
| '{' T 文字列リテラル '}'
| '{' TS 文字列リテラル '}'
| @:IDENTITY
| @:ROWCOUNT
| @@IDENTITY
| @@ROWCOUNT
式リストは次のように定義されます。
式リスト ::= 式[, 式...]
グローバル変数
PSQL は次のグローバル変数をサポートしています。
グローバル変数は 2 つの @ マーク(@@)で始まります。すべてのグローバル変数は、接続ごとの変数です。データベース接続ごとにそれぞれ固有の @@IDENTITY、@@ROWCOUNT、および @@SPID 値を持ちます。
@@IDENTITY
この変数は、一番最後に挿入された IDENTITY 列値(IDENTITY または SMALLIDENTITY)の値を返します。値は符号付き整数値になります。初期値はヌルです。
この変数は単一列のみ参照することができます。ターゲット テーブルに 2 つ以上の IDENTITY 列が含まれている場合、この変数の値は、テーブルの主キーとなる IDENTITY 列を参照します。このような列が存在しない場合には、この変数の値はテーブル内の最初の IDENTITY 列を参照します。
一番最後の挿入が IDENTITY 列を含まないテーブルに対して行われたものであった場合、@@IDENTITY の値はヌルに設定されます。
例
SELECT @@IDENTITY
現在の接続でレコードが挿入されていない場合はヌルを返し、そうでない場合は、一番最後に挿入された行の IDENTITY 列の値を返します。
SELECT * FROM t1 WHERE @@IDENTITY = 12
一番最後に挿入された行の IDENTITY 列の値が 12 の場合はその行を返し、そうでない場合は行を返しません。
INSERT INTO t1(c2) VALUES (@@IDENTITY)
最後に挿入された行の IDENTITY 値を新しい行の C2 列に挿入します。
UPDATE t1 SET t1.c1 = (SELECT @@IDENTITY) WHERE t1.c1 = @@IDENTITY + 10
C1 列の値が最後に挿入された行の IDENTITY 列の値より 10 大きい場合は、C1 列をこの IDENTITY 値で更新します。
UPDATE t1 SET t1.c1 = (SELECT NULL FROM t2 WHERE t2.c1 = @@IDENTITY)
C1 列の値が最後に挿入された行の IDENTITY 列の値と等しい場合は、C1 列をヌル値で更新します。
以下の例では、ストアド プロシージャを作成し、それを呼び出します。プロシージャは、最後に更新された行の IDENTITY 列の値と入力値の合計を変数 V1 に設定します。プロシージャは次に、C1 列が V1 と等しい行をテーブルから削除し、その後で何行削除されたかを示すメッセージを出力します。
CREATE PROCEDURE TEST (IN :P1 INTEGER);
BEGIN
DECLARE :V1 INTERGER;
SET :V1 = :P1 + @@IDENTITY;
DELETE FROM t1 WHERE t1.c1 = :V1;
IF (@@ROWCOUNT = 0) THEN
PRINT '行は削除されませんでした';
ELSE
PRINT CONVERT(@@ROWCOUNT, SQL_CHAR) + ' 行が削除されました';
END IF;
END;
CALL TEST (@@IDENTITY)
@@ROWCOUNT
この変数は、現在の接続で一番最後に行った操作により影響を受けた行の数を返します。値は符号なし整数になります。初期値はゼロです。
@@ROWCOUNT 変数は、INSERT、UPDATE、または DELETE ステートメント後に使用した場合にのみ有効になります。
例
SELECT @@ROWCOUNT
現在の接続で直前に行った操作により影響を受けたレコードがない場合はゼロを返し、そうでない場合は、直前の操作により影響を受けた行数を返します。
CREATE TABLE t1 (c1 INTEGER, c2 INTEGER)
INSERT INTO t1 (c1, c2) VALUES (100,200)
INSERT INTO t1(c1, c2) VALUES (300, @@ROWCOUNT)
SELECT @@ROWCOUNT
結果:
1(@@ROWCOUNT 変数の値)
4 番目の行で、@@ROWCOUNT 変数の値は 1 になります。これは、直前の INSERT 操作が影響を与えたのは 1 行だからです。
@@IDENTITY の例も参照してください。
@@SESSIONID
この変数は、PSQL 接続のために 8 バイトの整数値を返します。この整数は時刻の値と増分カウンターの組み合わせです。この変数は PSQL 接続をそれぞれ一意に識別するために使用できます。
@@SESSIONID が値を返すには、データベース エンジンに接続されていることが必要です。データベース エンジンへの接続が失われた場合、変数は ID を返すことができません。
例
SELECT @@SESSIONID
この例は、26552653137523 などの整数の ID を返します。
@@SPID
この変数(サーバー プロセス ID)は、PSQL 接続のシステム スレッドの ID を示す整数値を返します。
データベース エンジンへの接続が失われた場合、SPID は ID を返すことができません。代わりに、ステートメントが SqlState 08S01 を示すエラーを返します。
例
SELECT @@SPID
この例は、402 などの整数の ID を返します。
ほかの特性
このセクションでは、SQL 文法のその他の特性について説明します。この章は、以下のセクションに分かれています。
テンポラリ ファイル
PSQL は、指定されたクエリを処理するためにテンポラリ テーブルを生成する必要がある場合は、次の規則によって決定される場所にそのファイルを作成します。
まず、文字列キー値の PervasiveEngineOptions\TempFileDirectory を Windows レジストリに手動で追加した場合、PSQL は TempFileDirectory に設定されたパスを使用します。(レジストリの場所は、製品のビット アーキテクチャによって異なります。PSQL 32 ビット サーバー版では、HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI です。PSQL 64 ビット サーバー版では、HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ODBC\ODBC.INI です。)
レジストリ エントリを定義しなかった場合、Windows プラットフォームでは、PSQL は以下の順序でパスを使用します。
•TMP 環境変数で指定されたパス
•TEMP 環境変数で指定されたパス
•USERPROFILE 環境変数で指定されたパス
•Windows ディレクトリ
たとえば、TMP 環境変数が定義されていない場合、PSQL は TEMP 環境変数、その次の環境変数という順序で使用します。
Linux および OS X ディストリビューションでは、PSQL はサーバー プロセスの現在のディレクトリを使用します。TMP の使用を試みることはありません。
PSQL はクエリの処理を完了すると、そのクエリの処理で必要となったすべてのテンポラリ ファイルを削除します。クエリが SELECT ステートメントの場合には、テンポラリ ファイルは結果セットがアクティブである間、つまり、結果セットが呼び出し元のアプリケーションによって解放されるまでは存在します。
テンポラリ ファイルはどのような場合に作成されるか
PSQL は、メモリ内、ディスク上、および Btrieve(MicroKernel エンジン)の 3 種類のテンポラリ ファイルを使用します。
メモリ内のテンポラリ ファイル
メモリ内のテンポラリ ファイルは以下の状況で使用されます。
•前方のみのカーソル
•テンポラリ ファイル内のバイト数は 250,000 未満
•インデックスを使用しない ORDER BY、GROUP BY、DISTINCT を伴う SELECT ステートメントで、ORDER BY、GROUP BY、DISTINCT 内に BLOB または CLOB を含まない。また、UNION を伴う選択リストに BLOB または CLOB を含まない。
ディスク上のテンポラリ ファイル
ディスク上のテンポラリ ファイルは以下の状況で使用されます。
•前方のみのカーソル
•テンポラリ ファイル内のバイト数は 250,000 より大きい
•インデックスを使用しない ORDER BY、GROUP BY、DISTINCT を伴う SELECT ステートメントで、ORDER BY、GROUP BY、DISTINCT 内に BLOB または CLOB を含まない。また、UNION を伴う選択リストに BLOB または CLOB を含まない。
Btrieve テンポラリ ファイル
Btrieve テンポラリ ファイルは以下の状況で使用されます。
•ORDER BY、GROUP BY、DISTINCT 内に BLOB または CLOB を使用する前方のみカーソルがあるか、UNION を使用する選択リストで BLOB または CLOB を使用。
•UNION クエリを伴う動的または静的カーソル、または、インデックスを使用しない ORDER BY、GROUP BY、DISTINCT を伴う SELECT ステートメント
PSQL は、静的カーソル SELECT クエリで各ベース テーブルに Btrieve テンポラリ ファイルを作成しません。その代わり、各ベース テーブルを MicroKernel を使用して開き、ファイルの静的な表現としてファイル内にページを予約します。静的カーソルを介して行われた変更は、そのカーソルからは見えません。
NULL 値を使った作業
PSQL は NULL を未知の値として解釈します。したがって、2 つの NULL 値を比較すると、等価とは見なされません。
WHERE NULL=NULL という評価式は False を返します。
バイナリ データを使った作業
次のシナリオについて考えてみましょう。t1 テーブルで c1 という名前が付けられた BINARY(4)列にリテラル値 '1' を挿入します。次に、SELECT * FROM t1 WHERE c1='1' というステートメントを入力します。
データベース エンジンは、データ入力に使用したものと同じバイナリ形式を用いてデータを取得できます。つまり、上記の SELECT の例は、リテラルの一致がなくても正しく動作し、値 0x01000000 を返します。
メモ: データベース エンジンは、挿入する奇数桁のバイナリ値の前に必ずゼロ('0')を追加します。たとえば、値 '010' を挿入すると、値 '0x00100000' がデータ ファイルに保存されます。
現在、PSQL はバイナリ定数を示す接尾辞 0x をサポートしていません。バイナリ定数は、一重引用符で囲んだ 16 進数の文字列になります。
この動作は、SQL Server の動作と同じです。
インデックスの作成
インデックス可能な VARCHAR 型の列の最大サイズは、ヌル値が許可されない列では 254 バイト、ヌル値が許可される列では 253 バイトです。
CHAR 型の列の最大サイズは、ヌル値が許可されない列では 255 バイト、ヌル値が許可される列では 254 バイトです。
インデックス可能な NVARCHAR 型の列の最大サイズは NVARCHAR(126) です。この制限は、ヌル値が許可される列とヌルでない列の両方に適用されます。NVARCHAR のサイズは UCS-2 文字単位で指定されます。
NCHAR 型の列の最大サイズは NCHAR(127) です。この制限は、ヌル値が許可される列とヌルでない列の両方に適用されます。NCHAR のサイズは UCS-2 文字単位で指定されます。
Btrieve の最大キー サイズは 255 です。列でヌル値が許可され、インデックスが作成されている場合、セグメント キーは、ヌル インジケーターの 1 バイトと、インデックス列の最大 254 バイトを使って作成されます。VARCHAR 型の列が CHAR 型の列と異なるのは、長さバイト(Btrieve lstring)またはゼロ終端バイト(Btrieve zstring)のいずれかが予約されており、そのため有効な記憶域が 1 バイト増える点です。NVARCHAR(Btrieve wzstring)型の列が NCHAR 型の列と異なるのは、ゼロ終端文字が予約されており、そのため有効な記憶域が 2 バイト増える点です。
小数点の記号のカンマ
多くの地域では、浮動小数点数フィールド内で整数部と小数部を区切るのにカンマを使用します。たとえば、これらの地域は、1 と 2 分の 1 を数字で表すのに 1.5 ではなく 1,5 を使用します。
PSQL は、ピリオドとカンマの両方を小数点の記号としてサポートしています。PSQL はオペレーティング システムの地域の設定に基づいて、ピリオドまたはカンマを使用する入力値を受け入れます。デフォルトでは、データベース エンジンはピリオドを使って値を表示します。
メモ: 小数点の記号がピリオドでない場合、SQL ステートメントに指定する数値は引用符で囲む必要があります。
出力と表示のみについては、セッション レベルのコマンド
SET DECIMALSEPARATORCOMMA を使用すれば、出力(たとえば、SELECT の結果)でカンマを小数点の記号として使用するように指定できます。このコマンドは、データの入力や保存には影響しません。
クライアント/サーバーの考慮
小数点の記号としてカンマをサポートするかは、オペレーティング システムの地域の設定によります。クライアント オペレーティング システムとサーバー オペレーティング システムのどちらにも地域の設定があります。期待される動作は両方の設定に応じて変わります。
•サーバーとクライアントどちらか一方の地域設定で小数点の記号にカンマが使用されている場合、PSQL はピリオド区切りの値と引用符で囲まれたカンマ区切りの値の両方を受け入れます。
•サーバーとクライアントどちらの地域設定でも小数点の記号にカンマが使用されていない場合、PSQL はカンマ区切りの値を受け入れません。
地域の設定の変更
小数点の記号の情報は、Windows オペレーション システムが動作しているマシンでのみ取得または変更できます。Linux および OS X の場合、小数点の記号はピリオドに設定されており、設定を修正することはできません。Linux および OS X サーバー エンジンをお持ちで、小数点の記号にカンマを使用したい場合は、必ずすべてのクライアント コンピューターが小数点にカンマを使用する地域に設定されていなければなりません。
Windows オペレーティング システムの地域の設定を変更するには、コントロール パネルからこの設定にアクセスします。変更したら、PSQL サービスを停止して再起動し、データベース エンジンが変更された設定を使用できるようにします。
例
例 A - サーバーの地域が小数点の記号にカンマを使用する
クライアントの地域が小数点の記号にカンマを使用する場合:
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1.232')
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 FROM c1 = '10,123'
上記の 2 つの SELECT ステートメントがクライアントから実行された場合、次の値が返されます。
10.123, 1.232
10.123, 1.232
SET DECIMALSEPARATORCOMMA=ON
SELECT * FROM t1 FROM c1 = '10,123'
上記の SELECT ステートメントが、小数点の記号を設定した後でクライアントから実行された場合は、次の値が返されます。
10,123, 1,232
クライアントの地域が小数点の記号にピリオドを使用しており、次のステートメントが新しい接続から発行される場合(SET DECIMALSEPARATORCOMMA のデフォルトの動作):
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1.232')
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 WHERE c1 = '10,123'
上記の 2 つの SELECT ステートメントがクライアントから実行された場合、次の値が返されます。
10.123, 1.232
10.123, 1.232
例 B - サーバーの地域が小数点の記号にピリオドを使用する
クライアントの地域が小数点の記号にカンマを使用する場合:
例 A のクライアントがカンマを使用する場合と同様です。
クライアントの地域が小数点の記号にピリオドを使用する場合:
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1,232') -- 割り当てエラー
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 WHERE c1 = '10,123' -- 割り当てエラー
上記の最初の select ステートメントがクライアントから実行された場合、次の値が返されます。
10.123, 1.232
SET DECIMALSEPARATORCOMMA=ON
SELECT * FROM t1 FROM c1 = 10.123
上記の SELECT ステートメントが、表示用の小数点の記号を設定した後で実行された場合は、次の値が返されます。
10,123, 1,232