S-JIS[2003-07-19/2003-07-22]
char,varcharの長さの指定は、テーブルのエンコードタイプの文字数。
つまり、SQL_ASCIIの時はバイト単位(全角文字は2バイト、半角文字は1バイト)となり、
SJIS・EUC_JP・UNICODEの時は全角文字も半角文字も1文字となる。
length関数で返ってくる数値も同じ。
エンコード タイプ |
長さ | |
---|---|---|
全角1文字 | 半角1文字 | |
SQL_ASCII | 2 | 1 |
SJIS EUC_JP UNICODE |
1 | 1 |
create table v (cdata char(4),vdata varchar(4));
SQL_ASCII: insert into v values('ABCD' , '1234'); OK(半角) insert into v values('ABCDE', '1234'); ERROR(char) insert into v values('ABCD' , '12345'); ERROR(varchar) insert into v values('AB' , '12'); OK(全角) insert into v values('ABC', '12'); ERROR(char) insert into v values('AB' , '123'); ERROR(varchar) insert into v values('ABC' , '123'); OK(全角半角混じり)
SJIS・EUC_JP・UNICODE: insert into v values('ABCD' , '1234'); OK(半角) insert into v values('ABCDE', '1234'); ERROR(char) insert into v values('ABCD' , '12345'); ERROR(varchar) insert into v values('ABCD' , '1234'); OK(全角) insert into v values('ABCDE', '1234'); ERROR(char) insert into v values('ABCD' , '12345'); ERROR(varchar) insert into v values('ABCDE' , '1234'); ERROR(char) insert into v values('ABCE' , '12345'); ERROR(varchar)
文字列の長さを返す関数には、以下のようなものがある。[/2003-07-22]
関数名 | 説明 | 文字種 | 半角1文字の数値 | 全角1文字の数値 | ||||||
---|---|---|---|---|---|---|---|---|---|---|
DB | ASCII | UNICODE | ASCII | UNICODE | ||||||
\encoding | ASC | EUC | ASC | EUC | ASC | EUC | ASC | EUC | ||
length | 文字列の文字数を返す | 1 | 1 | 1 | 1 | 2 | 8 | 2 | 1 | |
char_length | 文字列の文字数を返す | 1 | 1 | 1 | 1 | 2 | 8 | 2 | 1 | |
octet_length | 文字列のバイト数を返す | 1 | 1 | 1 | 1 | 2 | 8 | 2 | 3 | |
bit_length | 文字列のビット数を返す | 8 | 8 | 8 | 8 | 16 | 64 | 16 | 24 |
DBのエンコードがSQL_ASCIIで\encodingがEUC_JPのときの、全角文字の数値の返り方が不思議。
UNICODEは1文字が3バイトらしいので、octet_lengthが3なのは妥当かな?
asciidb=# \encoding SQL_ASCII
asciidb=# select length('A'),length('A');
length | length
--------+--------
1 | 2
(1 row)
asciidb=# \encoding EUC_JP
asciidb=# select length('A'),length('A');
length | length
--------+--------
1 | 8
(1 row)
charのエリアにcharの指定より短い文字列を入れようとすると、左詰め(足りない分だけスペースが右側に追加される)になる。
varcharだと、当然
短い文字列そのままが入る。なお、PostgreSQLでは空文字「''」とnullは別物。
スペース以外で埋めたいときは、以下のような関数を使う。
やりたい事 | 関数名 | 例 |
---|---|---|
右詰め (スペースを左詰) |
lpad | # select lpad('abc',5); lpad ------- abc (1 row) |
'0'を左に詰める | lpad | # select lpad('abc',5,'0'); lpad ------- 00abc (1 row) |
'0'を右に詰める | rpad | # select rpad('abc',5,'0'); rpad ------- abc00 (1 row) |
chra,varcharの指定より長い文字列を入れようとすると
ERROR: value too long for type character(11) (char(11)のエリアに11文字より長い文字列を入れようとした)
といったエラーになる。
ただし、オーバーしている部分(文字列の右側)がスペースのみだった場合は、スペースが無視されて挿入・更新される。
文字列の端のスペース(あるいは指定した文字)の削除には、trim・rtrim・ltrimといった関数がある。
やりたい事 | 関数名 | 例 |
---|---|---|
スペース削除 | trim | # select trim(' abcdef '); btrim -------- abcdef (1 row) |
指定文字削除 | trim | # select trim('a' from 'abcdefa'); btrim ------- bcdef (1 row) # select trim('abcdefa','a'); btrim ------- bcdef (1 row) |
やりたい事 | 関数名 | 例 | MSX-BASIC だったら |
---|---|---|---|
結合 | || | # select 'a' || 'b'; |
+ |
文字の位置 | strpos | # select strpos('abcd','b'); strpos -------- 2 (1 row) |
INSTR |
部分文字列 | substr | # select substr('abcdefg',2,4); substr -------- bcde (1 row) |
MID$ |
置換 | translate | # select translate('abcdefg','bcd','xx'); translate ----------- axxefg (1 row) |
MID$ |
繰り返し | repeat | # select repeat('abc',3); repeat ----------- abcabcabc (1 row) |
STRING$ |