在oracle里使用UTL_RAW做汇总【转载】

本文探讨了如何通过优化SQL查询和构建汇总表来提高数据处理速度,特别是针对大量数据时的问题。详细介绍了如何使用二进制操作来减少重复计算,以及如何将多个store_key聚合为更高效的表示形式,从而显著降低统计时间。

我有一个表用来反映在不同时段下几个商店对某个物品的销售情况, 
period_key   item_key store_key

19980104     1      1
19980104     1      2
19980104     2      1
19980104     2      3
19990104     2      1
19990104     2      3

我主要想知道几个时段内物品在几家店有售。一般都用下面的sql来做
select count(distinct store_key)  from *
where period_key between ? and ?
and item_key =?


但数据太多, 统计时间太长, 所以想建一个汇总表来减少数据量. 象这样

period_key    item_key  distinct_store_key
19990104     1        1,2,5,7,9
20010104     2        2,5,6,8
..

但用distinct_store_key来找distinct count, 是字符操做, 也太慢, 我想把distinct_store_key变成其它格式, 下面用bit和位置来代表distinct_store_key

这样
{1,2,5,7,9} --> 101010011
{2,5,6,8} --> 010110010

然后进行或操作。

基本上,你的primary key有多少种取值可能,你用来代表这个table的数在二进制下就有多少位

UTL_RAW里有个函数BIT_OR很有用,我先把不同时段的store key放到一table的string字段里, 然后每次统计时用UTL_RAW.BIT_OR来得出几个时段中store key的并集, 再计算出并集中的count.

procedure test_raw_or IS
lvc_cursor ref_cursor;
lvn_counter BINARY_INTEGER;
lvs_a varchar2(4000);
RAW_a RAW(4000);
RAW_b RAW(4000);
RAW_c RAW(4000);
begin

OPEN lvc_cursor FOR
select bitmap_data from yh_bitmap;

lvn_counter := 0;
lvs_a := '';
LOOP
EXIT WHEN lvc_cursor%NOTFOUND;
lvn_counter := lvn_counter + 1;

FETCH lvc_cursor
INTO lvs_a;
RAW_a := UTL_RAW.CAST_TO_RAW(lvs_a);
if lvn_counter > 1 then
RAW_c := UTL_RAW.BIT_OR(RAW_a, RAW_b);
RAW_b := RAW_c;
else
RAW_b := RAW_a;
end if;

END LOOP;
CLOSE lvc_cursor;

insert into yh_calc_bitmap values (UTL_RAW.CAST_TO_varchar2(RAW_c));
commit;

end;

UTL_RAW.BIT_OR执行速度很快

### OracleUTL_RAW.CAST_TO_RAW 函数的用法与示例 `UTL_RAW.CAST_TO_RAW` 是 Oracle 提供的一个函数,用于将输入的字符串转换为 RAW 数据类型。RAW 类型是一种存储二进制数据的特殊数据类型,在处理加密、编码或网络通信时非常有用。 以下是 `UTL_RAW.CAST_TO_RAW` 的基本用法和示例: #### 基本语法 ```sql UTL_RAW.CAST_TO_RAW(input_string VARCHAR2) RETURN RAW; ``` - **input_string**: 输入的字符串,可以是普通的字符数据。 - 返回值: 转换后的 RAW 数据类型。 --- #### 示例 1:简单的字符串转换 以下示例展示了如何将普通字符串转换为 RAW 数据类型: ```sql SELECT UTL_RAW.CAST_TO_RAW('Hello World') AS raw_data FROM dual; ``` 此查询会将字符串 `'Hello World'` 转换为 RAW 格式[^1]。 --- #### 示例 2:在邮件发送中的应用 在 Oracle使用 `UTL_SMTP` 发送邮件时,通常需要对邮件头部(如主题)进行编码。以下是一个实际的例子: ```sql UTL_SMTP.WRITE_RAW_DATA( c, UTL_RAW.CAST_TO_RAW(CONVERT('Subject: ' || '来自Oracle数据库的邮件' || UTL_TCP.CRLF, 'ZHS16GBK')) ); ``` 上述代码中,`UTL_RAW.CAST_TO_RAW` 将包含主题的字符串转换为 RAW 数据类型,并结合 `CONVERT` 函数指定字符集编码[^1]。 --- #### 示例 3:与 BASE64 编码结合使用 在某些场景下,可能需要对用户名或密码进行 BASE64 编码后再转换为 RAW 数据类型。例如: ```sql DECLARE user_name RAW(200); BEGIN user_name := UTL_RAW.CAST_TO_RAW( UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW('[emailprotected]')) ); DBMS_OUTPUT.PUT_LINE(user_name); END; / ``` 此示例中,首先通过 `UTL_RAW.CAST_TO_RAW` 将电子邮件地址转换为 RAW,然后对其进行 BASE64 编码[^2]。 --- #### 示例 4:与其他加密功能结合 如果需要对数据进行加密操作,可以结合 `DBMS_CRYPTO` 包。例如: ```sql DECLARE encrypted_data RAW(200); input_string VARCHAR2(100) := 'Sensitive Data'; BEGIN -- 将字符串转换为 RAW encrypted_data := DBMS_CRYPTO.ENCRYPT( src => UTL_RAW.CAST_TO_RAW(input_string), typ => DBMS_CRYPTO.DES_CBC_PKCS5, key => UTL_RAW.CAST_TO_RAW('12345678') ); DBMS_OUTPUT.PUT_LINE(encrypted_data); END; / ``` 在此示例中,`UTL_RAW.CAST_TO_RAW` 用于将输入字符串转换为 RAW 格式,以便与 `DBMS_CRYPTO.ENCRYPT` 配合使用[^4]。 --- ### 注意事项 1. **字符集问题**: 在使用 `UTL_RAW.CAST_TO_RAW` 时,确保输入字符串的字符集与目标系统一致,否则可能导致乱码。 2. **权限问题**: 如果涉及 `DBMS_CRYPTO` 等高级功能,请确保用户具有相应的执行权限[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值