动态SQL语句
动态SQL语句
我们经常使用的SQL语句大多都是静态的,也就是说,SQL语句的结构是
固定的,当编译Script时,整个SQL语句都是已知的,它们不能在运行时动态
的改变。但是,在很多情况下,SQL语句或SQL所带的参数在编译时并不知道,
应用必须在运行时才能生成SQL语句。这种在运行时才能生成的SQL语句叫动
态SQL语句。动态SQL允许应用程序向数据库发送任何查询。此外,某些类型
的操作,尤其是数据定义语言(DDL)的语句如CREATE和DROP等,对嵌入
式SQL根本就不可能。动态SQL使得可以象发送查询一样向数据库发送DDL
和数据存取语言(DateAccessLanguage)的语句。
如果在预编译时下列信息不能确认,就必须使用动态SQL技术,如:
1)SQL语句正文
2)主变量个数
3)主变量的数据类型
4)SQL语句中引用的数据库对象(例如列、索引、基本表、视图等)
动态SQL方法允许在程序运行过程中临时“组装”SQL语句,主要有三种
形式:
1)语句可变:允许用户在程序运行时临时输入完整的SQL语句。
2)条件可变:对于查询语句,Select子句是确认的,即语句的输出是确定
的,其他子句(如Where子句、Having短语)有一定的可变性。
3)数据库对象,查询条件均可变:对于查询语句,Select子句的列名、From
子句中的表名或视图名、Where子句和Having短语中的条件均可由用户临时构
造,即语句的输入和输出可能都是不确定的。
1动态SQL执行方法
在SQLServer中有两种方法执行动态SQL语句,一是使用Sp_Executesql
系统存储过程,二是使用EXECUTE()。有时这两种方法产生同样的结果,不过
在其如何运行上却有着一些不同点。
1.1普通SQL语句可以用Exec执行
Select*FromTableName
Exec('Select*FromTableName')
ExecSp_ExecutesqlN'Select*FromTableName'--请注意字符串前一定要加
N
1.2字段名字段名、、表名表名、、数据库名之类作为变量时数据库名之类作为变量时,,必须用动态SQL
Declare@fnameVarchar(20)
Set@fname='FiledName'
--Select@fnameFromTableName
--错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec('Select'+@fname+'FromTableName')
--请注意加号前后的单引号的边上加空格***************************************************************
--当然将字符串改成变量的形式也可
Declare@fnameVarchar(20)
Set@fname='FiledName'--设置字段名
Declare@sVarchar(1000)
Set@s='Select'+@fname+'FromTableName'
Exec(@s)--成功
--ExecSp_Executesql@s--此句会报错
***************************************************************
Declare@sNvarchar(1000)
--注意此处改为Nvarchar(1000)(必须为Ntext或Nchar哐Nvarchar类型,
不能是Varchar类型)
Set@s='Select'+@fname+'FromTableName'
Exec(@s)--成功
ExecSp_Executesql@s--此句正确
1.3输入参数
Declare@QueryStringNvarchar(1000)
--动态查询语句变量(注:必须为Ntext或Nchar哐Nvarchar类型,不能是
Varchar类型)
Declare@paramstringNvarchar(200)
--设置动态语句中的参数的字符串(注:必须为Ntext或Nchar哐Nvarchar类
型,不能是Varchar类型)
Declare@input_idInt--定义需传入动态语句的参数的值
Set@QueryString='Select*FromTableNameWhereid=@id'
--id为字段名,@id为要传入的参数
Set@paramstring='@idInt'--设置动态语句中参数的定义的字符串
Set@input_id=1--设置需传入动态语句的参数的值为1
ExecSp_Executesql@querystring,@paramstring,@id=@input_id
***************************************************************
--若有多个参数:
Declare@QueryStringNvarchar(1000)
--动态查询语句变量(注:必须为Ntext或Nchar哐Nvarchar类型,不能是
Varchar类型)
Declare@paramstringNvarchar(200)
--设置动态语句中的参数的字符串(注:必须为Ntext或Nchar哐Nvarchar类
型,不能是Varchar类型)
Declare@input_idInt--定义需传入动态语句的参数的值,参数1
Declare@input_nameVarchar(20)--定义需传入动态语句的参数的值,参数2
Set@QueryString='Select*FromTableNameWhereid=@idand
name=@name'
--id与name为字段名,@id与@name为要传入的参数
Set@paramstring='@idInt,@nameVarchar(20)'
--设置动态语句中参数的定义的字符串,多个参数用","隔开Set@input_id=1
--设置需传入动态语句的参数的值为1
Set@input_name='张三'
--设置需传入动态语句的参数的值为"张三"
ExecSp_Executesql@querystring,@paramstring,@id=@input_id,@name=@input_name--请注意参数的顺序
1.4输出参数
Declare@numInt
Declare@sqlsNvarchar(4000)
Set@sqls='SelectCount(*)FromTableName'
Exec(@sqls)
--如何将Exec执行结果放入变量中?
Declare@numInt
Declare@sqlsNvarchar(4000)
Set@sqls='Select@a=Count(*)FromTableName'
ExecSp_Executesql@sqls,N'@aIntoutput',@numoutput
Select@num
此外,如果想要在SQL语句,字符串中使用单引号''可以通过''''转义。
***************************************************************
Declare@numInt,@sqlsNvarchar(4000)
Set@sqls='SelectCount(*)FromTableName'
Exec(@sqls)
--如何将Exec执行结果放入变量中?
Declare@QueryStringNvarchar(1000)
--动态查询语名变量(注:必须为Ntext或Nchar哐Nvarchar类型,不能是
Varchar类型)
Declare@paramstringNvarchar(200)
--设置动态语句中的参数的字符串(注:必须为Ntext或Nchar哐Nvarchar类
型,不能是Varchar类型)
Declare@output_resultInt
--查询结果赋给@output_result
Set@QueryString='Select@totalCount=Count(*)FromTableName'
--@totalCount为输出结果参数
Set@paramstring='@totalCountIntoutput'
--设置动态语句中参数的定义的字符串,多个参数用","隔开
ExecSp_Executesql@querystring,@paramstring,@totalCount=@output_resultoutputSelect@output_result
--当然,输入与输出参数可以一起使用,大家可以自己去试一试。
***************************************************************
--另外,动态语句查询的结果集要输出的话,可以用临时表的方法:
IFobject_id('[tempdb].[dbo].#tmp')ISNOTNULL--判断临时表#tmp是否存
在,存在则删除
droptable#tmpSelect*Into#tmpFromTableNameWhere1=2
--创建临时表#tmp,其结构与TableName相同
Declare@QueryStringNvarchar(1000)
--动态查询语名变量(注:必须为Ntext或Nchar哐Nvarchar类型,不能是
Varchar类型)
Set@QueryString='Select*FromTableName'
insertInto#tmp(field1,field2,)Exec(@querystirng)
1.5Sp_Sp_ExecutesqlExecutesql与EXECUTE()区别
系统存储过程Sp_Executesql允许参数可被传递进入或传出动态的SQL语
句,而EXECUTE()则不然。因为SQL语句是作为一个参数被传递给Sp_Executesql
存储过程中的,与EXECUTE()相比,它不易受到SQL注入式攻击。因为
Sp_Executesql是一个存储过程,所以将SQL字符串传递给它可以使SQL字符串
有更多的机会被放置在高速缓存中。Sp_Executesql可以生成清晰而且容易阅读
和维护的代码。
--EXEC语句
DECLARE@mVarchar(500)
DECLARE@sVarchar(20)
Select@s='string‘,
Set@m='Select*FromtblNameWhereemaillike''%'+@s+'%'''
EXEC(@m)
--Sp_Executesql语句
DECLARE@mNvarchar(500)
DECLARE@sVarchar(20)
Select@s='string‘,
Set@m='Select*FromtblNameWhereemaillike''%''+@s+''%'''
EXECSp_Executesql@m,N'@sVarchar(20)',@s
说明:动态SQL语句的执行性能稍差于静态SQL(随着查询复杂程度及数
据量的增大,二者间的性能差异会很小),但其可维护性较好;
Sp_Executesql的性能稍强于Exec,并且前者的查询缓存执行计划可重用性
较高;Sp_Executesql结合参数化查询,可防止SQL注入式攻击
oracle中executeimmediate的使用
oracle中executeimmediate的使用
EXECUTE IMMEDIATE 是 Oracle 数据库的一个动态 SQL 语句执行命令。它允许在运行时动态地构建和执行 SQL 语句的字符串,而不需要预编译。
EXECUTEIMMEDIATE执行的SQL语句可以是任何有效的SQL语句,包括SELECT、INSERT、UPDATE、DELETE等语句。它可以使用变量和参数进行动态的值替换。使用EXECUTEIMMEDIATE可以在运行时根据不同的条件和需求构建不同的SQL语句,从而实现更大的灵活性和可重用性。以下是EXECUTEIMMEDIATE的一些常见用法:
1.动态执行SELECT语句
可以使用EXECUTEIMMEDIATE动态执行SELECT语句,并将结果存储在变量中。例如:
DECLARE
l_emp_id NUMBER := 100;
l_emp_name VARCHAR2(100);
BEGIN
EXECUTE IMMEDIATE 'SELECT emp_name INTO :1 FROM employees
WHERE emp_id = :2' INTO l_emp_name USING OUT l_emp_name,
l_emp_id;
DBMS_OUTPUT.PUT_LINE('Employee Name: ' , l_emp_name);
END; 在上面的示例中,通过使用 USING OUT 子句将变量 l_emp_name 传递给 EXECUTE IMMEDIATE,并在动态 SQL 语句中使用该变量。使用 INTO
子句将结果存储在 l_emp_name 变量中。
2.动态执行DDL语句
EXECUTEIMMEDIATE还可以用于动态执行DDL(数据定义语言)语句,例如创建表、修改表结构等。例如:
DECLARE
l_table_name VARCHAR2(100);
16Mybatis_动态sql_if判断
16Mybatis_动态sql_if判断
mybatis的核⼼就是动态sql.
什么是动态sql:对sql语句进⾏灵活操作,通过表达式进⾏判断,对sql进⾏灵活拼接、组装。
这篇⽂章讲解sql中的if语句。它可以对查询条件进⾏判断,如果输⼊参数不为空才进⾏查询条件的拼接。这篇⽂章的核⼼就是下⾯的这段代
码。
and user.sex= #{userCustom.sex}
and ername=#{ername}
下⾯给出u具体案例:
案例代码结构如下:
除了userMapper.xml和Mybatis_mappertest.java要修改外,其他的代码都不⽤变。
userMapper.xml代码如下:
PUBLIC "-////DTD Mapper 3.0//EN"
"/dtd/mybatis-3-mapper.dtd">
SELECT id ,username FROM USER WHERE user.sex= #{userCustom.sex} AND ername=#{ername}
SELECT id id_,username username_ FROM USER
and user.sex= #{userCustom.sex}
and ername=#{ername}
测试代码Mybatis_mappertest.java代码如下:
package cn.itcast.mybatis.first;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
Oracle过程中执行动态SQL或DDL语句
如果你用的是 Oracle 8i 及以上的版本,那简单,在过程中用 execute immediate
sql_str 就行, sql_str 是一个拼凑的 SQL 语句,但这个动态语句中带参数,或 Select 的结果要 into 到变量中时就要稍加留心一下了。而在 8i 以前的版本(谁还用这么古老的玩艺,总有些不得已的地方,老系统考虑升级成本遗留下来的,应用软件所伴随着的等),都没法用 execute immediate,就得使用 DBMS_SQL 包来实现了
何谓动态 SQL 和 DDL 语句呢?通常在过程中要操作的表名、字段名都必须是明确的,否则编译过程时就要报错,但如果这两者也用变量名来表示就是动态的。DDL 就是数据库对象定义的操作,如 CREATE TABLE/VIEW/INDEX/SYN/CLUSTER……,及这些对象的删除、修改操作等等。
比如在
Oracle 中有执行下面过程块的意图时,就要使用到 execute immediate 或是
DBMS_SQL 包了。当然下面的语句块是通不过的。
declare
col_name varchar2(30) := 'name'; --假定表user存在name字段
col_val varchar2(30);
begin
select col_name into col_val --按照惯常思维,可能就会这么写
from user where age between 18 and 25; --编译时会提示列名不存在的
drop table t2; --不能直接执行 DDL 语句,后面查询 t2 编译器就无能为力了
end;
现在我们提出对上面问题的解,针对第一个 Select 语句来说明,并假设查询中还带有参数。块中的 DDL 也是类似的解法。例子因力图涵盖更多内容,所以稍显复杂,如果不需要 into (如 update/delete 语句),或者不带参数,会简单多了,应不难简化。有两种处理方法,以 8i 为分水岭。
Mybatis中的update动态SQL语句
Mybatis中的update动态SQL语句
Mybatis中的CRUD操作(增删改查)中,简单的SQL操作⽐较直观,如查找操作:
SELECT * FROM ENTITY_RELATION WHERE SRC_ID=#{srcId}
其中id对应同名java⽂件中的⽅法,resultMap对应的⾃定义的数据类型(当使⽤java⾃带类型就更容易了,⽐如ng.String之类的)。
但是涉及到更新操作时,可能不需要对所有字段更新,这时不需要更新的字段需要保持原字段信息,当使⽤以下信息就会报错:
update ENTITY_RELATION SET SRC_ID=#{srcId},SRC_TYPE=#{srcType},DEST_ID=#{destId},
DEST_TYPE=#{destType},REL_TYPE=#{relType},STATUS=#{status},SN_ID=#{snId}
where id=#{id}
因为不更新的字段,会被传递null到SQL中,引起异常。
这时就需要进⾏动态SQL拼接,如下,使⽤trim就是为了删掉最后字段的“,”。
主要不⽤单独写SET了,因为set被包含在trim中了:
UPDATE ENTITY_RELATION
SRC_ID=#{srcId},
SRC_TYPE=#{srcType},
DEST_ID=#{destId},
DEST_TYPE=#{destType},
REL_TYPE=#{relType},
STATUS=#{status},
SN_ID=#{snId},
WHERE id=#{id}
使用MySQL实现动态SQL查询和动态表名
使用MySQL实现动态SQL查询和动态表名
一、引言
MySQL是目前最流行的关系型数据库管理系统之一,它的灵活性和强大的功能使得它成为了众多开发者和企业的首选。在实际的应用中,我们常常会遇到需要根据不同的条件动态生成SQL语句和表名的情况。本文将介绍如何使用MySQL来实现动态SQL查询和动态表名。
二、动态SQL查询
动态SQL查询是指根据不同的条件生成不同的SQL语句,从而实现灵活的数据查询。在MySQL中,我们可以利用存储过程、预处理语句和动态执行语句来实现动态SQL查询。
1. 存储过程
存储过程是一组预定义的SQL语句和流程控制语句的集合,可以在执行之前编译和存储在数据库中。通过存储过程,我们可以通过参数的方式灵活地生成不同的SQL语句。例如,我们可以根据用户输入的条件动态地生成查询语句,并将结果返回给用户。
2. 预处理语句
预处理语句是一种特殊的SQL语句,可以提前对SQL语句进行编译和优化。在运行时,我们可以通过绑定变量的方式动态地传递参数,从而生成不同的SQL语句。预处理语句可以提高SQL语句的执行效率,并且可以防止SQL注入等安全问题。
3. 动态执行语句 动态执行语句是一种将SQL语句字符串作为变量进行拼接和执行的方式。通过动态执行语句,我们可以根据需要动态地生成SQL语句,并执行查询操作。然而,需要注意的是,动态执行语句的安全性和效率都比较低,容易导致SQL注入和性能问题,所以在使用时需要谨慎。
三、动态表名
动态表名是指在SQL语句中使用变量来表示表名,从而实现对不同表的操作。在MySQL中,我们可以通过存储过程、预处理语句和动态执行语句来实现动态表名。
1. 存储过程
存储过程可以通过参数的方式动态地生成不同的SQL语句,从而实现对不同表的操作。例如,我们可以根据用户输入的表名动态地生成查询语句,并将结果返回给用户。
2. 预处理语句
预处理语句可以通过绑定变量的方式动态地传递参数,从而实现对不同表的操作。在预处理语句中,我们可以使用占位符来表示表名,然后在运行时动态地将变量绑定到占位符上。
动态SQL的使用方法
动态SQL的使⽤⽅法
⼀般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使⽤SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使⽤,要想实现在PL/SQL中使⽤DDL语句及系统控制语句,可以通过使⽤动态SQL来实现。
⾸先我们应该了解什么是动态SQL,在Oracle数据库开发PL/SQL块中我们使⽤的SQL分为:静态SQL语句和动态SQL语句。所谓静态SQL指在PL/SQL块中使⽤的SQL语句在编译时是明确的,执⾏的是确定对象。⽽动态SQL是指在PL
Oracle中动态SQL可以通过本地动态SQL来执⾏,也可以通过DBMS_SQL包来执⾏。下⾯就这两种情况分别进⾏说明:
⼀、本地动态SQL
本地动态SQL是使⽤EXECUTE IMMEDIATE语句来实现的。
1、本地动态SQL执⾏DDL语句:
需求:根据⽤户输⼊的表名及字段名等参数动态建表。
create or replace procedure proc_test
(
table_name in varchar2, --表名
field1 in varchar2, --字段名
datatype1 in varchar2, --字段类型
field2 in varchar2, --字段名
datatype2 in varchar2 --字段类型
) as
str_sql varchar2(500);
begin
str_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;
execute immediate str_sql; --动态执⾏DDL语句
exception
when others then
null;
end ;
以上是编译通过的存储过程代码。下⾯执⾏存储过程动态建表。
SQL> execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);
MyBatis动态Sql语句
MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法
MyBatis中用于实现动态SQL的元素主要有:
if
choose(when,otherwise)
trim
where
set
foreach
1、if
对属性进行判断,如果不为空则执行判断条件
[html] view plain copy
resultMap="BaseResultMap">
select * from t_student
where
STU_ID = #{stuId}
and STU_NAME = #{stuName}
and STU_CLASS = #{stuClass}
and STU_SEX=#{stuSex}
and STU_AGE=#{stuAge}
来看看结果:
这是从web页面输入的参数
这是输出的结果
这是打印出来的Sql语句
从结果可以看出,只有在条件不为空的时候,属性才会赋值。
2、where
当where中的条件使用的if标签较多时,这样的组合可能会导致错误。我们以在1中的查询语句为例子,当输入参数stuId为空时,就会报错
然后是输出的结果:
此时SQL语句变成了select * from t_student where and STU_SEX=?这样会报错
如果上面例子,参数stuId为null,将不会进行STUDENT_NAME列的判断,则会直接导“WHERE AND”关键字多余的错误SQL。这时我们可以使用where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
简述一下动态sql的执行原理
1 / 2 简述一下动态sql的执行原理 动态 SQL 是 MyBatis 提供的一种功能,允许在 XML 映射文件中使用动态 SQL 元素,根据不同条件动态构建 SQL 语句。动态 SQL 的执行原理可以简要概括如下: 1. 解析 XML 映射文件: • MyBatis 在启动时解析 XML 映射文件,包括其中的动态 SQL 元素(如 、、 等)。 • 动态 SQL 元素被解析为相应的数据结构,如 SqlNode。 2. 构建 SQL 语句: • 在执行 SQL 语句前,MyBatis 根据动态 SQL 元素中的逻辑判断,决定是否包含或排除某些 SQL 片段。 • 动态 SQL 元素中的条件判断会根据运行时的参数进行动态计算。 3. 组装 SQL 语句: • 根据动态构建的 SQL 片段,MyBatis 组装最终的 SQL 语句。 • 这个组装过程可能会包含条件判断、循环拼接等动态逻辑。 4. 创建 SqlSource: • MyBatis 根据组装得到的 SQL 语句以及参数映射信息,创建一个 SqlSource 对象。 • SqlSource 包含了最终的 SQL 语句以及参数映射。 5. 创建 MappedStatement:
2 / 2 • MyBatis 使用 SqlSource 创建一个 MappedStatement 对象,它包含了 SQL 语句的信息,如 ID、参数映射、结果映射等。 • MappedStatement 是 MyBatis 中表示一条 SQL 语句的重要数据结构。 6. 执行 SQL: • 在运行时,当调用相应的 Mapper 接口方法时,MyBatis 根据 MappedStatement 获取 SQL 语句并执行。 • 动态 SQL 的条件判断和逻辑将在运行时进行计算,根据实际参数值动态构建 SQL 语句。 动态 SQL 的执行原理允许根据不同的条件生成不同的 SQL 语句,从而实现更加灵活的数据库操作。这使得开发者可以根据实际需求动态调整 SQL 语句,而不必事先写死所有可能的 SQL 变种。
mybatis动态sql语句if基本语法
mybatis动态sql语句if基本语法
MyBatis是一款流行的Java持久层框架,它提供了许多强大的功能,其中包括动态SQL语句的支持。在MyBatis的动态SQL语句中,if语句是非常常用的一个元素。本文将介绍MyBatis动态SQL语句中if语句的基本语法。
1. 简单的if语句
最基本的if语句是通过在SQL语句中使用if标签来实现的。if标签的使用格式如下:
```
SQL语句
```
这里的条件是一个表达式,如果表达式为true,则执行if标签内的SQL语句。
2. if-else语句
在MyBatis的动态SQL语句中,我们还可以使用if-else语句来实现条件判断。if-else语句的使用格式如下:
```
SQL语句1
SQL语句2
```
如果条件为true,则执行SQL语句1;否则执行SQL语句2。
3. 嵌套if语句
在MyBatis的动态SQL语句中,我们可以使用嵌套if语句来进行多重条件判断。嵌套if语句的使用格式如下:
```
SQL语句1
SQL语句2
```
如果条件1为true,则执行SQL语句1;如果条件2也为true,则执行SQL语句2。
4. if语句中使用参数
在MyBatis的动态SQL语句中,我们可以使用参数来动态地构建SQL语句。参数的使用格式如下:
```
SQL语句
```
如果参数不为null,则执行if标签内的SQL语句。
5. if语句中使用字符串比较
在MyBatis的动态SQL语句中,我们可以使用字符串比较来进行条件判断。字符串比较的使用格式如下:
```
Oracle动态SQL语句(2)之含变量的WHERE语句与日期变量
Oracle动态SQL语句(2)之含变量的WHERE语句与⽇期变量
在 Oracle 动态SQL语句(1)中提到基本动态SQL语句书写,但在写动态SQL语句时特别要注意⽇期型变量和WHERE语句的编写。
如下代码:
1、注意在执⾏动态SQL语句时,execute immediate ***关键语句,在调试过程中,最好把动态SQL语句即⼀个字符串赋值给⼀个字符变
量,
并⽤Dbms_output.put_line(SQL语句字符串)把SQL语句输出,⽅便查看SQL语句是否有误;
2、因动态SQL语句相对静态SQL语句的执⾏效率低,建议⽤静态SQL语句。如果⼀定要⽤,⼀定要注意变量的使⽤!!!
create or replace procedure sp_update_mnl00(i_id varchar,i_realtime DATE,i_min00 float, i_agv00 float,i_max00 float )
authid current_user as
/***********************
名称:sp_update_mnl00
功能描述:更新模拟量历史数据表中含00的列表项
修订记录:
版本号 编辑时间 编辑⼈ 修改描述1.0.0 2012-9-22 wy_laok 1.创建此存储过程
1.0.1 2012-9-21 wy_laok 2.修改表名称及变量名称,增加必要注释
⼊参出参描述:i_id 测点编号
i_realtime 更新时间
i_min00 最⼩值
i_agv00 平均值
i_max00 最⼤值
************************/
v_recordnum NUMBER:=0;--标识是否存在记录
v_tablename varchar2(30);--表名
v_sql_statement varchar2(200);--执⾏的SQL语句
v_time varchar2(30);--时间
