行变列构建sql语句

博客展示了一个存储过程sp_test的代码。该存储过程接收表名、行变列条件列、需汇总列和根据变列的列名作为参数,通过动态游标、临时表和SQL语句实现特定功能,最后将生成的SQL语句插入表中,并清除临时表。

很久以前做开发时候写的存储过程.


CREATE OR REPLACE PROCEDURE sp_test (
   p_tablename     IN   CHAR, --表名
   p_columnname    IN   CHAR, --行变列的条件列(在此例中是xbie00)
   p_columnout     IN   CHAR, --需要汇总的列(此例是rs0000)
   p_columnwhere   IN   CHAR --根据那个列来变(此例是zrc000)
)
IS
   TYPE cur_typ IS REF CURSOR;

   c_1           cur_typ; --动态游标
   v_temptable   VARCHAR2 (50); --临时表
   v_sql         VARCHAR2 (200); --SQL语句
   v_count       NUMBER; --总数
   v_outsql      VARCHAR2 (300); --生成的sql语句
   v_temp        VARCHAR2 (200); --临时变量
   v_xbie00      CHAR (1); --性别
BEGIN
   BEGIN
      EXECUTE IMMEDIATE    'drop table '
                        || p_columnname
                        || '_temp'; --Drop临时表
   EXCEPTION
      WHEN OTHERS
      THEN
         NULL;
   END;

   v_temptable :=    p_columnname
                  || '_temp';
   v_sql :=    'create table '
            || v_temptable
            || ' as select '
            || p_columnname
            || ' from '
            || p_tablename
            || ' group by '
            || p_columnname
            || ' order by '
            || p_columnname;
   DBMS_OUTPUT.put_line (v_sql); --生成临时表(注意: 用户需要有create any table 系统权限
   EXECUTE IMMEDIATE v_sql;
   v_sql :=
             'select count(distinct '
          || p_columnname
          || ') from '
          || p_tablename; --有多少性别
   DBMS_OUTPUT.put_line (v_sql);
   EXECUTE IMMEDIATE v_sql
      INTO v_count;
   v_outsql := 'select t1.zrc000,';
   v_sql :=    'select '
            || p_columnname
            || ' from '
            || p_tablename
            || ' group by '
            || p_columnname; --构建SqL语句
  
/*
   v_sql :=    'select '
            || v_temp
            || p_columnname
            || ' ),from '
            || p_tablename
            || ' group by '
            || p_columnname;
*/
   OPEN c_1 FOR v_sql;

   LOOP
      FETCH c_1 INTO v_xbie00; --取性别
      EXIT WHEN c_1%NOTFOUND;
      v_temp :=    '(select '
                || p_columnout
                || ' from '
                || p_tablename
                || ' where '
                || p_columnname
                || ' = '
                || v_xbie00
                || ' and '
                || p_columnwhere
                || ' = t1.'
                || p_columnwhere
                || ' ),'; --对某个性别生成sql语句
      v_outsql :=    v_outsql
                  || v_temp; --构建sql语句
   END LOOP;

   CLOSE c_1;
   v_outsql := SUBSTR (v_outsql, 1,   LENGTH (TRIM (v_outsql))
                                    - 1); --把最后的','去掉
   v_outsql :=    v_outsql
               || ' from (select '
               || p_columnwhere
               || ' from '
               || p_tablename
               || ' group by '
               || p_columnwhere
               || ' ) t1'; --最后的sql部分

   DELETE      t_sql;

   INSERT INTO t_sql
               (str_sql)
        VALUES (v_outsql); --插入表中

   -- 清除临时表     
   BEGIN
      EXECUTE IMMEDIATE    'drop table '
                        || p_columnname
                        || '_temp'; --Drop临时表
   EXCEPTION
      WHEN OTHERS
      THEN
         NULL;
   END;
EXCEPTION
   WHEN OTHERS
   THEN
      raise_application_error (-20637,    'error : '
                                       || v_sql);
END;
/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/6906/viewspace-21559/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/6906/viewspace-21559/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值