Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4183962
  • 博文数量: 240
  • 博客积分: 11504
  • 博客等级: 上将
  • 技术积分: 4277
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-28 14:24
文章分类

全部博文(240)

分类: Mysql/postgreSQL

2014-01-12 20:28:52

我们经常会对数据字典中的系统表进行遍历,从而写一些SHELL脚本或者动态造数据等等。 这里我用PLSQL演示了三种方法来遍历一张表。  


表结构如下,

点击(此处)折叠或打开

  1. t_girl=# \d tmp_1;
  2.            Unlogged table "public.tmp_1"
  3.   Column | Type | Modifiers
  4. ----------+-----------------------------+-----------
  5.  id | integer |
  6.  log_time | timestamp without time zone |




在这里我创建里一个自定义类型来保存我的函数返回值。

点击(此处)折叠或打开

  1. create type ytt_record as (id int,log_time timestamp without time zone);


 
 现在来看第一个函数。 也是用最笨的方法来遍历。

点击(此处)折叠或打开

  1. create or replace function sp_test_record1(
  2. IN f_id int
  3. ) returns setof ytt_record as
  4. $ytt$
  5. declare i int;
  6. declare cnt int;


  7. declare o_out ytt_record;
  8. begin
  9.    i := 0;
  10.    cnt := 0;
  11.    select count(*) into cnt from tmp_1 where id > f_id;
  12.    while i < cnt
  13.    loop
  14.        select id,log_time into strict o_out from tmp_1 where id > f_id order by log_time desc limit 1 offset i;
  15.      i := i + 1;
  16.      return next o_out;
  17.    end loop;
  18. end;
  19. $ytt$ language plpgsql;





我们来执行下结果,花费了3毫秒左右。

点击(此处)折叠或打开

  1. t_girl=# select * from sp_test_record1(60);
  2.  id | log_time
  3. ----+----------------------------
  4.  85 | 2014-01-11 17:52:11.696354
  5.  73 | 2014-01-09 17:52:11.696354
  6.  77 | 2014-01-04 17:52:11.696354
  7.  80 | 2014-01-03 17:52:11.696354
  8.  76 | 2014-01-02 17:52:11.696354
  9.  65 | 2013-12-31 17:52:11.696354
  10.  80 | 2013-12-30 17:52:11.098336
  11.  85 | 2013-12-27 17:52:11.098336
  12.  97 | 2013-12-26 17:52:11.696354
  13.  94 | 2013-12-24 17:52:09.321394
  14. (10 rows)


  15. Time: 3.338 ms






现在来看第二个函数,这个就比较优化了, 用了系统自带的循环遍历结构。

点击(此处)折叠或打开

  1. create or replace function sp_test_record2(
  2. IN f_id int
  3. ) returns setof ytt_record as
  4. $ytt$


  5. declare o_out ytt_record;
  6. begin


  7.   for o_out in select id,log_time from tmp_1 where id > f_id order by log_time desc
  8.   loop
  9.      return next o_out;
  10.    end loop;
  11. end;
  12. $ytt$ language plpgsql;



这次运行结果看看,时间不到1毫秒。

点击(此处)折叠或打开

  1. t_girl=# select * from sp_test_record2(60);
  2.  id | log_time
  3. ----+----------------------------
  4.  85 | 2014-01-11 17:52:11.696354
  5.  73 | 2014-01-09 17:52:11.696354
  6.  77 | 2014-01-04 17:52:11.696354
  7.  80 | 2014-01-03 17:52:11.696354
  8.  76 | 2014-01-02 17:52:11.696354
  9.  65 | 2013-12-31 17:52:11.696354
  10.  80 | 2013-12-30 17:52:11.098336
  11.  85 | 2013-12-27 17:52:11.098336
  12.  97 | 2013-12-26 17:52:11.696354
  13.  94 | 2013-12-24 17:52:09.321394
  14. (10 rows)


  15. Time: 0.660 ms




最后一个函数, 利用RETURN QUERY 直接返回结果集。

点击(此处)折叠或打开

  1. create or replace function sp_test_record3(
  2. IN f_id int
  3. ) returns setof ytt_record as
  4. $ytt$


  5. begin
  6.   return query select id,log_time from tmp_1 where id > f_id order by log_time desc ;
  7. end;
  8. $ytt$ language plpgsql;





这个结果其实等同于直接从表SELECT,响应时间和第二个差不多。

点击(此处)折叠或打开

  1. t_girl=# select sp_test_record3(60);
  2.           sp_test_record3
  3. -----------------------------------
  4.  (85,"2014-01-11 17:52:11.696354")
  5.  (73,"2014-01-09 17:52:11.696354")
  6.  (77,"2014-01-04 17:52:11.696354")
  7.  (80,"2014-01-03 17:52:11.696354")
  8.  (76,"2014-01-02 17:52:11.696354")
  9.  (65,"2013-12-31 17:52:11.696354")
  10.  (80,"2013-12-30 17:52:11.098336")
  11.  (85,"2013-12-27 17:52:11.098336")
  12.  (97,"2013-12-26 17:52:11.696354")
  13.  (94,"2013-12-24 17:52:09.321394")
  14. (10 rows)


  15. Time: 0.877 ms
  16. t_girl=#







阅读(8945) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~