为什么我可以在VARCHAR2列中插入数字?

时间:2016-06-01 17:01:14

标签: sql oracle oracle11g casting insert

我对表有一个奇怪的问题,我在表中插入行,现在我正在尝试测试它,在我的一个测试中,它允许输入它不应该。

我的表格定义:

CREATE TABLE ITEMS(
ITEM_NUMBER VARCHAR2(3)
CONSTRAINT ITEMS_ITEM_NUMBERf_PK PRIMARY KEY,
ITEM_DESCRIPTION VARCHAR2(30),
ITEM_SIZE VARCHAR2(2),
ITEM_COST NUMBER(30,0),
ITEM_QTY NUMBER(2,0),
ORDER_NUMBER VARCHAR2(4));

当我尝试通过放入ITEM_SIZE来测试number列时,只需将其插入即可。

INSERT INTO ITEMS VALUES ('I32', 'Leather blazer', 'L', 14.00, 1, 'O114');
INSERT INTO ITEMS VALUES ('I33', 'Fleece vest', 'L', 28.00, 1, 'O128');
INSERT INTO ITEMS VALUES ('I34', 'Khaki pants', 'S', 22.00, 3, 'O122');
INSERT INTO ITEMS VALUES ('I35', 'Muscle Tee', 'M', 12.99, 1, 'O122');
INSERT INTO ITEMS VALUES ('I36', 'Trench Coat', 'M', 03.00, 1, 'O133');
INSERT INTO ITEMS VALUES ('I37', 'Crewneck sweater', 'XL', 07.00, 1,   'O107');
INSERT INTO ITEMS VALUES ('I38', 'Varsity Sweater', 'M', 08.99, 1, 'O108');
INSERT INTO ITEMS VALUES ('I39', 'CROOK', 'M', 12.00, 1, 'O112');

// - 测试人员 - //

INSERT INTO ITEMS VALUES ('I49', 'bROOK', 10, 12.00, 1, 'O112');

在上面的陈述中,我将数字10插入ITEM_SIZE VARCHAR2(2)。我怎么能避免这种情况?

2 个答案:

答案 0 :(得分:3)

正如@kevinsky所说,Oracle is doing implicit data conversion在插入时从数字到字符串。

如果您想限制可以放入列中的值,则可以添加a check constraint

alter table items add constraint items_size_chk
  check (item_size in ('XXS','XS','S','M','L','XL','XXL','XXXL'));

Table ITEMS altered.

INSERT INTO ITEMS VALUES ('I49', 'bROOK', 10, 12.00, 1, 'O112');

SQL Error: ORA-02290: check constraint (SCHEMA.ITEMS_SIZE_CHK) violated
02290. 00000 -  "check constraint (%s.%s) violated"
*Cause:    The values being inserted do not satisfy the named check

如果您需要不同的限制,您可以更改检查的方式;例如,您可以使用正则表达式检查以排除数字但允许任何字符。在这种情况下,您似乎更有可能希望允许列出特定值。

请注意,添加新的有效大小时,您必须修改检查约束;任何项目都允许使用任何大小值。

如果有效大小来自另一个表,则可以使用外键约束。您可能真的需要一个对每个项目都有效的大小(或其他属性)列表,因此您的数据模型可能需要一些充实。

答案 1 :(得分:1)

Oracle隐式将数字10转换为varchar2字符串'10'。

这是另一个隐式转换

SELECT item_size + 1  FROM items;

Oracle 11g中的结果是

11

我不确定在构建解析器时这是否有用,但它确实会导致很多混乱。但是Oracle不会隐式地将字母字符转换为数字。它会失败。