五. 执行查询操作
5.1 预备语句
预备语句(prepared statement) : 一个带有宿主变量的查询语句,每次查询的时候时只需要为该变量填入不同的字符串就可以反复多次地使用该语句。
在PreparedStatement预备语句中,每个宿主变量都用“?”来表示。如果存在一个以上的变量,那么在设置变量值时必须注意"?"的位置。
e.g.
String publishQuery = "SELECT * FROM table WHERE name=?"
PreparedStatement publishQueryStat = conn.prepareStatement(publishQuery);
(1)在执行预备语句之前,必须使用setXXX方法将变量绑定到实际值上。和ResultSet方法中得get方法类似。第一个参数是需要赋值的变量的位置,位置1标示第一个"?",第二个参数是赋予宿主变量的值。
(2)重用预备语句,需要通过set或调用clearParameters方法,否则所有宿主的变量的绑定都不会改变。也就是说,想要在一个查询到另一个查询中,重用预备语句,只需要使用setXXX方法。
(3)执行execute/executeQuery/executeUpdate
e.g. Result rs = publishQueryStmt.executeQuery();
注意:
(1)因为效率问题,当能通过复杂的SQL进行查询的情况下,不要通过JAVA代码来遍历结果集
(2)executeUpdate方法中的sql可以使用select子句。
e.g. String sql = "UPDATE books SET books.price=? where books.id=(select id from publish where publish.name=?)"
5.2 读写LOB
在SQL中二进制大对象称为BLOB,字符串大对象称为CLOB
(1)读取LOB,需要执行SELECT语句,然后在ResultSet上调用getBlob和getClob方法,这样就可以获得Blob和Clob对象。
要从Blob中获取二进制数据,可以调用getBytes或getInputStream。
要从Clob中获取字符数据,可以调用getSubString或getCharacterStream
e.g.
PreparedStatement stat = conn.prepareStatement("SELECT cover FROM book_covers WHERE isbn=?")
stmt.setInt(1, isbn);
ResultSet result = stmt.executeQuery();
if(result.next){
Blob coverBlob = result.getBlob(1);
Image coverImage = ImageIO.read(coverBlob.getInputStream());
}
(2)将LOB置于数据库中,需要在Connection对象上调用调用createBlob或createClob,然后获取一个用于该LOB的输出流或写出器,并将该对象存储到数据库中。
e.g.
Blob coverBlob = connection.createBlob();
int offset = 0;
OupputStream out = coverBlob.setBinaryStream(offset);
ImageIO.write(coverImage, "PNG", out);
PreparedStatement stat = conn.prepareStatement("INSERT INTO cover VALUES(?,?)")
stmt.set(1, isbn);
stmt.set(2, coverBlob);
stmt.executeUpdate();
5.3 SQL转义
转义主要用于特征:
(1)日期和时间字面常量
日期和时间字面常量在随数据库的不同而变化很大,要嵌入日期或时间字面常量,需要按照ISO 8601格式指定它的值。之后驱动程序会将其转换为本地格式。
其中d-DATE {d '2011-11-11'}, t-TIME {t '23:59:59'}, ts-TIMESTAMP {ts '2011-11-11 23:59:59'}
e.g.MySQL环境下例子
1)建表
String sql = String createTable = "CREATE TABLE test_table(d DATE, t TIME, ts TIMESTAMP)";
2)输入
String sql = "INSERT INTO test_table VALUES({d '2001-11-11'},{t '23:59:59'},{ts '2011-11-11 23:59:59'})";
connection.createStatement().executeUpdate(sql);
或
String sql = "INSERT INTO test_table values(?,?,?)";
PreparedStatement prepStat = conn.prepareStatement(sql);
long dateNumber = new java.util.Date().getTime();
for(int i=0;i<ch.length&&i<str.length;i++){
prepStmt.setDate(1, new Date(dateNumber));
prepStmt.setTime(2, new Time(dateNumber));
prepStmt.setTimestamp(3, new Timestamp(dateNumber));
prepStmt.executeUpdate();
}
prepStmt.close();
3)输出
Statement stat = conn.createStatement();
boolean haveResult = stmt.execute("select * from test_table");
if(haveResult){
do{
ResultSet result = stmt.getResultSet();
while(result.next()){
System.out.println(result.getDate(1)+","+result.getTime(2)+","+result.getTimestamp(3));
}while(stmt.getMoreResults());
}
(2)调用标量函数(scalar function)
是指仅返回一个数值的函数。在不同数据库中函数名存在差异,JDBC规范提供了标准的名字,并将其转义为数据库相关的名字。
e.g. {fn left(?,20)}
{fn user()}
具体支持内容在JDBC规范中
(3)调用存储过程
是在数据库中执行的用数据库相关的语言编写的过程。要调用存储过程,需要使用call转义命令,其中在存储过程没有任何参数的时候,就不用加上括号。另外,应该用=来捕获存储过程的返回值。
e.g. {call PROC1(?,?)}
{call PROC2}
{call ? = PROC3(?)}
(4)外连接(outer join)
两个表的外连接并不要求每个表的行都要根据连接条件进行匹配
e.g. SELECT * FROM {oj books LEFT OUTER JOIN publisher ON books.publisher_id = publisher.publisher_id}
这个查询的执行结果中包含有publisher_id在publisher表中没有任何匹配的书,其中publisher_id为null值的行,就表示不存在任何匹配。
如果使用RIGHT OUTER JOIN就可以包括没有任何匹配图书的出版商,而使用FULL OUTER JOIN可以同时返回这两类没有任何匹配的信息。
使用转义的原因 : 并非所有的数据库对于这些连接都使用标准写法,因此需要使用转义语法。
(5)在LIKE子句中的转义字符
由于在LIKE子句中_和%具有特殊含义(用来匹配一个字符或一个字符序列),所以不存在任何在字面上使用他们的标准方式。
e.g. 匹配所有包含_字符的字符串的结构
... WHERE ? LIKE %!_%{escape '!'}
这里我们将!定义为转义字符,而!_组合表示字符常量下划线_。
5.4 多结果集
在执行存储过程,或在使用允许在单个查询中提交多个SELECT语句的数据库时,一个查询可能会返回多个结果集。
(1)使用execute方法来执行SQL语句。
(2)获取第一个结果集或更新计数。
(3)重复调用getMoreResult方法移动到下一个结果集(这个调用会自动关闭前一个结果集)。
(4)当不存在更多的结果集或更新计数时,完成操作。
注意 : 如果由多个结果集构成的链的下一个是结果集,execute方法和getMoreResult方法将返回true,如果在链的下一项不是更新计数,getUpdateCount方法将返回-1。
try{
PreparedStatement prepStat = null;
try{
String sql = "SELECT * FROM test_table where key=? ";
prepStat = conn.prepareStatement(sql);
prepStmt.setString(1, "a");
boolean hasResult = prepStmt.execute();
if(hasResult){
do{
ResultSet result = prepStmt.getResultSet();
while(result.next()){
System.out.println(result.getInt("id"));
}
}while(prepStmt.getMoreResults());
}
}finally{
prepStmt.close();
}
}catch(SQLException e){
for(Throwable t : e){
e.printStackTrace();
}
}
5.5 获取自动生成键
大多数数据库都支持某种在数据库中对行自动计数的机制,不同提供商提供的数据库之间存在着很大的差异,而这些自动生成键经常用作主键。
JDBC中没有提供独立与提供商的自动生成键的解决方案,但是提供了获取自动生成键的有效途径。
e.g. 向数据库中插入新行,自动生成键的实现
stmt.executeUpdate(insertStatement, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
int key = rs.getInt(1);
}
分享到:
相关推荐
- 对于查询操作,则会显示返回的记录数。 **3. 错误信息提示** - 如果某条SQL语句出现错误,工具将显示来自DBMS的错误信息,便于用户定位问题。 #### 四、操作示例 以DB2数据库为例,演示如何使用《DB查询分析器...
在Java中执行SQL语句实现查询是非常常见的操作,以下是Java执行SQL语句实现查询的通用方法详解。 首先,需要获取数据库连接,使用JDBCTools.getConnection()方法来获取数据库连接。然后,使用PreparedStatement来...
执行场地,执行查询操作的实际位置,它可以与查询场地或源数据场地相同,也可能不同。这些场地的选择和优化对于查询性能至关重要。 以例5.1为例,假设有两个关系EMP和DEPT,优化过程可能涉及对这两个关系进行连接...
Oracle 执行计划是一种查询执行路径的表示形式,它展示了 Oracle 数据库在执行查询时访问数据的路径。下面是 Oracle 执行计划的详细解读,包括执行计划的定义、访问数据的方式、执行计划层次关系、实例解说 serta ...
LINQ不仅提供了一种新的方式来查询数据,还引入了一个丰富的标准查询操作符库,这些操作符可以用于执行各种各样的数据操作,例如过滤、排序、分组等。 #### 二、标准查询操作符的作用 标准查询操作符是一系列内置的...
五、explain执行计划 * explain执行计划可以查看查询的执行过程 六、distinct和group * distinct找出给定键所有不同的值 * group分组 七、游标 * 游标可以用于遍历查询结果 八、存储过程 * 存储过程可以用于...
- **查询执行**:一旦优化器决定了最佳执行路径,查询引擎就会按照该计划执行查询并返回结果。 **2. 预估与实际执行计划** SQL Server支持两种类型的执行计划:预估执行计划和实际执行计划。预估执行计划是在查询...
3. **使用Actual Execution Plan视图**:在SSMS中执行查询时,可以选择“包含实际执行计划”选项来查看图形化的执行计划。 4. **使用DMVs**:动态管理视图(DMVs)提供了有关执行计划的元数据信息。 #### 五、执行...
1. **并行查询(Parallel Query, PQ)**:并行查询是指将一个大的查询操作分成多个小的任务,这些小任务可以由不同的进程同时执行。例如,在进行全表扫描时,可以将表分成多个分区,每个分区由一个或多个并行执行...
### DB 查询分析器:中断 SQL 语句执行的利器 #### 一、背景介绍 在进行数据库查询或数据分析工作中,用户经常会遇到某些 SQL 语句执行时间过长的问题。特别是对于那些涉及大量数据处理的任务,即便是经过精心设计...
数据库查询语句执行顺序与编写顺序详解 数据库查询语句的执行顺序和编写顺序是数据库开发中非常重要的知识点。特别是在WHERE、GROUP BY、HAVING、ORDER BY同时出现时,执行顺序和编写顺序变得尤为重要。本文将详细...
SQL提供了强大的数据操作能力,包括查询、插入、更新和删除等操作,这些操作可以通过SQL执行语句来实现。 #### 二、SQL查询语句详解 ##### 1. `SELECT`语句基础 - **语法**: ```sql SELECT column1, column2, ....
实验内容分为两个部分:简单查询操作和连接查询操作。 1. 简单查询操作: - 投影:选取指定列,例如查询学生选课库中数学系学生的学号和姓名。 - 选择条件表达:根据特定条件筛选数据,如查询选修了课程的学生...
- **无须打开电气端盖**:全球首款可以在不打开电气端盖的情况下进行调试和查询的阀门执行器。 - **红外线设定器**:使用红外线设定器可以安全、快速地设定力矩值、限位等所有控制和指示功能,即使在危险区域也能...
执行计划包含了如何执行查询的具体步骤,如表扫描、索引查找、联接操作等。 #### 四、SQL Server 2005中的新逻辑处理阶段 SQL Server 2005引入了一些新的逻辑处理阶段,以支持更多复杂的查询需求: - **并行查询...
对于IBM的DB2数据库而言,理解和掌握执行计划的创建、分析以及更新机制,是提升查询性能、确保索引有效利用的关键。 **一、执行计划的创建** 当一个SQL语句被提交至DB2数据库,数据库优化器会根据一系列规则和统计...
#### 五、理解常见的执行计划访问路径 常见的执行计划访问路径包括: - **全表扫描**(Table Access Full): 当优化器认为扫描整个表比使用索引更快时,就会采用这种方式。 - **索引扫描**(Index Scan): 包括索引...
数据库系统原理的第五章主要讨论了查询处理与优化,这是数据库系统中的关键环节,直接影响到查询效率和系统性能。本章涵盖了查询处理的一般过程、代数优化、依赖于存取路径的优化以及规则优化等方面。 查询处理的...