我们有一个数据库,其中字符集设置为 WE8MSWIN1252,我理解它是一个单字节字符集。
我们通过运行以下脚本创建了一个模式及其表:
ALTER SYSTEM SET NLS_LENGTH_SEMANTICS=CHAR
由于我们使用具有字符语义的 VARCHAR2 列,而底层字符集是单字节,我们可能会丢失数据吗?
我们有一个数据库,其中字符集设置为 WE8MSWIN1252,我理解它是一个单字节字符集。
我们通过运行以下脚本创建了一个模式及其表:
ALTER SYSTEM SET NLS_LENGTH_SEMANTICS=CHAR
由于我们使用具有字符语义的 VARCHAR2 列,而底层字符集是单字节,我们可能会丢失数据吗?
如果您使用的是像 Windows-1252 这样的单字节字符集,那么您使用的是字符语义还是字节语义都无关紧要。每个字符只占用一个字节,因此无论是声明列VARCHAR2(10 CHAR)
还是VARCHAR2(10 BYTE)
. 在任何一种情况下,将分配最多 10 个字节的存储空间,最多 10 个字符。
由于更改NLS_LENGTH_SEMANTICS
设置没有任何好处,因此您应该将设置保持为默认值 ( BYTE
),因为这不太可能导致您可能需要运行的其他脚本(例如来自 Oracle 的脚本)出现问题。
很好的问题。多字节字符将占用所需的字节数,这可能会使用比您预期更多的存储空间。如果您在 varchar2(4) 列中存储一个 4 字节字符,则您已经使用了所有 4 个字节。如果您在 varchar2(4 char) 列中存储一个 4 字节字符,那么您只使用了 1 个字符。许多外语和特殊字符使用 2 字节字符集,因此最好“了解您的数据”并相应地定义您的数据库列。Oracle 不建议将 NLS_LENGTH_SEMANTICS 更改为 CHAR,因为它会影响定义为 CHAR 或 VARCHAR2 的每个新列,在您进行就地升级时可能包括您的目录表。您可以看到为什么这可能不是一个好主意。其他 Oracle 工具集和接口也可能存在问题。