文章目录
- oracle基础函数创建
- bitor(按位或)函数
- bitnot(按位非)函数
- bitxor(按位异或)函数
- 左移函数
- BITSHIFT()函数(实测不可用,废弃掉该方案)
- 右移函数(略,有此场景吗?)
- 实际应用
- 资质字典
- 增删改查分别对应什么操作
- 新增对应操作
- 查询对应的操作
- 修改
- 删除(正向删除)(实际不用这个,而是直接update已修改的值)
- 删除(直接用已修改好的值)
- 统计
- 位运算业务层的入参有几个
- 删除的时候是给后台已算完的值,还是到后台自己算呢?
- 查询条件是单个值还是多个值
- 界面展示呢?
- 编辑界面呢?
项目中有标签的场景,如一个人有多个角色,多个爱好,用关联表的方式不太优雅,用左移右移相对好一点。
oracle基础函数创建
首先oracle是不支持左移右移运算的。
select 1<<2 from dual; # 报错
select 4>>2 from dual; # 报错
自带的函数只有一个bitand。
select bitand(1,2) from dual; #支持
bitor(按位或)函数
create or replace function bitor(a in int,b in int)
return int
is
begin
return a+b-bitand(a,b);
end;
/ -- sql脚本窗口这个可以不执行。
bitnot(按位非)函数
create or replace function bitnot(a in int,b in int)
return int
is
begin
return (a+b)-bitand(a,b)*2;
end;
/ -- sql脚本窗口这个可以不执行。
bitxor(按位异或)函数
create or replace function bitxor(a in int ,b in int)
return int
is
beginreturn a+b-2*bitand(a,b);
end;
/ -- sql脚本窗口这个可以不执行。
左移函数
因为BITSHIFT()函数实测不可用,所以自己写个吧。
CREATE OR REPLACE FUNCTION left_shift (num IN NUMBER,bits IN NUMBER
) RETURN NUMBER IS
BEGINRETURN num * POWER(2, bits);
END;
/
例:
SELECT left_shift(10, 2) FROM dual;
BITSHIFT()函数(实测不可用,废弃掉该方案)
左移示例(报错):
SELECT BITSHIFT(123, 2, BINARY_INTEGER) AS left_shifted FROM DUAL;右移示例(报错):
SELECT BITSHIFT(123, -2, BINARY_INTEGER) AS right_shifted FROM DUAL;
右移函数(略,有此场景吗?)
主要是没有右移的场景吧。
实际应用
资质字典
qualification
int(11) NOT NULL COMMENT ‘1=监理2=安全员4=项目经理8=技术员16=特种作业人员32=劳务人员’, # 注:是整数类型
1=监理2=安全员4=项目经理8=技术员16=特种作业人员32=劳务人员
增删改查分别对应什么操作
新增对应操作
例如:有两种资质 1=监理 4=项目经理
语句:
SELECT 1<<0 | 1<<4 FROM dual; # 伪语句
SELECT bitor(left_shift(1,0) ,left_shift(1,4) ) FROM dual; # 17
查询对应的操作
注:这里oracle select不支持boolean值,这个要特别注意,见oracle笔记。
SELECTCASE bitand(QUALIFICATION,1)WHEN 0 THEN 0ELSE bitand(QUALIFICATION,1)END as 监理,CASE bitand(QUALIFICATION,2)WHEN 0 THEN 0ELSE bitand(QUALIFICATION,2)END as 安全员,CASE bitand(QUALIFICATION,4)WHEN 0 THEN 0ELSE bitand(QUALIFICATION,4)END as 项目经理
FROM EMP;
效果如图:
这是mysql的写法(这里永不到也先保留吧)。
select ,
(attrbute & (1<<0) !=0) as 监理,
(attrbute & (1<<1) !=0) as 安全员,
(attrbute & (1<<2) !=0) as 项目经理,
(attrbute & (1<<3) !=0) as 技术员,
(attrbute & (1<<4) !=0) as 特种作业人员,
(attrbute & (1<<5) !=0) as 劳务人员
from emp
修改
例如要增加安全员。
oracle写法:
update emp set qualification = bitor(qualification,left_shift(1,1)) where id = 1;mysql语法:
update emp set qualification = qualification | (1<<2) where id = 1;
删除(正向删除)(实际不用这个,而是直接update已修改的值)
删除是非的操作,但是值如果设置错了,反而会增加,如何避免增加呢?
删除的正确逻辑:
先bitnot(31,2) # 31是全量值,2是角色值 这样相当于把角色为设置为0
再bitand(19,BITnot(31,2)) # bitand角色位,相当于置0了
SELECT bitand(19,BITnot(31,2)) FROM dual
例如要删除安全员。
oracle写法:
update emp set qualification = bitand(qualification,BITnot(31,2)) where id = 1;
注:这里的31也需要想想如何设置值。
删除(直接用已修改好的值)
直接赋值实际上是对的。
统计
位运算业务层的入参有几个
肯定需要字典表。
只有坐标应该不够吧,还需要边界,字典表是在字典表定义比较好呢,还是在哪里呢?
删除的时候是给后台已算完的值,还是到后台自己算呢?
如果直接保存,应该是已算完的值。
查询条件是单个值还是多个值
单个值 肯定可以,多个值呢?
多个值应该也可以? 传参需要转换。
那么界面的入参应该是列表,但是不是单选列表,而是可多选列表。
界面展示呢?
也是应该拆分展示,根据字典转换。
编辑界面呢?
实际上应该也是算好的。