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$ |