5

我在编写 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)
4

5 回答 5

8

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

alter table <<table_name>> modify (<<column_name>> [<<data type>>] null)
于 2013-10-06T17:11:22.500 回答
5

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

于 2013-10-06T17:10:30.143 回答
4

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

我的意思是' ' = ' '(单空格和双空格)应该评估truevarchar字段。

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

于 2013-10-06T19:06:27.590 回答
0

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

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

于 2013-10-07T07:09:21.933 回答
0

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

现在使用您的查询

于 2013-10-07T08:31:12.923 回答