微信公众号: 老杜随笔 关注可了解更多的文章。问题或建议,请公众号留言;
Oracle 21c 引入了一个新的分析函数 CHECKSUM,它可以为一个或多个列计算校验和,用于检测数据的完整性,这个函数可以用于替代 DBMS_SQLHASH.GETHASH 函数。也可以用于检查表的内容是否已变更。
一、初始化示例数据
SQL> CREATE TABLE employees
2 ( employee_id NUMBER PRIMARY KEY,
3 first_name VARCHAR2(50),
4 last_name VARCHAR2(50),
5 email VARCHAR2(100),
6 hire_date DATE,
7 salary NUMBER,
8 deptno number(2)
);
Table created.
-- 插入样本数据
SQL> INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, salary, deptno )
2 VALUES (1, 'John', 'Doe', 'john.doe@example.com', TO_DATE('2022-01-01', 'YYYY-MM-DD'), 50000, 1);
1 row created.
SQL>
SQL> INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, salary, deptno )
2 VALUES (2, 'Jane', 'Smith', 'jane.smith@example.com', TO_DATE('2022-02-15', 'YYYY-MM-DD'), 60000, 2);
1 row created.
SQL>
SQL> INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, salary, deptno )
2 VALUES (3, 'Mike', 'Johnson', 'mike.johnson@example.com', TO_DATE('2022-03-20', 'YYYY-MM-DD'), 55000,2);
1 row created.
SQL> commit
2 ;
Commit complete.
二、CHECKSUM 聚合函数
CHECKSUM 函数返回一个8字节有符号长整型校验和,并转换为Oracle number 类型。这对于检查表的内容是否已更改非常有用。校验和基于一组行的传入表达式,该表达式不受行顺序的影响。表达式可以是列、常量、绑定变量或组合它们的表达式。它支持除ADT和JSON之外的大多数数据类型。可以选择对所有行或不同的行执行操作。 作为聚合函数,它减少了行数,因此称为“聚合”。
SQL> select checksum(first_name ) as row_checksum from employees ;
ROW_CHECKSUM
------------
775823
通过 GROUP BY 子句,获得更细粒度的信息。在下面的示例中,可以对部门的薪水求校验和。
SQL> select deptno ,
2 checksum(salary ) as checksum_id from
3 employees group by deptno order by deptno ;
DEPTNO CHECKSUM_ID
---------- -----------
1 612421
2 756575
向表加增加一行部门编号为“1”的数据,查看它如何影响校验和,并删除。
SQL> INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, salary, deptno )
2 VALUES (4, 'DU', 'XI', 'du@example.com', TO_DATE('2023-01-01', 'YYYY-MM-DD'), 60000, 1);
1 row created.
SQL>
SQL> select deptno ,
2 checksum(salary ) as checksum_id from
3 employees group by deptno order by deptno ;
DEPTNO CHECKSUM_ID
---------- -----------
1 722294
2 756575
SQL> select checksum(distinct salary ) as checksum_dept from employees ;
CHECKSUM_DEPT
-------------
519258
看到这会影响表的整体校验和,并且按部门编号分组查看他其实只影响 group by 查询中部门编号为“1”的校验和。
三、CHECKSUM 分析函数
CHECKSUM 分析函数的基本定义描述如下。
CHECKSUM "(" [ DISTINCT | ALL ] expr ")" [ OVER "(" analytic_clause ")" ]
显示薪水校验和以及所有原始数据。
SQL> select employee_id, first_name, deptno, salary, checksum(salary) over () as checksum_total from employees;
EMPLOYEE_ID FIRST_NAME DEPTNO SALARY CHECKSUM_TOTAL
----------- --------------------------------------------- ------ ---------- --------------
1 John 1 50000 752745
2 Jane 2 60000 752745
3 Mike 2 55000 752745
4 DU 1 60000 752745
需要注意的是,CHECKSUM 函数返回的是一个数字,如果列的值发生变化,即使是微小的变化,也可能导致校验和的变化。因此,CHECKSUM 不适合用于密码学上的校验和,它更适合用于快速比较或创建标识符。
