暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

openGauss存储过程增强及SQL功能增强

原创 风一样自由 2024-11-13
175

一、存储过程增强

openGauss6.0新版本数据库存储过程增强,游标支持嵌套定义,cursor 定义中可以再定义子 cursor。

(一)应用场景

1.‌处理复杂的查询逻辑‌:当需要在查询过程中进行多次筛选或处理时,嵌套游标可以提供更大的灵活性和控制能力。例如,在一个外层游标中处理每一行数据,然后使用内层游标进一步处理这些数据‌。

2.‌逐行处理数据‌:在处理大量数据时,嵌套游标可以逐行读取和处理数据,避免一次性加载所有数据到内存中,从而减少内存消耗和提高处理效率‌。

3.‌动态查询‌:在某些情况下,查询条件需要根据前一个查询的结果动态生成。嵌套游标可以在外层游标中获取某些条件,然后使用这些条件在内层游标中进行进一步的查询。

‌(二)功能测试

1.创建测试表

source_db=# create table family_tbl(id int, name varchar, job varchar);

CREATE TABLE

source_db=# create table age_tbl(id int, age int);

CREATE TABLE

source_db=# insert into family_tbl values (1, 'yyf', 'IT'),(2, 'jjj', 'NURSE'),(3, 'yyz', 'STUDENT');

INSERT 0 3

source_db=# insert into age_tbl values (1, 32),(2, 31),(3, 3);

INSERT 0 3


2.在存储过程中使用游标嵌套

source_db=# create or replace procedure p1

source_db-#  as

source_db$#      age_temp int;

source_db$#      name_temp varchar;

source_db$#      type emp_cur_type is ref cursor;

source_db$#      c2 emp_cur_type;

source_db$#      cursor c1 is SELECT t.age, CURSOR(SELECT name FROM family_tbl t1 where t1.id = t.id) abc FROM age_tbl t;

source_db$#  begin

source_db$#      OPEN c1;

source_db$#      loop

source_db$#      fetch c1 into age_temp, c2;

source_db$#      exit when c1%notfound;

source_db$#      raise notice 'age : %',age_temp;

source_db$#        loop

source_db$#           fetch c2 into name_temp;

source_db$#           exit when c2%notfound;

source_db$#           raise notice 'name : %', name_temp;

source_db$#        end loop;

source_db$#        close c2;

source_db$#      end loop;

source_db$#      CLOSE c1;

source_db$#  end;

source_db$#  /

CREATE PROCEDURE


3.调用存储过程

source_db=# call p1();

NOTICE:  age : 32

NOTICE:  name : yyf

NOTICE:  age : 31

NOTICE:  name : jjj

NOTICE:  age : 3

NOTICE:  name : yyz

 p1

----


二、SQL功能增强

(一)管道函数

openGauss6.0版本支持PIPELINED 管道函数,函数可以返回行集合。

1.应用场景

在openGauss数据库中,管道函数是一种特殊的函数,用于流式处理大量数据。管道函数可以分批次处理数据,而不是一次性加载全部数据到内存中,这对于处理大规模数据集非常有用。

2.功能测试

(1)创建管道函数

source_db=# create or replace type MsgType as table of varchar2(4000);

CREATE TYPE

source_db=# create or replace function f_pipeline_test return MsgType

source_db-#     PIPELINED as

source_db$#           begin

source_db$#         for i in 1 .. 10 loop

source_db$#           pipe row('Iteration ' || i || ' at ' || CURRENT_TIMESTAMP);

source_db$#           pg_sleep(1);

source_db$#        end loop;

source_db$#        pipe row('All done!');

source_db$#        return;

source_db$#        end;

source_db$#    /

CREATE FUNCTION


(2)调用管道函数

source_db=# select * from table( f_pipeline_test );

                f_pipeline_test

-----------------------------------------------

 Iteration 1 at 2024-11-13 15:51:10.040849+08

 Iteration 2 at 2024-11-13 15:51:10.04128+08

 Iteration 3 at 2024-11-13 15:51:11.04244+08

 Iteration 4 at 2024-11-13 15:51:12.043706+08

 Iteration 5 at 2024-11-13 15:51:13.044874+08

 Iteration 6 at 2024-11-13 15:51:14.046069+08

 Iteration 7 at 2024-11-13 15:51:15.047488+08

 Iteration 8 at 2024-11-13 15:51:16.048629+08

 Iteration 9 at 2024-11-13 15:51:17.049801+08

 Iteration 10 at 2024-11-13 15:51:18.050931+08

 All done!

(11 rows)


(二)行列转换

openGauss6.0版本中,SELECT 语句支持通过 ROTATE 和 NOT ROTATE 子句进行行列转换。

1.应用场景

(1)‌数据透视‌:将原始数据按照某一列进行分组,并将其他列的值进行合并,生成透视表。例如,在Oracle中,可以使用PIVOT函数来实现行转列操作,从而生成所需的数据透视表‌。

(2)‌数据汇总‌:将多个行数据按照指定的列进行汇总,生成一条汇总数据。这种操作常用于将某一列的值作为新的列名,并将对应的值填入相应的位置‌。

(3)‌数据展示‌:将多条行数据进行合并,生成一行展示数据。这种操作可以使数据更加紧凑和易于展示‌。

(4)‌数据分析‌:在数据分析中,行转列函数可以用于对数据进行重排或重新组织,例如,通过行列转换函数进行数据透视表操作、数据聚合等‌。

2.功能测试

(1)创建表t_original_orders

source_db=# create table t_original_orders (id int, year int, order_mode text, order_total int);


(2)向表t_original_orders中插入记录

source_db=# insert into t_original_orders values (1,2020,'direct',5000), (2,2020,'online',1000), (3,2021,'online',1000), (4,2021,'direct',1000), (5,2022,'direct',5000), (6,2020,'direct',500);

INSERT 0 6

source_db=# select * from t_original_orders;

 id | year | order_mode | order_total

----+------+------------+-------------

  1 | 2020 | direct     |        5000

  2 | 2020 | online     |        1000

  3 | 2021 | online     |        1000

  4 | 2021 | direct     |        1000

  5 | 2022 | direct     |        5000

  6 | 2020 | direct     |         500

(6 rows)


(3)使用rotate将表t_original_orders中数据行转列输出

source_db=# select * from ( select year, order_mode, order_total from t_original_orders) rotate (sum(order_total) for order_mode in ('direct' as store, 'online' as internet)) order by year;

 year | store | internet

------+-------+----------

 2020 |  5500 |     1000

 2021 |  1000 |     1000

 2022 |  5000 |


(4)创建表t_rotate_orders

source_db=# create table t_rotate_orders as (select * from (select year, order_mode, order_total from t_original_orders) as t rotate (sum(order_total) for order_mode in ('direct' as store, 'online' as internet)) order by year);

INSERT 0 3


(5)使用not rotate将表t_rotate_orders中数据列转行输出

source_db=# select * from t_rotate_orders not rotate ( yearly_total for order_mode in ( store as 'direct', internet as 'online'));

 year | order_mode | yearly_total

------+------------+--------------

 2020 | direct      |         5500

 2021 | direct      |         1000

 2022 | direct      |         5000

 2020 | online     |         1000

 2021 | online     |         1000

(5 rows)



 

 

最后修改时间:2024-11-13 16:50:56
文章转载自风一样自由,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论