Oracle 12c:VARCHAR2 值的 LENGTH() 如何大于其大小?

问题描述 投票:0回答:1

今天,我

SELECT
编辑了
LENGTH()
列中某个值的
VARCHAR2(1)
,并得到了“5”,尽管当我直接在PLSQL Developer中
SELECT
列(它有据我所知,价值
'0'
)。我可以检查什么来解决这个问题?对我来说似乎很疯狂,我想不出我可能会错过什么。

plsql oracle12c
1个回答
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 个字符,并且不可能存储任何多字节字符。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.