`

(四) 执行SQL语句

阅读更多

(1)在执行SQL命令之前,需要创建一个Statement对象。要创建Statement对象,需要使用DriverManager.getConnection方法所获得的Connection对象。
e.g.Statements stmt = conn.createStatement();

(2)将要执行的SQL语句放入字符串中
e.g.    String command = "UPDATE Books SET price = price - 5.00 WHERE title NOT LIKE '%introduction%' "
           
(3)调用Statements类中的executeUpdate方法
e.g.  stmt.executeUpdate(command);
        executeUpdate方法返回受SQL命令影响的行数,或者对于不返回行数的语句返回0。
注意:
1)executeUpdate方法可以即可执行INSERT,UPDATE和DELETE之类的操作,也可执行CREATE TABLE和DROP TABLE之类的数据定义语句。
2)执行SELECT方法必须使用executeQuery方法
3)execute方法可以执行任意SQL语句,此方法通常用于用户提供的交互式查询。

(4)查询结果的遍历
1)通过executeQuery方法返回一个ResultSet对象,可以通过它来每次一行的迭代遍历所有结果。
e.g.    ResultSet rs = stmt.executeQuery("SELECT * FROM table");
2)分析结果集时通常使用类似如下的循环语句代码:
e.g.  while(rs.next()){
            look at a row of result set
        }
结果集中顺序是任意的。除非使用ORDER BY子句进行指定行的顺序,否则不能为行序列强加任何意义。
注意 :ResultSet方法与java.util.Iterator方法不同,对于ResultSet类,迭代器初始化时被设定为在第一行之前的位置,必须调用next方法将它移动到第一行。并且ResultSet类没有hasNext方法,需要不断调用next方法,直到返回false。
3)通过访问器(accessor)方法获取每一行的信息,不同的数据类型有不同的访问器,比如getString和getDouble。
e.g.    String bookname = rs.getString(1);
          double price = re.getDouble("price");
每个访问器都有两种形式,一种接受数字参数,一种接受字符串参数。当使用数字参数时,是指所对应的列;当使用字符串参数时,指的是结果集中以该字符串为列名的列。
注意:使用数字参数效率更高一些,但使用字符串参数可以使代码易于阅读和维护。当get方法的类型和列的数据不一致时,每个get方法都会进行合理的类型转换,但当类型无法强转的时候会抛出java.sql.SQLException异常。例如,调用rs.getString("price")时,该方法会将price列的浮点值转换成字符串。

4.1 管理连接、语句和结果集
一个Connection对象都可以创建一个或多个Statement对象,同一个Statement对象可以用于多个不相关的命令和查询。但是,一个Statement对象最多只能打开一个结果集。如果需要执行多个查询操作,且需要同时分析查询结果,那么必须创建多个Statement对象。
至少有一种常用的数据库(SQLServer)的JDBC驱动程序只允许同时存在一个激活的Statements对象。使用DatabaseMeteData中的getMaxStatments方法,获取JDBC程序同时支持的语句对象的总数。
e.g.    conn.getMetaData().getMaxStatements();
实际上应该通过组合查询,就可以只分析一个结果。对数据库进行组合查询比用JAVA程序遍历多个结果集要更高效。

当使用完ResultSet,Statment或Connection对象时,应该立即调用close方法,这些对象都使用了规模较大的数据结构,所以不应该等待垃圾回收器来处理它们。
注意 : 如果Statements对象上有一个打开的结果集,那么调用close方法将自动关闭该结果集。同样Connection类的close方法将关闭该连接上的所有语句。
如果所有连接都是短时的,那么无需考虑关闭语句和结果集。只需要将close语句放finally块中,以便确保最终关闭连接对象。
try{
    Connection conn = ...;
    try{
        Statement stmt = conn.createStatement();
        ResultSet result = stmt.executeQuery(querySting);
        process query result...
    }finally{
    conn.close();
    }
}catch(SQLException e){
    handle exception
}
使用try/finally块关闭连接,而使用一个单独的try/catch块处理一次。分割try程序块可以提高代码的可读性和可维护性。

4.2 分析SQL异常
(1)每个SQLException都有一个由多个SQLException对象构成的链,这些对象可以通过getNextException方法获取。这个异常链是每个异常都具有由Throwable对象构成的“成因”链之外的异常链,因此需要两个嵌套的循环来完全枚举所有的异常。
Java SE 6改进了SQLException,实现了Iterator<Throwable>接口,调用iterator()方法产生迭代器,这个迭代器可以迭代这两个链。首先迭代第一个SQLException的成因链,然后迭代下一个SQLException。
e.g.  for(Throwable t : sqlException){
            do someting whit t
        }

(2)getSQLState/getErrorCode : 可以通过调用SQLException上的getSQLState和getErrorCode方法来进一步分析它。
1)getSQLState方法将产生符合X/Open和SQL:2003标准的字符串,比如42X01(调用DatabaseMetaData的方法getSQLStateType可以查出驱动程序所使用的标准)。
2)getErrorCode方法返回的错误代码是提供商相关的,比如Derby中的-1。

(3)Java SE 6开始,SQL异常按照层次结构树的方式组织到了一起,这使得我们可以按照提供商无关的方式来捕获具体的错误类型。
另外,数据库驱动程序可以将非致命问题作为警告报告,我们可以从连接、语句和结果集中获取这些警告。

(4)SQLWarning类是SQLException类的子类,且SQLWarning类不会被当做异常抛出,可以通过调用getSQLState和getErrorCode来获取有关警告的信息。与SQL异常类似,警告也是成链的。
e.g.获取所有的警告
    SQLWarning w = stmt.getWaring();
    while(w!=null){
    do something with w
    w = w.getNextWarning();
当数据从数据库中读出并意外被截断时,SQLWarning的DataTruncation子类将会被当做异常抛出。

4.3 一个读取SQL指令,并执行的DEMO
该DEMO操作步骤
(1)根据database.properties中属性信息创建Connection
(2)使用SQL命令打开文件,如果未提供任何文件名,则在控制台中提示用户输入命令。
(3)使用通用的execute执行sql命令,如果返回true,说明产生结果集。每个SQL文件均在最后执行一个SELECT *语句,这样可以看到是否插入数据。
(4)如果产生结果集则打印结果集。
(5)如果运行中出现SQL异常,则打印这个异常以及所有可能包含在其中的与其链接在一起的相关异常。
(6)关闭数据库连接。

 

package jdbc.readsql;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.Scanner;

public class ExecSQL {
	public static void main(String[] args) {
		try {
			Scanner in;
			if (args.length == 0) {
				in = new Scanner(System.in);
			} else {
				in = new Scanner(new File(args[0]));
			}

			Connection conn = getConnection();
			try {
				Statement stat = conn.createStatement();
				while (true) {
					if (args.length == 0) {
						System.out.println("Enter command or exit to exit");
						if (!in.hasNext()) {
							return;
						}
						String line = in.nextLine();
						if ("exit".equalsIgnoreCase(line)) {
							return;
						}
						if (line.trim().endsWith(";")) {
							line = line.trim();
							line = line.substring(0, line.length() - 1);
						}
						try {
							boolean hasResultSet = stat.execute(line);
							if (hasResultSet) {
								showResultSet(stat);
							}
						} catch (SQLException e) {
							for (Throwable t : e) {
								t.printStackTrace();
							}
						}

					}
				}
			} finally {
				conn.close();
			}

		} catch (SQLException se) {
			se.printStackTrace();
		} catch (IOException ie) {
			ie.printStackTrace();
		}
	}

	private static Connection getConnection() throws IOException, SQLException {
		Properties param = new Properties();
		FileInputStream in = new FileInputStream(System.getProperty("user.dir")
				+ "/bin/database.properties");
		param.load(in);
		in.close();

		String drivers = param.getProperty("jdbc.drivers");
		if (drivers != null && !"".equals(drivers)) {
			System.setProperty("jdbc.drivers", drivers);
		}
		// Class.forName(drivers);
		String url = param.getProperty("jdbc.url");
		String username = param.getProperty("jdbc.username");
		String password = param.getProperty("jdbc.password");

		return DriverManager.getConnection(url, username, password);
	}

	private static void showResultSet(Statement stat) throws SQLException {
		ResultSet result = stat.getResultSet();
		ResultSetMetaData metaData = result.getMetaData();
		int columnCount = metaData.getColumnCount();
		
		for(int i=1;i<=columnCount;i++){
			if(i>1){
				System.out.print(",");
				System.out.print(metaData.getColumnLabel(i));
			}
		}
		
		System.out.println();
		
		while(result.next()){
			for(int i=1;i<=columnCount;i++){
				if(i>1){
					System.out.print(",");
					System.out.print(result.getString(i));
				}
			}
			System.out.println();
		}
		
		result.close();
	}
}
 

 

分享到:
评论

相关推荐

    mybatis直接执行sql语句后续之一

    这篇博客“mybatis直接执行sql语句后续之一”可能探讨了如何在MyBatis中高效且有效地执行SQL操作。下面我们将深入探讨MyBatis的SQL执行机制及相关知识点。 首先,MyBatis的核心组件是SqlSessionFactory,它是创建...

    存储过程中怎么动态执行sql语句

    ### 动态执行SQL语句在Oracle中的应用 #### 标题解读 “存储过程中怎么动态执行SQL语句”这一标题表明文章将介绍如何在Oracle数据库的存储过程中编写能够动态执行的SQL语句。动态SQL是指在运行时才能确定其具体内容...

    hibernate执行原生sql语句

    "hibernate执行原生sql语句" Hibernate 是一种流行的 ORM(Object-Relational Mapping)框架,用于将 Java 对象映射到关系数据库中。然而,在一些情况下,我们需要直接执行原生 SQL 语句,而不是使用 Hibernate 的...

    oracle监听执行sql语句

    ### Oracle监听执行SQL语句详解 #### 一、Oracle监听执行概述 在Oracle数据库管理与维护过程中,有时候我们需要了解应用程序正在执行哪些SQL语句,这不仅有助于性能优化,还可以帮助我们诊断潜在的问题。通过监听...

    java定时执行sql语句

    通过配置数据库连接信息和要执行的sql语句,可实现定时执行多个sql语句。 所要执行的语句只能是写死的,可支持sqlserver mysql oracle。 配置说明: config/sys.properties 中指定数据库类型及连接信息,执行间隔...

    Mybatis执行SQL语句的方式

    Mybatis 执行 SQL 语句的方式 Mybatis 是一个基于 Java 的持久层框架,它提供了多种方式来执行 SQL 语句。在本文中,我们将介绍三种执行 SQL 语句的方式:通过 Mapper 接口、通过 XML 配置文件、通过 SqlSession ...

    java执行SQL语句实现查询的通用方法详解

    "java执行SQL语句实现查询的通用方法详解" 本文主要介绍了java执行SQL语句实现查询的通用方法详解,具有一定借鉴价值,需要的朋友可以参考下。 一、Java执行SQL语句实现查询的通用方法详解 在Java中执行SQL语句...

    oracle利用批处理文件执行SQL语句,bat连接oracle数据库并执行语句

    批处理文件(如.bat文件)在Windows环境中是一种高效的方式,可以自动化执行一系列命令,包括连接数据库和执行SQL语句。在这个场景中,我们可以利用批处理文件来简化Oracle数据库的操作,如删除用户、创建用户、创建...

    解决python 执行sql语句时所传参数含有单引号的问题

    在Python编程中,当我们需要执行SQL语句时,有时会遇到参数中包含单引号(')的情况,这可能导致SQL语法错误。在描述的问题中,作者在尝试插入数据到`teacher`表时遇到了编程错误,因为`t_info`字段的值`result2`...

    SQL Server 2005 定时执行SQL语句的方法

    SQL SERVER 2005有定时任务,你可以启动一下。不过要想更加直观的控制,直接写一个程序,定时执行你的存储过程...“步骤” — 设置步骤名称 — “类型”T-SQL — 选择数据库 — “命令”输入SQL语句 “计划” — “新建

    BAT文件执行SQL语句

    在IT行业中,有时候我们需要在没有图形用户界面的环境中执行SQL语句,比如在服务器上进行自动化操作。这时,我们可以利用批处理(BAT)文件来实现。"BAT文件执行SQL语句"这一主题就是关于如何通过编写简单的批处理...

    oracle 查看当前会话执行的sql语句

    ### Oracle 查看当前会话执行的SQL语句 在Oracle数据库管理中,有时我们需要了解某个特定会话(Session)正在执行哪些SQL语句。这在性能调优、问题诊断等场景下尤为重要。以下将详细介绍如何通过不同的方法来查看...

    连接sqlserver数据库,批量执行sql语句

    在本案例中,我们关注的是使用VC++和MFC(Microsoft Foundation Classes)库连接到SQL Server数据库并批量执行SQL语句的过程。下面将详细介绍这个过程涉及的关键知识点。 首先,`VC++`是微软开发的一款集成开发环境...

    如何获得PreparedStatement最终执行的sql语句

    这篇博客可能是探讨如何在实际运行中获取`PreparedStatement`最终执行的SQL语句,这对于调试和分析数据库操作非常有帮助。 在Java中,`PreparedStatement`对象通常会接收参数占位符(如`?`),然后在执行前填充具体...

    批处理执行sql语句

    在这个“批处理执行sql语句”示例中,我们可以深入理解批处理的运用。 首先,`升级数据库批处理.bat` 是一个批处理文件,通常扩展名为 .bat 的文件是Windows操作系统中的批处理脚本,用于执行一系列命令。在这个...

    Web页面执行SQL语句.rar

    【标题】"Web页面执行SQL语句.rar" 涉及的关键知识点主要集中在Web开发、数据库管理和.NET框架的使用上。这个压缩包文件提供了一种通过Web界面与数据库交互的方法,使得用户可以在网页上直接执行SQL语句进行数据操作...

    SQL 执行超长语句

    本文将围绕“SQL执行超长语句”这一主题进行深入探讨,包括超长语句可能出现的原因、如何编写更加高效合理的超长SQL语句以及如何优化执行性能等方面。 #### 一、超长SQL语句的定义与常见场景 ##### 定义 超长SQL...

    access 一次执行多条sql语句

    4. **执行SQL语句**: 使用`OleDbCommand`对象设置SQL语句并执行。在这个例子中,第一条SQL语句是更新账户登录次数,第二条SQL语句是调用存储过程来增加软件的日志数量。 5. **提交或回滚事务**: 如果没有异常发生,...

    NC后台sql语句执行的方式

    在`Private`包下,可以使用`BaseDAO`类来执行SQL语句。这种方式主要适用于业务逻辑较为复杂的场景,需要从数据库中获取大量数据的情况。 **具体步骤:** 1. **创建BaseDAO实例:** ```java BaseDAO baseDAO = ...

Global site tag (gtag.js) - Google Analytics