Oracle SQL使用空字符串更新NOT NULL列

时间:2013-10-06 16:57:34

标签: sql oracle

我在编写SQL Update语句时遇到问题,我需要使用空字符串更新非空字段。

UPDATE channel_mgmt.channels
    SET registered_address_id=p_address_id
        ,vendor_id=p_spc_code
     WHERE id=v_channel_id;

在这种情况下,p_spc_code可以设置为'',运行时遇到SQL错误:

Error report:
ORA-01407: cannot update ("CHANNEL_MGMT"."CHANNELS"."VENDOR_ID") to NULL
ORA-06512: at line 8973
 01407. 00000 -  "cannot update (%s) to NULL"
*Cause:    
*Action:

我有什么想法可以解决这个问题?我需要在某些情况下使用空字符串,但我不确定为什么oracle会抱怨null值。

desc channel_mgmt.channels
Name                  Null     Type               
--------------------- -------- ------------------ 
ID                    NOT NULL NUMBER(16)         
CHANNEL_STATUS_KEY    NOT NULL VARCHAR2(64 CHAR)  
REGISTERED_ADDRESS_ID NOT NULL NUMBER(16)         
VENDOR_ID             NOT NULL VARCHAR2(64 CHAR)

5 个答案:

答案 0 :(得分:5)

如果在列上定义了NOT NULL约束,则无法通过将null或零长度字符串('')指定为列的新值来更新表。 Oracle将零长度字符串(''分配给varchar2列或变量时)视为NULL,因此从 oracle的角度来看,这两个语句是相同的set col_name = nullset col_name = ''。如果您希望允许列接受NULL,则需要从该列中删除非空约束,如果它赢得了任何伤害:

alter table <<table_name>> modify (<<column_name>> [<<data type>>] null)

答案 1 :(得分:4)

Oracle无法区分空字符串和空值。它为它们使用相同的标记(一个零字节)。

答案 2 :(得分:4)

您是否尝试过使用' '(其中包含一个空格的字符串)?如果varchar,我相信比较(对于大多数情况,即你没有指定比较白色字符)按预期工作。

我的意思是' ' = ' '(单个和双个空格)应评估为true字段的varchar

(我没有Oracle的实例,所以我无法确定......)

答案 3 :(得分:0)

如果你有一个NOT NULL列并且你要将它更新为NULL,那么你可能需要考虑你的应用程序中的逻辑。 否则,您可以定义一个nvl(column,some_pattern),例如'???' (当然,取决于列的长度)对于未知的空数据,当您知道不允许插入/更新NULL时。

你要检查一下是否有什么东西表现不正确,或者在视图或其他东西中过滤掉这三个问号并再次显示为NULL。

答案 4 :(得分:0)

你的id不是null,你想让它为null 您可以将所有表行作为备份插入到另一个表中,然后删除表并使用null able id行再次创建它,并从备份中再次插入行 只关心你是否使用你的id作为你的主键,它将不再为null

另一种方法是在更新中使用'',它只返回空格,但它不是空的

CREATE TABLE BACKUP(
ID                    NOT NULL NUMBER(16),         
CHANNEL_STATUS_KEY    NOT NULL VARCHAR2(64 CHAR),  
REGISTERED_ADDRESS_ID NOT NULL NUMBER(16),         
VENDOR_ID             NOT NULL VARCHAR2(64 CHAR));

INSERT INTO BACKUP (SELECT * FROM YourTable);

ALTER TABLE YourTable(
ID                             NUMBER(16),         
CHANNEL_STATUS_KEY    NOT NULL VARCHAR2(64 CHAR),  
REGISTERED_ADDRESS_ID NOT NULL NUMBER(16),         
VENDOR_ID             NOT NULL VARCHAR2(64 CHAR));

INSERT INTO YourTable (SELECT * FROM BACKUP);

现在使用您的查询