使用动态SQL构造通用动态页面查询

由于动态SQL特有的灵活性,我们很容易的按照某种共性去构造通用和重用功能的代码,例如基于某个表的动态字段查询;

但凡事有利有弊;首先动态SQL语句无法在编译前期检查SQL是否正确,必须等到运行期才会发现问题;其次静态SQL是一次解析,多次执行,虽然动态SQL也可以使用绑定变量的方式,但是也会带来一些意想不到的性能问题,例如绑定变量在SQL要访问的表存在数据倾斜时会提供错误的执行计划;最后动态SQL语句可读性较差,比较难以维护。

下面我们就以比较经典的分页功能为例:

CREATE OR REPLACE Procedure sp_exec_dynamic_page

(

  i_tablename   VARCHAR2,    --表名 employees e,departments d

  i_tablecolumn VARCHAR2,    --查询列 a.employee_id,b.department_name

  i_where       VARCHAR2,    --查询条件 b.department_name like 'S%'

  i_ordercolumn VARCHAR2,    --排序 b.department_name desc

  i_pagesize    NUMBER,      --每页大小 20

  i_curpage     NUMBER,      --当前页 6

  o_rowcount    OUT NUMBER,  --返回总条数

  o_pagecount   OUT NUMBER,  --返回总页数

  o_cursor      OUT ref_cursor.t_RetDataSet --返回分页结果集

)

IS

  v_startrecord  INT;

  v_endrecord    INT;

  v_pagesize     INT;

  v_curpage      INT;

  v_tablecolumn  VARCHAR2(2000);

  v_where        VARCHAR2(2000);

  v_ordercolumn  VARCHAR2(200);

  v_count_sql    VARCHAR2(2000);

  v_select_sql   VARCHAR2(2000);

BEGIN

  --如果没有表名称,则直接返回异常消息

  --如果没有字段,则表示全部字段

  IF i_tablecolumn IS NOT NULL THEN

     v_tablecolumn:=i_tablecolumn;

  ELSE

     v_tablecolumn:=' * ';

  END IF;

  --可以没有WHERE条件

  IF i_where IS NOT NULL THEN

     v_where:=' WHERE 1=1 AND '||i_where||' ';

  ELSE

     v_where:=' WHERE 1=1 ';

  END IF;

  --可以没有ORDER BY条件

  IF i_ordercolumn IS NULL THEN

     v_ordercolumn:=' ';

  ELSE

     v_ordercolumn:=' ORDER BY '||i_ordercolumn;

  END IF;

  --如果未指定查询页,则默认为首页

  IF i_curpage IS NULL OR i_curpage<1 THEN

     v_curpage:=1;

  ELSE

     v_curpage:=i_curpage;

  END IF;

  --如果未指定每页记录数,则默认为10条记录

  IF i_pagesize IS NULL THEN

     v_pagesize:=10;

  ELSE

     v_pagesize:=i_pagesize;

  END IF;

  --查询总条数

  v_count_sql:='SELECT COUNT(*) FROM '||i_tablename||v_where;

  --构造最核心的查询语句

  v_select_sql:='(SELECT '||v_tablecolumn||' FROM '||i_tablename||v_where||v_ordercolumn||') e';

  --执行查询,查询总条数

  EXECUTE IMMEDIATE v_count_sql INTO o_rowcount;

  DBMS_OUTPUT.PUT_LINE('查询总条数SQL=>'||v_count_sql);

  DBMS_OUTPUT.PUT_LINE('查询总条数Count='||o_rowcount);

  --得到总页数,并进行处理

  IF MOD(o_rowcount,i_pagesize)=0 THEN

     o_pagecount:=o_rowcount/i_pagesize;

  ELSE

     o_pagecount:=FLOOR(o_rowcount/i_pagesize)+1;

  END IF;

  --如果当前页大于最大页数,则取最大页数

  IF i_curpage>o_pagecount THEN

     v_curpage:=o_pagecount;

  END IF;

  --设置开始结束的记录数

  v_startRecord := (v_curpage - 1) * v_pagesize + 1;

  v_endRecord := v_curpage * v_pagesize;

  --进行完整的动态SQL语句拼写

  v_select_sql:='SELECT * FROM '||

                '( '||

                '   SELECT e.*,ROWNUM rn '||

                '     FROM '||

                v_select_sql||

                '    WHERE ROWNUM<='||v_endRecord||

                ') '||

                ' WHERE rn>='||v_startRecord;

  DBMS_OUTPUT.PUT_LINE('查询SQL=>'||v_select_sql);

  OPEN o_cursor FOR v_select_sql;

END;

本文出自 “不胜人生一场醉” 博客,请务必保留此出处http://baoqiangwang.blog.51cto.com/1554549/530544

查看本栏目更多精彩内容:http://www.bianceng.cn/database/basis/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索sql
, 查询
, 动态查询
, 动态
, 字段
, varchar2
, sql动态查询
varchar
sql动态构造条件子句、建筑构造通用图集、建筑构造通用图集88j、条件构造器 通用查询、动态构造二维数组,以便于您获取更多的相关知识。

时间: 2024-08-03 12:49:23

使用动态SQL构造通用动态页面查询的相关文章

经常用到的交叉表问题,一般用动态SQL能生成动态列!

动态|问题 原始表如下格式:Class     CallDate    CallCount1 2005-8-8    401 2005-8-7    62 2005-8-8    773 2005-8-9    333 2005-8-8    93 2005-8-7    21 根据Class的值,按日期分别统计出CallCount1,CallCount2,CallCount3.当该日期无记录时值为0要求合并成如下格式:CallDate CallCount1 CallCount2 CallCou

通过非动态SQL语句在SQL Server中执行动态查询

问题: 我尝试在一个存储过程中传递一系列以逗号划定界限的值,以限制结果集.但是无论什么时候,我在 IN子句中使用变量,都会得到错误信息.是否存在一种不执行动态SQL语句也能完成查询的方式呢? 专家解答: 这里存在一种不执行动态SQL语句也能完成查询的方式,但是首先让我们来探究这个问题.我将在以下 例子中运用AdventureWorks数据库. 在你只有一个值的时候,执行将不会有什么问题. Declare @ManagerIDs Varchar(100) Set @ManagerIDs = '3'

用非动态SQL Server SQL语句来对动态查询进行执行

此文章主要向大家讲述的是非动态SQL ServerSQL语句执行动态查询,在实际操作中我尝试在一个存储过程中,来进行传递一系列以逗号划定界限的值,来对结果集进行限制.但是无论什么时候,我在IN子句中使用变量,都会得到错误信息. 是否存在一种不执行动态SQL语句也能完成查询的方式呢? 我尝试在一个存储过程中传递一系列以逗号划定界限的值,以限制结果集.但是无论什么时候,我在IN子句中使用变量,都会得到错误信息.是否存在一种不执行动态SQL ServerSQL语句也能完成查询的方式呢? 专家解答: 这

java版云笔记(九)之动态sql

SQL 首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程. 静态SQL 静态SQL通常用于完成可以确定的任务.(即在编译阶段就可以确定数据库要做什么事情.) select * from t1 where c1>5 对于上述类似的DML语句在第一次运行时进行编译,而后续再次调用,则不再编译该过程.即一次编译,多次调用,使用的相同的执行计划.此种方式被称之为使用的是静

PL/SQL动态SQL(原创)

概述 使用动态SQL是在编写PL/SQL过程时经常使用的方法之一.很多情况下,比如根据业务的需要,如果输入不同查询条件,则生成不同的执行SQL查询语句,对于这种情况需要使用动态SQL来完成.再比如,对于分页的情况,对于不同的表,必定存在不同的字段,因此使用静态SQL则只能针对某几个特定的表来形成分页.而使用动态的SQL,则可以对不同的表,不同的字段进行不同的分页.这些情况的处理通常都是用动态SQL来完成. 动态SQL和静态SQL静态SQL静态SQL通常用于完成可以确定的任务.比如传递部门号调用存

mybatis-MyBatis动态SQL的一些问题

问题描述 MyBatis动态SQL的一些问题 <select id=""findBySalary"" parameterType=""com.tarena.entity.Condition"" resultType=""com.tarena.entity.Emp""> select * from t_emp <choose> <when test="

PL/SQL --&amp;gt; 动态SQL

--==================== -- PL/SQL --> 动态SQL --====================         使用动态SQL是在编写PL/SQL过程时经常使用的方法之一.很多情况下,比如根据业务的需要,如果输入不同查询条件,则生成不同的执行 SQL查询语句,对于这种情况需要使用动态SQL来完成.再比如,对于分页的情况,对于不同的表,必定存在不同的字段,因此使用静态SQL则只 能针对某几个特定的表来形成分页.而使用动态的SQL,则可以对不同的表,不同的字段进行

Oracle基础 动态SQL语句

原文:Oracle基础 动态SQL语句 一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL中的DML和事务控制语句,但是DDL语句,以及会话控制语句却不能再PL/SQL中直接使用,如动态创建表或者某个不确定的操作时,这就需要动态SQL来实现. 2.动态SQL 动态SQL是指在PL/SQL编译时SQL语句是不确定的,如根据用户输入的参数的不同来执行不

MyBatis使用动态SQL标签的小陷阱_java

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 现在MyBatis越来越受大家的喜爱了,它的优势大家都知道,我就不多说了,直接说重点. MyBatis中提供动态SQL功能,我们可以使用<if><when&