欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > oracle位运算、左移右移、标签算法等

oracle位运算、左移右移、标签算法等

2025/2/26 1:56:09 来源:https://blog.csdn.net/enthan809882/article/details/144981252  浏览:    关键词:oracle位运算、左移右移、标签算法等

文章目录

    • 位运算基础
      • 同或
        • 同或应用场景
      • 异或
        • 异或应用场景
      • 什么是真值表
    • oracle基础函数创建
        • bitor(按位或)函数
        • bitnot(按位非)函数
        • bitxor(按位异或)函数
        • 左移函数
        • BITSHIFT()函数(实测不可用,废弃掉该方案)
        • 右移函数(略,有此场景吗?)
    • 实际应用
      • 资质字典
      • 增删改查分别对应什么操作
        • 新增对应操作
        • 查询对应的操作
        • 修改
        • 删除(正向删除)(实际不用这个,而是直接update已修改的值)
        • 删除(直接用已修改好的值)
        • 统计
        • 位运算业务层的入参有几个
        • 删除的时候是给后台已算完的值,还是到后台自己算呢?
        • 查询条件是单个值还是多个值
        • 界面展示呢?
        • 编辑界面呢?
        • 十进制转二进制字符串

项目中有标签的场景,如一个人有多个角色,多个爱好,用关联表的方式不太优雅,用左移右移相对好一点。

位运算是个基础课题,也是个大课题,它的应用非常广泛,虽然有点绕,但是必须掌握。

位运算基础

与: 有0为0。

或: 有1为1。

非:0变1、1变0。

同或

同或:相同为1,不同为0。
同或真值表:

输入a输入b输出
001
010
100
111
同或应用场景

异或

异或:不同为1,相同为0。

异或真值表:

输入a输入b输出
000
011
101
110
异或应用场景

这篇文章不错:
https://www.cnblogs.com/codelogs/p/16676272.html

什么是真值表

一直在用,但是没有十分清楚,稀里糊涂算怎么回事。
真值表用于描述逻辑门的行为,即输入与输出的关系。

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也需要想想如何设置值。

删除(直接用已修改好的值)

直接赋值实际上是对的。

统计
位运算业务层的入参有几个

肯定需要字典表。

只有坐标应该不够吧,还需要边界,字典表是在字典表定义比较好呢,还是在哪里呢?

删除的时候是给后台已算完的值,还是到后台自己算呢?

如果直接保存,应该是已算完的值。

查询条件是单个值还是多个值

单个值 肯定可以,多个值呢?
多个值应该也可以? 传参需要转换。

那么界面的入参应该是列表,但是不是单选列表,而是可多选列表。

界面展示呢?

也是应该拆分展示,根据字典转换。

编辑界面呢?

实际上应该也是算好的。

十进制转二进制字符串

CREATE OR REPLACE FUNCTION DecimalToBinary(p_number NUMBER) RETURN VARCHAR2 ISv_binary VARCHAR2(4000);v_remainder NUMBER := p_number;
BEGINWHILE v_remainder > 0 LOOPv_binary := MOD(v_remainder, 2) || v_binary;v_remainder := TRUNC(v_remainder / 2);END LOOP;RETURN v_binary;
END;使用:
SELECT DecimalToBinary(19) FROM dual; # 10011

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词