为列定义字符集对于oracle数据库表

时间:2012-03-31 13:50:30

标签: oracle character-encoding oracle9i

我在SQL * Plus中运行以下查询

CREATE TABLE  tbl_audit_trail (
  id NUMBER(11) NOT NULL,
  old_value varchar2(255) NOT NULL,
  new_value varchar2(255) NOT NULL,
  action varchar2(20) CHARACTER SET latin1 NOT NULL,
  model varchar2(255) CHARACTER SET latin1 NOT NULL,
  field varchar2(64) CHARACTER SET latin1 NOT NULL,
  stamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  user_id NUMBER(11) NOT NULL,
  model_id varchar2(65) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (id),  
  KEY idx_action (action)
);

我收到以下错误:

action varchar2(20) CHARACTER SET latin1 NOT NULL,
                      *
ERROR at line 5:
ORA-00907: missing right parenthesis

你能说一下我错过了什么吗?

2 个答案:

答案 0 :(得分:30)

简单的答案是,与MySQL不同,无法在column (or table) level定义字符集。 Latin1也不是有效的Oracle字符集。

字符集在整个数据库中是一致的,并且在创建数据库时已指定。您可以通过查询NLS_DATABASE_PARAMETERS

找到您的角色
select value
  from nls_database_parameters
 where parameter = 'NLS_CHARACTERSET'

11g r2for 9i可以使用完整的可能字符集列表,或者您可以查询V$NLS_VALID_VALUES

可以使用ALTER SESSION statement设置NLS_LANGUAGENLS_TERRITORY,但遗憾的是,您无法对字符集执行此操作。我相信这是因为改变语言会改变Oracle 显示存储数据的方式,而更改字符集会改变Oracle 存储数据的方式。

显示数据时,您当然可以在您使用的任何客户端中指定所需的字符集。

Character set migration不是一项微不足道的任务,不应轻易做到。

稍微注意一下你为什么要使用拉丁语1?以UTF-8(也称为AL32UTF8 - 不使用UTF8)或UTF-16等方式设置新数据库更为正常,这样您就可以存储多字节数据有效。即使你现在不需要它,但是明智地尝试 - 不能保证生命 - 将来证明你的数据库,而不需要在将来进行迁移。

如果您希望为数据库中的不同列指定不同的字符集,那么更好的选择是确定是否真的需要此要求并尝试将其删除。如果肯定有必要 1 那么你最好的选择可能是使用一个字符集,它是所有潜在字符集的超集。然后,使用某种检查约束将列限制为特定的十六进制值。我根本不建议这样做,错误蔓延的可能性很大,而且非常复杂。此外,不同的字符集会以不同的方式呈现不同反过来,这意味着您需要强制在特定字符中呈现列,这是不可能的,因为它超出了数据库的范围。

<子> 1。我有兴趣了解情况

答案 1 :(得分:4)

根据提供的DDL声明,有些人需要使用2个字符集。 Oracle中此功能的实现与MySQL不同,并且使用n *数据类型(如nvarchar2,nchar)完成... Latin1类似于某些可能是默认的西欧字符集。所以你能够定义例如“Latin1”(WE **)和一些Unicode(UTF8 ..)。

Oracle引入了NVARCHAR2数据类型,用于希望对某些列使用Unicode,同时为数据库的其余部分(使用VARCHAR2)保留另一个字符集的数据库。 NVARCHAR2是仅限Unicode的数据类型。 您要使用NVARCHAR2的原因可能是您的数据库使用非Unicode字符,并且您仍希望能够存储某些列的Unicode数据。 示例中的列将能够存储相同的数据,但字节存储将不同。

相关问题