如何直接在浏览器内运行SQL命令
本文示范了如何用一个Java Servlet、一个JSP页面和一个静态Java类构造出一个SQL网关应用。利用这个应用,你可以直接在浏览器内执行SQL命令,浏览器将把SQL命令提交给远程服务器上的数据库系统,然后返回结果。
如果你正在使用ISP(Internet Service Provider)提供的数据库,可能已经熟悉SQL网关应用的概念了。有的ISP会提供一个操作数据库的HTML页面,就象本文提供的网关应用一样。如果ISP没有提供这样的界面,你可以把本文的程序上载到服务器,以后要访问ISP服务器上的数据库就很方便了。
SQL网关应用不仅可以用于开发过程,而且还可以直接提供给比较熟悉系统的最终用户使用。当然,允许最终用户直接在数据库上运行SQL命令会带来一些安全隐患,应当慎重考虑。
本文要求读者具备一定的Java、Servlet、JSP和数据库的基础知识,如果要运行本文的程序,还要有一个Servlet/JSP服务器和数据库服务器。在下面的说明中,我们要使用的是Tomcat 4.0和MySQL,但它应该也能在其他JSP/Servlet容器中运行;如果你要改用MySQL之外的其他数据库,只要提供一个适当的驱动程序,然后修改数据库连接字符串就可以了。
一、用户界面
图1就是本文SQL网关的用户界面。在这个界面中,SQL网关已经执行了一条SQL命令并返回了结果。
图1:SQL网关的用户界面
从图1可以看出,页面底部的一条信息显示出最近执行的SQL命令影响的行数。如果SQL命令是一个SELECT语句,当SELECT语句执行成功,页面底部将用HTML表格显示出查询结果,如图二所示。
图2:HTML表格显示出查询结果集
当然,如果SQL命令执行失败,SQL网关将返回异常信息。
二、设计JSP页面
在JSP页面中,我们首先放入一个Scriptlet,它的功能是从session对象提取两个属性:
第一个属性sqlStatement 表示SQL命令字符串,第二个属性message 是包含结果信息的字符串。如果这两个属性的值是null,则表示它们尚未被设置,我们把sqlStatement和message变量设置成空字符串。
JSP页面还有一个HTML表单,HTML表单包含一个文本区域(TEXTAREA)和一个“执行”按钮。
表单中的文本区域用来输入SQL命令。我们将sqlStatement变量的值作为文本区域的默认内容,文本区域的大小是宽60字符、高8行。当JSP页面第一次运行时,这个文本区域的内容为空。如果用户点击文本区域下面的“执行”按钮,JSP页面把表单内容提交给SQLGatewayServlet(稍后再详细介绍)。
JSP页面底部的表格显示出message字符串的内容。如前所述,message的内容是运行SQL命令的结果。
SQL命令执行结果:
三、编写Servlet
SQLGatewayServlet首先导入java.sql包以便使用JDBC类。另外,它还要声明一个Connection对象,以便Servlet之内的所有方法都可以使用数据库连接。
package test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
public class SQLGatewayServlet extends HttpServlet{
private Connection connection;
当Servlet引擎开始运行这个Servlet,Servlet的init方法就打开一个数据库连接:
public void init() throws ServletException{
try{
Class.forName("org.gjt.mm.mysql.Driver");
String dbURL = "jdbc:mysql://localhost/murach";
String username = "root";
String password = "";
connection = DriverManager.getConnection
(dbURL, username, password);
}
catch(ClassNotFoundException e){
System.out.println("找不到数据库驱动程序.");
}
catch(SQLException e){
System.out.println("不能打开数据库连接: "
+ e.getMessage());
}
}
在这个例子中,Servlet利用一个MysQL数据库的驱动程序打开murach数据库的连接,数据库和Servlet运行在同一个服务器上。此外,Servlet使用MySQL的默认用户名字root,密码为空。不过,你可以修改这里的代码,只要有适当的驱动程序,就可以让Servlet连接到任何服务器上的任何数据库(有关MySQL数据库的更多信息,请参见www.mysql.com)。
Servlet引擎关闭Servlet之前,调用destroy方法关闭数据库连接,释放连接资源:
public void destroy() {
try{
connection.close();
}
catch(SQLException e){
System.out.println("不能关闭数据库连接: " + e.getMessage());
}
}
前面介绍的JSP页面要调用Servlet的doPost方法,doPost方法调用doGet方法:
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException{
doGet(request, response);
}
在doGet方法之中,第一个语句首先获取用户在JSP页面中输入的SQL命令,第二个语句声明message变量:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException{
String sqlStatement = request.getParameter("sqlStatement");
String message = "";
然后,在try块之内,第一个语句利用Connection对象创建Statement对象,接下来的两个语句利用String对象的trim方法和substring方法返回用户输入的SQL命令的前六个字符。
try{
Statement statement = connection.createStatement();
sqlStatement = sqlStatement.trim();
String sqlType = sqlStatement.substring(0, 6);
如果SQL命令的前六个字符是“select”,则利用Statement的executeQuery方法执行SQL语句,获得一个ResultSet对象,把这个对象传递给SQLUtil类(稍后详细说明)的getHtmlRows方法,getHtmlRows方法将把记录集中的记录格式化成HTML表格并返回。
if (sqlType.equalsIgnoreCase("select")){
ResultSet resultSet = statement.executeQuery(sqlStatement);
// 构造一个String,其中包含HTML表格形式的结果集数据
message = SQLUtil.getHtmlRows(resultSet);
}
如果SQL语句的前六个字符不是“select”,则我们调用Statement对象的executeUpdate方法,executeUpdate方法返回当前操作影响的行数——如果这个数字是0,则该SQL命令是一个DDL命令,例如DROP TABLE或CREATE TABLE等;否则,则表明SQL命令可能是DML命令,如INSERT、UPDATE或DELETE命令。无论是哪一种SQL命令,我们都把message变量设置成相应的消息。
else
{
int i = statement.executeUpdate(sqlStatement);
if (i == 0) // 这是一个DDL命令
message =
"" +
"命令执行成功." +
"";
else // 这是一个INSERT、UPDATE或DELETE命令
message =
"" +
"SQL命令执行成功。
" +
"已更改" + i + " 行。" +
"";
}
statement.close();
}
如果try块里面的任何一个语句抛出一个SQLException,catch块就设置message变量,使其包含有关该SQLException的信息。例如,如果在表单中输入的SQL命令语法错误,下面设置的message变量值将帮助你排解错误。
catch(SQLException e){
message = "执行SQL命令时遇到错误:
"
+ e.getMessage() + "";
}
在catch块之后,接下来的三个语句获得session对象,把sqlStatement和message变量设置为session的属性:
HttpSession session = request.getSession();
session.setAttribute("message", message);
session.setAttribute("sqlStatement", sqlStatement);
接下来,最后两个语句创建一个RequestDispatcher,并转发request和response对象给前文介绍的JSP页面:
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(
"/sql/sql_gateway.jsp");
dispatcher.forward(request, response);
四、编写工具类
下面来看看工具类SQLUtil的代码:
package test;
import java.sql.*;
public class SQLUtil{
SQLUtil类包含一个getHtmlRows静态方法,前面的Servlet正是通过调用该方法将结果集格式化成HTML表格。getHtmlRows的输入参数是一个ResultSet对象,其返回值是一个String对象,这个String对象的内容是记录集的所有列表题和行的HTML代码。为了构造出这样一个String对象,getHtmlRows声明了一个名为htmlRows的StringBuffer对象,然后在方法执行过程中向这个StringBuffer对象追加数据。在getHtmlRows方法的末尾,我们用toString方法将StringBuffer的内容转换成String,最后将这个String返回给Servlet:
public static synchronized String getHtmlRows(ResultSet results)
throws SQLException{
StringBuffer htmlRows = new StringBuffer();
ResultSetMetaData metaData = results.getMetaData();
int columnCount = metaData.getColumnCount();
// 将记录集中列的名称作为HTML表格列的标题
htmlRows.append("");
for (int i = 1; i
绛旓細鍦ㄤ笅鏂归夐」 2銆丼QL Server Browser鈥旀湇鍔(鍋滄鏃跺彧鏈満璁块棶)3銆佺▼搴忊擬icrosoft SQL Server 2005鈥旈厤缃伐鍏封擲QL Server Configuration Manager鈥旂綉缁滆繛鎺ュ崗璁旈夋嫨瀹炰緥瀵瑰簲鍗忚鈥斿惎鐢(shard memory銆丯amed Pipes銆乀CP\IP)娉:SQL Server 娴忚鍣绋嬪簭浠ユ湇鍔$殑褰㈠紡鍦ㄦ湇鍔鍣ㄤ笂杩愯銆SQL Server 娴忚鍣ㄤ睛鍚 ...
绛旓細1銆佹墦寮chrome娴忚鍣锛屽啀鎵撳紑 寮鍙戣呭伐鍏凤紙鎸塅12锛屾垨鑰呴紶鏍囧彸鍑->瀹℃煡鍏冪礌 涔熻兘鎵撳紑锛夛紝2銆佽繖灏辨槸浼犺涓殑寮鍙戣呭伐鍏凤紝鏌ョ湅dom缁撴瀯 3銆佽祫婧愮殑鏌ョ湅锛坈oookie锛宧tml5鏈湴鏁版嵁搴撶瓑锛4銆佹ā鎷熸墜鏈虹幆澧冿紝瀵圭Щ鍔ㄥ紑鍙戣呴潪甯告湁鐢
绛旓細鐏嫄娴忚鍣鐨勯檮鍔犵粍浠禨QL Inject Me锛屼綔涓烘澹玏TF鎻掍欢闆嗗悎涓殑涓閮ㄥ垎锛屽湪妫娴嬩綘姝e湪娴忚涓殑搴旂敤绋嬪簭鏂归潰闈炲父瀹炵敤銆傞氳繃瀹冧綘鍙互妫娴嬪叏閮ㄦ灦鏋勬垨閫変腑鐨勫弬鏁版墍鑳藉彈鍒扮殑鍚勭鏀诲嚮鏂瑰紡锛屾垨鑰呮槸妫娴嬭宸ュ叿涓璁剧殑涔濈甯歌鏀诲嚮绫诲瀷銆傚綋鍦ㄥ伐鍏蜂腑閫夊畾鏀诲嚮鏂瑰紡鍚庯紝鍐鎵цSQL Inject Me锛屽垯璇ュ伐鍏风殑杩愯鐘跺喌鍗充細濡傚浘涓...
绛旓細ActiveX鏁版嵁瀵硅薄锛圓DO锛堿DO锛圓ctiveX Data Object锛,鏄竴缁勪紭鍖栫殑璁块棶鏁版嵁搴撶殑涓撶敤瀵硅薄闆嗭紝瀹冧负ASP鎻愪緵浜嗗畬鏁寸殑绔欑偣鏁版嵁搴撹В鍐虫柟妗堬紝瀹冧綔鐢ㄥ湪鏈嶅姟鍣ㄧ锛屾彁渚涘惈鏈夋暟鎹簱淇℃伅鐨勪富椤靛唴瀹癸紝閫氳繃鎵цSQL鍛戒护锛岃鐢ㄦ埛鍦ㄦ祻瑙堝櫒鐢婚潰涓緭鍏ワ紝鏇存柊鍜屽垹闄ょ珯鐐规暟鎹簱鐨勪俊鎭侫DO鐨勪富瑕佷紭鐐规槸鏄撶敤銆侀珮閫熴佸崰鐢ㄥ唴瀛樺拰纾佺洏...
绛旓細1.鍚姩Websphere6.0鏈嶅姟 2.鎵撳紑IE娴忚鍣锛屽湪鍦板潃鏍忎腑杈撳叆锛歭ocalhost:9060/ibm/console/锛岀櫥闄哤ebsphere6.0绠$悊鎺у埗鍙 3.鍦ㄥ鑸爮宸︿晶閫夋嫨锛氱幆澧-銆塛ebsphere鍙橀噺 鎵惧埌ORACLE_JDBC_DRIVER_PATH锛岃緭鍏RACLE_JDBC_DRIVER_PATH鐨勫硷紝鎸囧畾ORACLE鏁版嵁搴撻┍鍔╦ar鍖呯殑浣嶇疆锛岀‘瀹氾紝淇濆瓨銆4.鍦ㄥ鑸爮宸︿晶閫夋嫨锛...
绛旓細鍙互鐨勫晩.鍙 Web 鏈嶅姟鍣ㄥ彲浠 璁块棶 SQL Server銆備綘瀹㈡埛绔彧瑕佹湁涓涓狪E娴忚鍣灏卞彲浠ヤ簡銆
绛旓細閫氳繃閰嶇疆绠$悊鍣紝浣犲彲浠ユ洿鏀SQL Server瀹炰緥鐨勭綉缁滈厤缃佹湇鍔″笎鎴枫佹湇鍔″櫒绾у埆璁剧疆绛夈傛澶栵紝閰嶇疆绠$悊鍣ㄨ繕鍙互鍗忓姪鐢ㄦ埛閰嶇疆鍜岀鐞哠QL Server鐨勫鎴风鍒悕銆丼QL Server娴忚鍣鏈嶅姟銆丼QL Server閿欒鏃ュ織绛夈傛讳箣锛孲QL Server閰嶇疆绠$悊鍣ㄦ槸SQL Server涓涓涓潪甯搁噸瑕佺殑宸ュ叿锛屽鏋滀綘闇瑕佺鐞哠QL Server瀹炰緥鎴栫粍浠讹紝浣...
绛旓細鍙互鐨勩傜浉鍏崇煡璇嗙偣寤朵几锛1銆佲滅綉椤 + 鏁版嵁搴撯濇槸鍏稿瀷鐨勪笁灞傛瀯鏋躲傚嵆鈥滄暟鎹簱鈥濅负鍚庡彴灞傦紝鈥滅綉椤垫湇鍔″櫒鈥濅粠鍚庡彴灞傚彇鏁版嵁涓轰腑闂村眰锛岀敤鎴风數鑴戜笂鐨勫鎴风搴旂敤姣斿鈥娴忚鍣鈥濊В閲婂拰灞曠幇浠庣綉椤垫湇鍔鍣ㄤ笂鐨勪唬鐮佸拰鏁版嵁涓虹敤鎴峰眰銆2銆亀eb缃戦〉鏈嶅姟鍣ㄥ彲浠ュ悓鏃惰仈鎺ュ涓暟鎹簱銆佹暟鎹簮銆傛暟鎹簱鏈嶅姟鍣ㄧ殑鍦板潃鍙互鏈夊涓...
绛旓細灏婃暚鐨勭敤鎴凤紝鎮ㄥソ锛佸緢楂樺叴涓烘偍绛旂枒銆傝繖瑕佺湅鎮ㄩ〉闈SQL鎵ц鏃堕噰鐢ㄧ殑鏁版嵁浼犻掓柟寮忎簡锛岀伀鐙愬洜涓哄畨鍏ㄧ骇鍒瀹氱殑缂樻晠锛屾湁鍙兘浼氬涓浜涙晱鎰熷瓧绗﹁繘琛岃浆璇戯紝杩欐牱浣跨敤娉ㄥ叆鏂瑰紡鎵ц鐨凷QL鍗充細琚浆鎹㈡垚鏅氳鍙ヨ屾棤娉曟墽琛屻傚笇鏈涙垜鐨勫洖绛斿鎮ㄦ湁鎵甯姪锛屽鏈夌枒闂紝娆㈣繋缁х画鍜ㄨ鎴戜滑銆
绛旓細鎵撳紑DOS鍛戒护妗嗐傜偣鍑汇愬紑濮嬨--銆杩愯銆--杈撳叆锛欳MD 鍛戒护銆2 鍦ㄥ懡浠ゆ杈撳叆瀛楃鍛戒护銆傛垜浠垚鍔熸墦寮鍛戒护妗嗗悗锛屽湪鍛戒护妗閲杈撳叆锛歯et start mssqlserver 鍚姩Sql鏈嶅姟鍣紝鍚岀悊net stop mssqlserver 鏄仠姝㈡湇鍔″櫒銆3 鎭枩浣狅紝鎴愬姛寮鍚SQL鏈嶅姟鍣ㄣ4 妫楠屾槸鍚﹀紑鍚湇鍔°傚畨瑁呬笂闈㈡柟娉曚竴鎴栬呬簩閮藉彲浠ワ紝涓嬮潰鏄垜...