PL/SQL中‘’(空串)与Null的区别

本文详细解析了PL/SQL中空字符串与NULL的区别,并通过代码示例展示了如何正确判断空字符串及NULL值,揭示了在比较运算中的特殊结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家对Java中空字符串与null的区别早已是耳熟能详。那么在PL/SQL中,这二者又有何区别呢?
简单地来说,我们可以认为空字符串‘’等价于Null:即‘’is null。
二者的比较实际上涉及的是PL/SQL中Boolean值的问题。
PL/SQL中Boolean类型的值有3种:TRUE, FALSE, NULL。
NULL用来表示一个错误的,不合适的或者不确定的值。
Boolean值是不能打印的。

表达式              结果
'' IS NULL          TRUE
'' = NULL           NULL
'' <> NULL          NULL
NOT NULL            NULL
NULL=NULL           NULL
NULL<>NULL          NULL
'' = ''             NULL
'' <> ''            NULL
注:对空字符串‘’和Null进行任何的比较运算(>, <, =)或者算术运算(+, -, x, /) ,最后的结果都是:Null.

通过下面的代码,它们之间的关系就可以一目了然。 

DECLARE
   v_value VARCHAR2(100);
   v_bool  BOOLEAN := TRUE;
BEGIN

   /*
    * 0. Boolean值是不能打印的 
    * 判断一个Boolean值是TRUE, FALSE 可以用 = , NOT 
   */

   -- 编译出错
   --DBMS_OUTPUT.put_line('Boolean: ' || TRUE);

   -- 0.1 output: v_bool = TRUE
   IF v_bool
   THEN
      DBMS_OUTPUT.put_line('0.1 - v_bool = TRUE');
   END IF;

   -- 0.2 output: v_bool = TRUE
   IF v_bool
   THEN
      DBMS_OUTPUT.put_line('0.2 - v_bool = TRUE');
   END IF;

   -- 0.3 output: v_bool = FALSE
   v_bool := FALSE;
   IF v_bool = FALSE
   THEN
      DBMS_OUTPUT.put_line('0.3 - v_bool = FALSE');
   END IF;

   -- 0.4 output: v_bool = FALSE
   v_bool := FALSE;
   IF NOT v_bool
   THEN
      DBMS_OUTPUT.put_line('0.4 - v_bool = FALSE');
   END IF;

   /*
    * 1. 判断一个变量或值是不是空,要用 IS NULL 或者 IS NOT NULL 
    * 任何值(含'', null)与NULL进行比较操作(=, <>),结果仍是NULL
    * 对NULL进行NOT操作,结果仍是NULL
   */
   -- 1.1 yield: v_value IS NULL
   IF v_value IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.1 - v_value IS NULL');
   END IF;

   -- 1.2 yield: v_value IS NOT NULL
   v_value := '123';
   IF v_value IS NOT NULL
   THEN
      DBMS_OUTPUT.put_line('1.2 - v_value IS NOT NULL');
   END IF;

   -- 1.3 yield: (v_value = NULL) IS NULL
   IF (v_value = NULL) IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.3 - (v_value = NULL) IS NULL');
   END IF;

   -- 1.4 yield: (v_value <> NULL) IS NULL
   IF (v_value <> NULL) IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.4 - (v_value <> NULL) IS NULL');
   END IF;

   -- 1.5 yield: (NOT NULL) IS NULL
   IF (NOT NULL) IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.5 - (NOT NULL) IS NULL');
   END IF;

   -- 1.6 yield: (NULL = NULL) IS NULL
   IF (NULL = NULL) IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.6 - (NULL = NULL) IS NULL');
   END IF;

   -- 1.7 yield: (NULL <> NULL) IS NULL
   IF (NULL = NULL) IS NULL
   THEN
      DBMS_OUTPUT.put_line('1.7 - (NULL <> NULL) IS NULL');
   END IF;

   /*
    * 2. 判断一个空字符串是不是空,要用 IS NULL 或者 IS NOT NULL;而不是 = '' 或者 <> ''
   */
   -- 2.1 yield: '' IS NULL
   IF '' IS NULL
   THEN
      DBMS_OUTPUT.put_line('2.1 - '''' IS NULL');
   END IF;

   -- 2.2 yield: ('' = '') : IS NULL
   IF ('' = '') IS NULL
   THEN
      DBMS_OUTPUT.put_line('2.2 - ('''' = '''') : IS NULL');
   END IF;

   -- 2.3 yield: ('' <> '') : IS NULL
   IF ('' <> '') IS NULL
   THEN
      DBMS_OUTPUT.put_line('2.3 - ('''' <> '''') : IS NULL');
   END IF;

   /*
    * 3. 对NULL进行算术运算,得到的结果仍为NULL
   */
   -- 3.1 yield: 
   DBMS_OUTPUT.put_line('123 + NULL =' || (123 + NULL));
   DBMS_OUTPUT.put_line('123 - NULL =' || (123 - NULL));
   DBMS_OUTPUT.put_line('123 * NULL =' || (123 * NULL));
   DBMS_OUTPUT.put_line('123 / NULL =' || (123 / NULL));

   /*
    * 4. 对NULL进行concatenation运算,得到的结果为不为空的那个操作数
   */
   DBMS_OUTPUT.put_line('123 || NULL =' || (123 || NULL));

END;


 

 

<think>嗯,用户问的是数据库表中null空串区别。这个问题看起来基础,但实际应用中确实容易混淆。我得先理清楚两者的定义和区别。 首先,null和空字符串在数据库里都是表示“没有数据”的情况,但它们的含义不同。我记得null代表的是未知或缺失的数据,也就是说这个字段还没有被赋值,或者不适用。而空字符串是一个具体的值,只不过长度为零。比如,用户填表单时,如果没填某个字段,数据库里可能存null,但如果填了一个空,可能就是空字符串了。 接下来要比较它们在数据库中的处理方式。比如,在SQL查询中,判断null需要用IS NULL或IS NOT NULL,而空字符串可以直接用= ''或者<> ''。举个例子,SELECT * FROM table WHERE column IS NULL; 和SELECT * FROM table WHERE column = ''; 会得到不同的结果。 存储方式也可能不同。null通常不占用物理存储空间,而空字符串可能需要存储一个长度为零的字符串,不过这可能因数据库系统而异。比如MySQL中,空字符串确实会占用一点空间,而null则不会。 还有索引的影响。如果字段允许null,索引可能会包含null值,但有些数据库在创建唯一索引时,可能会有不同的处理方式。比如,某些数据库允许唯一索引字段有多个null,但空字符串只能出现一次,因为它们是实际的值。 默认值也是一个区别。创建表的时候,如果字段设置为NOT NULL,默认值可能需要指定,而允许null的话,默认可能就是null。空字符串的话,可能需要显式设置默认值为''。 应用场景方面,比如用户的中间名可能允许null,表示不适用,而如果用户明确不提供,可能用空字符串。不过这里可能要看具体业务需求。 可能还要注意不同数据库系统的差异,比如Oracle会把空字符串视为null,但其他数据库如MySQL、PostgreSQL则区分两者。这点需要特别提醒用户,避免跨数据库迁移时出现问题。 用户可能的疑问还包括性能上的考虑,null和空字符串哪个更好。一般来说,null可能在某些情况下更高效,但具体还要看使用场景和数据库的实现。 最后要总结两者的关键区别,帮助用户明确何时使用null,何时使用空字符串。可能还要提醒在设计和查询时注意正确的语法,避免因为混淆导致查询结果错误。</think>### 逐步解析:数据库表中 `NULL` 和空串(`''`)的区别 --- #### **1. 本质区别** - **`NULL`** - 表示 **未知、缺失或不适用的值**。 - 属于数据库的 **特殊标记**,代表“无数据”。 - 示例:用户未填写年龄字段时,存储为 `NULL`。 - **空串(`''`)** - 表示 **已知且明确存在的空值**。 - 属于 **字符串类型** 的合法值,长度为0。 - 示例:用户明确填写了姓名字段但留空,存储为 `''`。 --- #### **2. 查询语法差异** - **判断 `NULL`** 需使用 `IS NULL` 或 `IS NOT NULL`: ```sql SELECT * FROM users WHERE age IS NULL; ``` - **判断空串** 直接使用等号(`=`)或不等号(`!=`): ```sql SELECT * FROM users WHERE name = ''; ``` ⚠️ 错误示例: ```sql SELECT * FROM users WHERE name IS NULL; -- 无法匹配空串 SELECT * FROM users WHERE age = ''; -- 类型不匹配(若 age 是数值型) ``` --- #### **3. 存储索引行为** | 特性 | `NULL` | 空串(`''`) | |---------------------|-------------------------------|---------------------------| | 存储空间占用 | 通常不占用空间(标记位存储) | 占用空间(存储长度为0的字符串) | | 唯一索引约束 | 可能允许多个`NULL`(取决于数据库) | 仅允许一个空串(视为具体值) | | 聚合函数处理 | `COUNT(column)` 会忽略`NULL` | 空串会被统计 | --- #### **4. 默认值约束** - **默认值设置** ```sql CREATE TABLE users ( -- 允许 NULL,默认未赋值时为 NULL notes VARCHAR(100), -- 禁止 NULL,默认未赋值时为空串 address VARCHAR(100) NOT NULL DEFAULT '' ); ``` - **非空约束** - 若字段定义为 `NOT NULL`,则不能插入 `NULL`,但可以插入空串(需字段为字符串类型)。 --- #### **5. 应用场景建议** - 使用 `NULL` 的场景: - 数据缺失或未知(如未填写的可选字段)。 - 区分“未设置”和“明确留空”。 - 使用空串的场景: - 明确表示“无内容”(如用户填写了空白的备注)。 - 需要参字符串操作(如拼接 `CONCAT('Hello', name)`)。 --- #### **6. 常见数据库差异** - **Oracle** 将空串自动转换为 `NULL`,两者无区别。 - **MySQL/PostgreSQL/SQL Server** 严格区分 `NULL` 和空串。 --- ### 总结表格 | 维度 | `NULL` | 空串(`''`) | |-----------|-----------------------------|---------------------------| | **语义** | 未知或缺失 | 已知且明确为空 | | **查询语法**| `IS NULL`/`IS NOT NULL` | `= ''`/`!= ''` | | **存储** | 通常不占空间 | 占空间(字符串类型) | | **索引** | 可能允许多个`NULL` | 视为唯一值 | | **适用性** | 区分“未设置”和“无内容” | 明确表示“无内容” | 通过合理选择 `NULL` 或空串,可以更精确地描述数据状态,避免逻辑错误!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值