今天,我
SELECT
编辑了LENGTH()
列中某个值的VARCHAR2(1)
,并得到了“5”,尽管当我直接在PLSQL Developer中SELECT
列(它有据我所知,价值'0'
)。我可以检查什么来解决这个问题?对我来说似乎很疯狂,我想不出我可能会错过什么。
很可能存在一些不可见的字符与可见的字符一起存储。请看下面的示例:
WITH
tbl (ID, A_VARCHAR) AS
( Select 1, 'G' From Dual Union All
Select 2, 'E' From Dual Union All
Select 3, '0' || Chr(13) From Dual Union All
Select 4, '0' From Dual
)
Select ID, A_VARCHAR, Length(A_VARCHAR) "LEN_CHAR", LengthB(A_VARCHAR) "LEN_BYTE"
From tbl
/*
ID A LEN_CHAR LEN_BYTE
---------- - ---------- ----------
1 G 1 1
2 E 1 1
3 0 2 2
4 0 1 1 */
其他可能性是您正在处理多字节字符。 Oracle 将 VARCHAR2 视为 CHAR 或 BYTE,具体取决于 NLS_LENGTH_SEMANTICS 参数(更多信息请参见此处)。您可以使用以下方法检查会话的 NLS_LENGTH_SEMANTICS 参数值(以及所有其他参数值):
SELECT * FROM V$NLS_PARAMETERS;
下面是一个小示例,您可以看到两个 NLS_LENGTH_SEMANTICS 参数值的差异:
ALTER SESSION SET NLS_LENGTH_SEMANTICS = CHAR
WITH
tbl (ID, A_VARCHAR) AS
( Select 1, CAST('G' as VarChar2(1)) From Dual Union All
Select 2, CAST('E' as VarChar2(1)) From Dual Union All
Select 3, CAST('ü' as VarChar2(1)) From Dual Union All
Select 4, CAST('€' as VarChar2(1)) From Dual
)
Select ID, A_VARCHAR, Length(A_VARCHAR) "LEN_CHAR", LengthB(A_VARCHAR) "LEN_BYTE"
From tbl
/* R e s u l t :
ID A LEN_CHAR LEN_BYTE
---------- - ---------- ----------
1 G 1 1
2 E 1 1
3 ü 1 2
4 € 1 3 */
以上配置 NLS_LENGTH_SEMANTICS = CHAR 表示 VARCHAR2(1) 数据类型将存储 1 个字符,无论该字符有多长。
ALTER SESSION SET NLS_LENGTH_SEMANTICS = BYTE
/* R e s u l t : (of the same above query)
ID A LEN_CHAR LEN_BYTE
---------- - ---------- ----------
1 G 1 1
2 E 1 1
3
4 */
以上配置 NLS_LENGTH_SEMANTICS = BYTE 表示 VARCHAR2(1) 数据类型将存储 1 个字节长度的 1 个字符,并且不可能存储任何多字节字符。