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

Posted

技术标签:

【中文标题】Oracle SQL 使用空字符串更新 NOT NULL 列【英文标题】:Oracle SQL Updating a NOT NULL column with an empty string 【发布时间】:2013-10-06 16:57:34 【问题描述】:

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

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 会抱怨空值。

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)

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

不幸的是我无法更新表。是否可以检查插入语句,如果为空,则将列更新为''?作为小骗子 不,因为 Oracle 无法区分 NULL 和空字符串。禁止 NULL 的相同约束将禁止空字符串。您将得到的最接近的方法是将其设置为包含单个空格的字符串。【参考方案2】:

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

【讨论】:

好的,但是在这种情况下,oracle 是如何允许插入语句工作的呢?如果我做一个插入,我可以将列中的值设置为'',我想复制这是一个更新语句【参考方案3】:

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

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

(我没有 Oracle 实例,所以我不能确定...)

【讨论】:

那行得通,不知道为什么我没有早点想到它,只是想把事情复杂化:(【参考方案4】:

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

比您有一些东西要检查以查看某些东西是否行为不正确或过滤视图中的三个问号或其他东西并再次将其显示为 NULL。

【讨论】:

【参考方案5】:

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

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

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);

现在使用您的查询

【讨论】:

以上是关于Oracle SQL 使用空字符串更新 NOT NULL 列的主要内容,如果未能解决你的问题,请参考以下文章

Oracle数据库空字符串和空字符串比较的问题

用于测试非空字符串和非空字符串的兼容 SQL

kibana查询搜索引擎字段为空字符串

Oracle sql 中的字符(串)替换与转换

总结Oracle sql 中的字符(串)替换与转换

Oracle SQL 查询计数组按时间戳子串