﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-灵魂-放水-随笔分类-数据库</title><link>http://www.blogjava.net/zqli/category/16574.html</link><description>为学日益，为道日损。</description><language>zh-cn</language><lastBuildDate>Mon, 14 Sep 2009 03:40:51 GMT</lastBuildDate><pubDate>Mon, 14 Sep 2009 03:40:51 GMT</pubDate><ttl>60</ttl><item><title>【转】MS SQL数据库日志的压缩方法</title><link>http://www.blogjava.net/zqli/archive/2009/09/14/294979.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 14 Sep 2009 02:22:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2009/09/14/294979.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/294979.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2009/09/14/294979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/294979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/294979.html</trackback:ping><description><![CDATA[<p>MS SQL性能是很不错的，但是数据库用了一段时间之后，数据库却变得很大，实际的数据量不大。一般都是数据库日志引起的！数据库日志的增长可以达到好几百M。</p>
<p>网上的MSSQL虚拟主机价格也贵，要想不让数据库超容，只好压缩下数据库日志，或者删除数据库日志。<br />
下面我给大家介绍一个方法</p>
<p>1、打开企业管理器<br />
2、打开要处理的数据库<br />
3、点击菜单&gt;工具&gt;SQL查询分析器<br />
4、在输入窗口里面输入:<br />
DUMP TRANSACTION [数据库名] WITH NO_LOG<br />
BACKUP LOG [数据库名] WITH NO_LOG<br />
DBCC SHRINKDATABASE([数据库名])<br />
点击执行！这样子数据库就操作成功了。</p>
<p>程序里面的方法：<br />
压缩数据库日志<br />
--1.清空日志<br />
exec('DUMP TRANSACTION [' @dbname '] WITH NO_LOG') <br />
--2.截断事务日志：<br />
exec('BACKUP LOG [' @dbname '] WITH NO_LOG')<br />
--3.收缩数据库文件(如果不压缩,数据库的文件不会减小<br />
exec('DBCC SHRINKDATABASE([' @dbname '])')</p>
<img src ="http://www.blogjava.net/zqli/aggbug/294979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2009-09-14 10:22 <a href="http://www.blogjava.net/zqli/archive/2009/09/14/294979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]在虚拟主机环境下备份数据库并且导出到EXCEL  </title><link>http://www.blogjava.net/zqli/archive/2008/07/02/212127.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Wed, 02 Jul 2008 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2008/07/02/212127.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/212127.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2008/07/02/212127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/212127.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/212127.html</trackback:ping><description><![CDATA[<span id="ArticleContent1_ArticleContent1_lblContent">&nbsp;
<p>在虚拟主机的环境下，因为没有管理员权限，只有数据库使用权限，定时备份SQL数据是</p>
<p>个比较麻烦的问题。解决思路如下：（仅对SQL2000有效)<br />
1. 利用T-SQL备份数据库到指定目录，文件名根据日期指定。<br />
2. 利用Resin的定时功能，定时执行备份。<br />
3. 用户定时下载备份并且删除过期备份。</p>
<p>导出全部数据到Excel也比较实用。下面提供的方法可以导出库中的全部表，也可以指定</p>
<p>几个表导出。注意：<br />
1. 因为是导出全部数据，在数据比较多的情况下慎用。<br />
2. 理论上应该适用各种JDBC数据库，仅对SQL2000测试过<br />
3. 对于B/S下载，建议不要在服务器上生成文件，以免造成垃圾文件。直接从HTTP的Response中取得OutputStream进行输出。<br />
4. Excel操作的API请到这里下载：<a href="http://www.andykhan.com/jexcelapi/">http://www.andykhan.com/jexcelapi/</a><br />
</p>
<p>package steeven;<br />
import jxl.write.*;<br />
import java.util.*;<br />
import java.sql.Statement;<br />
import java.sql.ResultSet;<br />
import java.sql.Types;<br />
import java.sql.Connection;<br />
import java.sql.PreparedStatement;<br />
import java.sql.SQLException;<br />
import java.text.DateFormat;<br />
import java.io.*;</p>
<p>/**<br />
&nbsp;* &lt;p&gt;Title: 数据库备份&lt;/p&gt;<br />
&nbsp;* &lt;p&gt;Description: 在Java中备份数据库&lt;/p&gt;<br />
&nbsp;* @author steeven<br />
&nbsp;* @version 1.0<br />
&nbsp;*/<br />
public class DBackup{<br />
&nbsp;&nbsp;&nbsp; Context ctx ;<br />
&nbsp;&nbsp;&nbsp; public DBackup(Context ctx) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ctx = ctx;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 备份SQL2000数据库到文件，整个数据库备份<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 文件名后面将追加备份年月日。例如：c:\dbBackup\mydb031109<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param file 导出的文件名全路径。例如："c:\\dbBackup\\mydb"<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void backup(String dbName, String file)throws SQLException{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sql = "BACKUP DATABASE ["+dbName+"] TO DISK = N'";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql += file + new SimpleDateFormat("yyMMdd").format(new Date());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql += "' WITH&nbsp; NOINIT ,&nbsp; NOUNLOAD ,&nbsp; NAME = N'lvdong',&nbsp; NOSKIP ,&nbsp; </p>
<p>STATS = 10,&nbsp; NOFORMAT";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Statement stmt = ctx.getConnection().createStatement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.executeUpdate(sql);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 导出整个数据库到Excel<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param conn 数据库连接<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param out 输出Stream<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void db2Excel(Connection conn,OutputStream out)throws </p>
<p>Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db2Excel(conn,out,getTables(conn));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 导出数据库中指定的表名到Excel<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param conn 数据库连接<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param out 输出Stream<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param tables 表名<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @throws Exception<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void db2Excel(Connection conn,OutputStream out,List </p>
<p>tables)throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WritableWorkbook wb = jxl.Workbook.createWorkbook(out);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; tables.size(); i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WritableSheet sheet = wb.createSheet(tables.get(i).toString(),i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeSheet(sheet,tables.get(i).toString(),conn);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wb.write();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wb.close();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 导出表数据到Excel的sheet<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void writeSheet(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WritableSheet sheet,String table,Connection conn)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //取得所有表数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sql = "select * from "+DB.ESC1+table+DB.ESC2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSet rs = conn.createStatement().executeQuery(sql);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据ResultSet的MetaData取得表头，列数，列宽<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.ResultSetMetaData meta = rs.getMetaData();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n = meta.getColumnCount();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int row = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WritableCellFormat fmt = new WritableCellFormat();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fmt.setBackground(jxl.format.Colour.YELLOW);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; n; i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //导出表头<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sheet.addCell(new Label(i, row, meta.getColumnLabel(i + 1),fmt));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设定列宽<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sheet.setColumnView(i,meta.getColumnDisplaySize(i+1));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(rs.next()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; n; i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据列的类型决定Excel中对应的Cell类型，缺省为文本。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WritableCell cell ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(meta.getColumnType(i+1)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.BIT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.BIGINT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.BOOLEAN:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.DECIMAL:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.FLOAT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.INTEGER:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.NUMERIC:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.REAL:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.SMALLINT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.TINYINT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double val = rs.getDouble(i+1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs.wasNull()) cell = new jxl.write.Blank(i,row);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cell = new jxl.write.Number(i, row, val);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.DATE:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.TIME:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types.TIMESTAMP:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date = rs.getDate(i + 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs.wasNull()) cell = new jxl.write.Blank(i,row);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else cell = new jxl.write.DateTime(i, row, date);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cell = new Label(i, row, rs.getString(i + 1));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } //end of switch<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sheet.addCell(cell);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//end of for each column<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//end of while(rs.next())<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 从Connection的MetaData取得所有数据表的名称<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static List getTables(Connection conn)throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSet rs = conn.getMetaData().getTables(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,null,null,new String[]{"Table"});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list = new ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(rs.next())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.add(rs.getString(3));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return list;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection conn = DB.getConn();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputStream out = new FileOutputStream("c:\\test.xls");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db2Excel(conn,out);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.close();<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
</span>------------------------------------<br />
<a class="singleposttitle" id="AjaxHolder_ctl01_TitleUrl" href="http://www.cnblogs.com/wildfish/archive/2005/07/12/191136.html">关于虚拟主机的数据库如何备份</a> <br />
<div class="postbody">1.最早的时候用sqlserver的备份功能，在本地可以实现，用程序调用就可以了。后来发不到虚拟机的时候才发现，虚拟机把大部分的存储过程都给关闭了。只好考虑用别的方法。<br />
2.后来，我就用自己写的存储过程来备份数据库，当时是虚拟主机和数据库在同一台机器上，ok没有问题了。<br />
3.现在由于速度问题，虚拟主机必须移到香港，所以第二种方法就没法子实现了。<br />
想来想去，嘿嘿，利用本地的sqlserver。<br />
新建一个包，然后点&#8220;复制sqlserver 对象任务&#8221;，然后输入源/目的/复制的信息。一般如果是数据量比较少的话，我们可以用替换现有数据，也是最正常的情况，我觉得这个比较可行，如果是追加的话，就会丢失修改的信息。然后，虚拟主机的sqlserver一般需要用户名密码，那么我们就在自己本地的sqlserver的安全里面也增加相同用户名及密码。这样我们执行的时候就不会出问题了。<br />
然后我们保存这个包，确信sqlagent服务已经启动。如果启动了，那么我们在数据转换服务-本地包，然后右击我们刚才创建的包，选择调度。设定一个时间段，我一般选择12点，那时候大家都去吃饭了~~</div>
<img src ="http://www.blogjava.net/zqli/aggbug/212127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2008-07-02 16:12 <a href="http://www.blogjava.net/zqli/archive/2008/07/02/212127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQLServer几种连接字符串服务器名的区别</title><link>http://www.blogjava.net/zqli/archive/2007/07/03/127934.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Tue, 03 Jul 2007 11:12:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/07/03/127934.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/127934.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/07/03/127934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/127934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/127934.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 在SQL 里: Server=(local); 用的是named pipes 通讯. Server=localhost; 用的是从 port 1434 udp协商来的端口,缺省是1433的口上进行TCP通讯. 我听人说过,Server=localhost在XP Service Pack 2 以前还工作,到了XP SP2就不工作了. MS建议用server=计算机名,不用Server=localhost 。
<img src ="http://www.blogjava.net/zqli/aggbug/127934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-07-03 19:12 <a href="http://www.blogjava.net/zqli/archive/2007/07/03/127934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于一个不大常用的SQL数据类型－UNIQUEIDENTIFIER   </title><link>http://www.blogjava.net/zqli/archive/2007/01/30/96653.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Tue, 30 Jan 2007 01:01:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/30/96653.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/96653.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/30/96653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/96653.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/96653.html</trackback:ping><description><![CDATA[当你正在处理被多个站点（像在跨国公司条件下）使用的大数据库时，你也许会遇到保证表格对象唯一性这样的棘手问题。在这种情形下，可能只能靠   UNIQUEIDENTIFIER来解决。UNIQUEIDENTIFIER是一个保存全局唯一标识符的GUID数据类型。GUID是一个保证唯一的二进制数，因此几乎没有别的计算机会产生同一个值。   <br />    <br />  GUID的唯一值是由计算机网卡的标识数加上一个CPU时钟产生的唯一数而得到的。网卡制造商至少在下一个100年内能保证网卡的唯一性。   <br />    <br />  UNIQUEIDENTIFIER值不能像IDENTITY属性那样自动产生。要想为你的表格对象产生UNIQUEIDENTIFIER值，你必须指定NEWID函数为column的缺省值。   <br />    <br />  例如，如果你想要创建一个表格列出你的跨国公司的所有子公司的尖端产品的收入，并且你希望指定一个GUID数据类型，那么你可以键入：   <br />    <br />  CREATE   TABLE   NetRevenueTable   <br />    <br />  (UniqueColumn   UNIQUEIDENTIFIER   DEFAULT   NEWID(),   <br />    <br />  Characters   VARCHAR(10))   <br />    <br />  在数据库工具中，你要在数据库图表中或当你正在设计一个表格时做这件事情。为你想唯一确定的column选择Is   RowGUID。缺省情况将是(newid())，它自动产生RowGUID。   <br />    <br />  尽管在许多情况下你必须保证表格对象的唯一性，但是如果你决定使用UNIQUEIDENTIFIER数据类型，请注意以下特性：   <br />    <br />        1.   这些值是长而且难懂的。   <br />        2.   这些值是随机的，不带有对用户有意义的样式。   <br />        3.   这些值在依靠连续增加的值的应用程序中很难使用。   <br />        4.   这些值有16字节，很大，因此用这些钥匙构建索引会更慢。     <br /><br /><br /> 全局唯一标识符 ,. NET中没有对应的数据类型。   这个列的值，数据库系统会自动生成。这个列根本不需要你为它添加数据！只要把其他数据列添完提交他会自动生成数据。<img src ="http://www.blogjava.net/zqli/aggbug/96653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-30 09:01 <a href="http://www.blogjava.net/zqli/archive/2007/01/30/96653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>收集-数据库优化</title><link>http://www.blogjava.net/zqli/archive/2007/01/15/94017.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 15 Jan 2007 11:35:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/15/94017.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/94017.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/15/94017.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/94017.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/94017.html</trackback:ping><description><![CDATA[1   逻辑数据库和表的设计     <br />  　　数据库的逻辑设计、包括表与表之间的关系是优化关系型数据库性能的核心。一个好的逻辑数据库设计可以为优化数据库和应用程序打下良好的基础。     <br />    <br />  　　标准化的数据库逻辑设计包括用多的、有相互关系的窄表来代替很多列的长数据表。下面是一些使用标准化表的一些好处。     <br />    <br />  A:由于表窄，因此可以使排序和建立索引更为迅速     <br />  B:由于多表，所以多镞的索引成为可能     <br />  C:更窄更紧凑的索引     <br />  D:每个表中可以有少一些的索引，因此可以提高insert   update   delete等的速度，因为这些操作在索引多的情况下会对系统性能产生很大的影响     <br />  E:更少的空值和更少的多余值，增加了数据库的紧凑性由于标准化，所以会增加了在获取数据时引用表的数目和其间的连接关系的复杂性。太多的表和复杂的连接关系会降低服务器的性能，因此在这两者之间需要综合考虑。     <br />  　　定义具有相关关系的主键和外来键时应该注意的事项主要是：用于连接多表的主键和参考的键要有相同的数据类型。     <br />    <br />  　　2   索引的设计     <br />  A:尽量避免表扫描     <br />  检查你的查询语句的where子句，因为这是优化器重要关注的地方。包含在where里面的每一列（column)都是可能的侯选索引，为能达到最优的性能，考虑在下面给出的例子：对于在where子句中给出了column1这个列。     <br />  下面的两个条件可以提高索引的优化查询性能！     <br />  第一：在表中的column1列上有一个单索引     <br />  第二：在表中有多索引，但是column1是第一个索引的列     <br />  避免定义多索引而column1是第二个或后面的索引，这样的索引不能优化服务器性能     <br />  例如：下面的例子用了pubs数据库。     <br />  SELECT   au_id,   au_lname,   au_fname   FROM   authors     <br />  WHERE   au_lname   =   ’White’     <br />  按下面几个列上建立的索引将会是对优化器有用的索引     <br />  ?au_lname     <br />  ?au_lname,   au_fname     <br />  而在下面几个列上建立的索引将不会对优化器起到好的作用     <br />  ?au_address     <br />  ?au_fname,   au_lname     <br />  考虑使用窄的索引在一个或两个列上，窄索引比多索引和复合索引更能有效。用窄的索引，在每一页上     <br />  将会有更多的行和更少的索引级别（相对与多索引和复合索引而言），这将推进系统性能。     <br />  对于多列索引，SQL   Server维持一个在所有列的索引上的密度统计（用于联合）和在第一个索引上的     <br />  histogram（柱状图）统计。根据统计结果，如果在复合索引上的第一个索引很少被选择使用，那么优化器对很多查询请求将不会使用索引。     <br />  有用的索引会提高select语句的性能，包括insert,uodate,delete。     <br />  但是，由于改变一个表的内容，将会影响索引。每一个insert,update,delete语句将会使性能下降一些。实验表明，不要在一个单表上用大量的索引，不要在共享的列上（指在多表中用了参考约束）使用重叠的索引。     <br />  在某一列上检查唯一的数据的个数，比较它与表中数据的行数做一个比较。这就是数据的选择性，这比较结果将会帮助你决定是否将某一列作为侯选的索引列，如果需要，建哪一种索引。你可以用下面的查询语句返回某一列的不同值的数目。     <br />  select   count(distinct   cloumn_name)   from   table_name     <br />  假设column_name是一个10000行的表，则看column_name返回值来决定是否应该使用，及应该使用什么索引。     <br />  Unique   values   Index     <br />    <br />  5000   Nonclustered   index     <br />  20   Clustered   index     <br />  3   No   index     <br />    <br />  镞索引和非镞索引的选择     <br />    <br />  &lt;1:&gt;镞索引是行的物理顺序和索引的顺序是一致的。页级，低层等索引的各个级别上都包含实际的数据页。一个表只能是有一个镞索引。由于update,delete语句要求相对多一些的读操作，因此镞索引常常能加速这样的操作。在至少有一个索引的表中，你应该有一个镞索引。     <br />  在下面的几个情况下，你可以考虑用镞索引：     <br />  例如：   某列包括的不同值的个数是有限的（但是不是极少的）     <br />  顾客表的州名列有50个左右的不同州名的缩写值，可以使用镞索引。     <br />  例如：   对返回一定范围内值的列可以使用镞索引，比如用between,&gt;,&gt;=,&lt;,&lt;=等等来对列进行操作的列上。     <br />  select   *   from   sales   where   ord_date   between   ’5/1/93’   and   ’6/1/93’     <br />  例如：   对查询时返回大量结果的列可以使用镞索引。     <br />  SELECT   *   FROM   phonebook   WHERE   last_name   =   ’Smith’     <br />    <br />  当有大量的行正在被插入表中时，要避免在本表一个自然增长（例如，identity列）的列上建立镞索引。如果你建立了镞的索引，那么insert的性能就会大大降低。因为每一个插入的行必须到表的最后，表的最后一个数据页。     <br />  当一个数据正在被插入（这时这个数据页是被锁定的），所有的其他插入行必须等待直到当前的插入已经结束。     <br />  一个索引的叶级页中包括实际的数据页，并且在硬盘上的数据页的次序是跟镞索引的逻辑次序一样的。     <br />    <br />  &lt;2:&gt;一个非镞的索引就是行的物理次序与索引的次序是不同的。一个非镞索引的叶级包含了指向行数据页的指针。     <br />  在一个表中可以有多个非镞索引，你可以在以下几个情况下考虑使用非镞索引。     <br />  在有很多不同值的列上可以考虑使用非镞索引     <br />  例如：一个part_id列在一个part表中     <br />  select   *   from   employee   where   emp_id   =   ’pcm9809f’     <br />  查询语句中用order   by   子句的列上可以考虑使用镞索引     <br />    <br />  3   查询语句的设计     <br />    <br />  SQL   Server优化器通过分析查询语句，自动对查询进行优化并决定最有效的执行方案。优化器分析查询语句来决定那个子句可以被优化，并针对可以被优化查询的子句来选择有用的索引。最后优化器比较所有可能的执行方案并选择最有效的一个方案出来。     <br />  在执行一个查询时，用一个where子句来限制必须处理的行数，除非完全需要，否则应该避免在一个表中无限制地读并处理所有的行。     <br />  例如下面的例子，     <br />  select   qty   from   sales   where   stor_id=7131     <br />  是很有效的比下面这个无限制的查询     <br />  select   qty   from   sales     <br />  避免给客户的最后数据选择返回大量的结果集。允许SQL   Server运行满足它目的的函数限制结果集的大小是更有效的。     <br />  这能减少网络I/O并能提高多用户的相关并发时的应用程序性能。因为优化器关注的焦点就是where子句的查询，以利用有用的索引。在表中的每一个索引都可能成为包括在where子句中的侯选索引。为了最好的性能可以遵照下面的用于一个给定列column1的索引。     <br />  第一：在表中的column1列上有一个单索引     <br />  第二：在表中有多索引，但是column1是第一个索引的列不要在where子句中使用没有column1列索引的查询语句，并避免在where子句用一个多索引的非第一个索引的索引。     <br />  这时多索引是没有用的。     <br />  For   example,   given   a   multicolumn   index   on   the   au_lname,   au_fname   columns   of   the   authors   table   in     <br />  the   pubs   database,     <br />  下面这个query语句利用了au_lname上的索引     <br />  SELECT   au_id,   au_lname,   au_fname   FROM   authors     <br />  WHERE   au_lname   =   ’White’     <br />  AND   au_fname   =   ’Johnson’     <br />  SELECT   au_id,   au_lname,   au_fname   FROM   authors     <br />  WHERE   au_lname   =   ’White’     <br />  下面这个查询没有利用索引，因为他使用了多索引的非第一个索引的索引     <br />  SELECT   au_id,   au_lname,   au_fname   FROM   authors     <br />  WHERE   au_fname   =   ’Johnson’   <br /><img src ="http://www.blogjava.net/zqli/aggbug/94017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-15 19:35 <a href="http://www.blogjava.net/zqli/archive/2007/01/15/94017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]数据库索引</title><link>http://www.blogjava.net/zqli/archive/2007/01/15/94016.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 15 Jan 2007 11:33:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/15/94016.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/94016.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/15/94016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/94016.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/94016.html</trackback:ping><description><![CDATA[用户对数据库最频繁的操作是进行数据查询。一般情况下，数据库在进行查询操作时需要对整个表进行数据搜索。当表中的数据很多时，搜索数据就需要很长的时间，这就造成了服务器的资源浪费。为了提高检索数据的能力，数据库引入了索引机制。本章将介绍索引的概念及其创建与管理。<br /><br /><span class="style2">8.1.1 索引的概念</span><br />索引是一个单独的、物理的数据库结构，它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引是依赖于表建立的，它提供了数据库中编排表中数据的内部方法。一个表的存储是由两部分组成的，一部分用来存放表的数据页面，另一部分存放索引页面。索引就存放在索引页面上，通常，索引页面相对于数据页面来说小得多。当进行数据检索时，系统先搜索索引页面，从中找到所需数据的指针，再直接通过指针从数据页面中读取数据。从某种程度上，可以把数据库看作一本书，把索引看作书的目录，通过目录查找书中的信息，显然较没有目录的书方便、快捷。 <br /><br />索引和关键字及约束有较大的联系。关键字可以分为两类：一种是逻辑关键字，即在 “数据库基础章”节中介绍的；另一种是物理关键字，它用来定义索引的列，也即索引。<br /><br /><span class="style2">8.1.2 索引的结构</span><br />（1） 索引的B-树结构<br />SQL Server 中的索引是以B-树结构来维护的，如图8-1 所示。B-树是一个多层次、自维护的结构。一个B-树包括一个顶层，称为根节点（Root Node）；0 到多个中间层（Intermediate）；一个底层（Level 0），底层中包括若干叶子节点（Leaf Node）。在图 8-1 中，每个方框代表一个索引页，索引列的宽度越大，B-树的深度越深，即层次越多，<br /><br /><img height="219" src="http://edu.cnzz.cn/newsfile/050606154882500.gif" width="560" /><br /><br />读取记录所要访问的索引页就越多。也就是说，数据查询的性能将随索引列层次数目的增加而降低。 图8-1 索引的B-树结构<br />在SQL Server 的数据库中按存储结构的不同将索引分为两类：簇索引（Clustered Index）和非簇索引（Nonclustered Index）。 <br /><br />（2） 簇索引簇索引对表的物理数据页中的数据按列进行排序，然后再重新存储到磁盘上，即簇索引与数据是混为一体，的它的叶节点中存储的是实际的数据。由于簇索引对表中的数据一一进行了排序，因此用簇索引查找数据很快。但由于簇索引将表的所有数据完全重新排列了，它所需要的空间也就特别大，大概相当于表中数据所占空间的120% 。表的数据行只能以一种排序方式存储在磁盘上，所以一个表只能有一个簇索引。 <br /><br />（3） 非簇索引非簇索引具有与表的数据完全分离的结构，使用非簇索引不用将物理数据页中的数据按列排序。非簇索引的叶节点中存储了组成非簇索引的关键字的值和行定位器。行定位器的结构和存储内容取决于数据的存储方式。如果数据是以簇索引方式存储的，则行定位器中存储的是簇索引的索引键；如果数据不是以簇索引方式存储的，这种方式又称为堆存储方式（Heap Structure），则行定位器存储的是指向数据行的指针。非簇索引将行定位器按关键字的值用一定的方式排序，这个顺序与表的行在数据页中的排序是不匹配的。由于非簇索引使用索引页存储因此它比簇索引需要更多的存储空间且检索效率较低但一个表只能建一个簇索引，当用户需要建立多个索引时就需要使用非簇索引了。从理论上讲，一个表最多可以建249 个非簇索引。<br /><img src ="http://www.blogjava.net/zqli/aggbug/94016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-15 19:33 <a href="http://www.blogjava.net/zqli/archive/2007/01/15/94016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Sql 中日期函数的比较 </title><link>http://www.blogjava.net/zqli/archive/2007/01/11/93248.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Thu, 11 Jan 2007 12:22:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/11/93248.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/93248.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/11/93248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/93248.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/93248.html</trackback:ping><description><![CDATA[
		<p>select convert(varchar(8),getdate(),112)</p>
		<p>Sql 中日期函数的比较<br />作者:corin 日期:2006-06-15<br />字体大小: 小 中 大  <br />下午公司的项目完成了会员系统，会员可以后台设置到期时间！</p>
		<p>大概字段有PostDate,EndDate标志注册时间和到期时间！</p>
		<p>上午把到期时间，剩余天数及24小时登录和和注册的用户多完成了，用了一个函数DateDitt</p>
		<p>检测24小时登录和注册用户的Sql语句：</p>
		<p>Case "Login":strSql=strSql+HZ.iif(Instr(strSql,"Where")&gt;0," AND DateDiff(hh,LastDate,getdate())&lt;25"," Where DateDiff(hh,LastDate,getdate())&lt;25")<br />Case "Reg":strSql=strSql+HZ.iif(Instr(strSql,"Where")&gt;0," AND DateDiff(hh,PostDate,getdate())&lt;25"," Where DateDiff(hh,PostDate,getdate())&lt;25")</p>
		<p>其时已经实现了会员到期自动红子提示，后来要完成搜索就是可以把离到期还剩余15天的会员多列举出来，用DateDiff函数调试了半天多不正确，刚开始以为是“'”的问题， 后来检查了发现没有问题基本确认是DateDiff函数问题，可是上面检测时间的时候正确，而且Sql中也可是使用这个函数，郁闷大概调试了2个小时问题依然没有解决！</p>
		<p>偶然想到了DateAdd函数改SQL语句如下：</p>
		<p>Case "EndDate":strSql=strSql+HZ.iif(Instr(strSql,"Where")&gt;0," AND EndDate &lt; DateAdd(d,15,getdate())"," Where EndDate &lt; DateAdd(d,15,getdate())")</p>
		<p>调试通过，呼呼奇怪的问题后台去网上搜索下也没有满意的答案，只是找到这样一段</p>
		<p>Select member_number, first_name, last_name  FROM members<br />Where DATEDIFF(yy,datofbirth,GETDATE()) &gt; 21<br />应改为:<br />Select member_number, first_name, last_name  FROM members<br />Where dateofbirth &lt; DATEADD(yy,-21,GETDATE())<br />即：任何对列的操作都将导致表扫描，它包括数据库函数、计算表达式等等，查询时要尽可能将操作移至等号右边。</p>
<img src ="http://www.blogjava.net/zqli/aggbug/93248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-11 20:22 <a href="http://www.blogjava.net/zqli/archive/2007/01/11/93248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DataView</title><link>http://www.blogjava.net/zqli/archive/2007/01/08/92402.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 08 Jan 2007 08:15:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/08/92402.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/92402.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/08/92402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/92402.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/92402.html</trackback:ping><description><![CDATA[
		<font face="Courier New">  在实际编程工程中，常常遇到这样的情况：DataTable并不是数据库中的，或者DataTable尚未写到数据库，或者从数据库中读出的DataTable已经在本地被改动，又没有写回数据库（可能还要作其他改动），在这些情况下，要查询DataTable中的数据，强大的SQL语言就派不上用场了。 <br />    <br />  有些.NET程序员采取在数据库中建立临时表等方法来解决这类查询问题。而我觉得这种方法不可行，其实只要用.NET类库中提供的DataView类的强大功能（主要是用它的RowFilter属性），就能方便地解决这类查询问题。下面就举一个具体的例子，来说明如何不用SQL语句，用DataView的RowFilter属性来查询。 <br />    <br />  用DataView的RowFilter属性完全能达到SQL语句SELECT语句所实现的功能 <br />    <br />  RowFilter中的查询语句与SQL语句中SELECT语句的语法和作用都极为相似，以下是摘自MSDN中关于RowFilter查询语句的语法说明： <br />    <br />  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// <br />    <br />  用户定义的值可以用在将与列值进行比较的表达式内。字符串值应放在单引号内。日期值应放在磅符号 (#) 内。对于数值，允许使用小数和科学记数法。例如：  <br />     <br />  "FirstName = 'John'"   <br />    <br />  "Price &lt;= 50.00"     <br />    <br />  "Birthdate &lt; #1/31/82#"     <br />    <br />  对于包含枚举值的列，将值强制转换为整数数据类型。例如：  <br />    <br />  "EnumColumn = 5"     <br />    <br />  运算符     <br />    <br />  使用布尔值 AND、OR 和 NOT 运算符时允许串联。可以使用括号来组合子句和强制优先级。AND 运算符优先于其他运算符。例如：  <br />    <br />  (LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'     <br />    <br />  在创建比较表达式时，允许使用下列运算符：  <br />    <br />  &lt;  <br />    <br />  &gt;    <br />    <br />  &lt;=     <br />    <br />  &gt;=    <br />    <br />  &lt;&gt;  <br />     <br />  =  <br />      <br />  IN  <br />      <br />  LIKE  <br />       <br />  在表达式中还支持下列算术运算符：  <br />       <br />  +（加）  <br />      <br />  -（减）  <br />       <br />  *（乘）  <br />       <br />  /（除）  <br />       <br />  %（模数）  <br />       <br />  字符串运算符  <br />       <br />  若要连接字符串，请使用 + 字符。字符串比较是否区分大小写由 DataSet 类的 CaseSensitive 属性的值来确定。但是，可以用 DataTable 类的 CaseSensitive 属性重写此值。  <br />      <br />  通配符  <br />       <br />  在 LIKE 比较中，* 和 % 两者可以互换地作为通配符。如果 LIKE 子句中的字符串包含 * 或 %，那么这些字符应用中括号（[]）对其进行转义。如果子句中有中括号，那么中括号字符应用中括号对其进行转义（例如 [[] 或 []]）。在模式的开头和结尾，或者在模式的结尾，或在模式的开头允许使用通配符。例如：  <br />       <br />  "ItemName LIKE '*product*'"  <br />       <br />  "ItemName LIKE '*product'"  <br />       <br />  "ItemName LIKE 'product*'"  <br />       <br />  在字符串的中间不允许使用通配符。例如，不允许 'te*xt'。  <br />      <br />  父/子关系引用  <br />       <br />  通过在列名称前面加 Parent，就可以在表达式中引用父表。例如，Parent.Price 引用父表的名为 Price 的列。  <br />      <br />  通过在列名称前面加一个 Child，就可以在表达式中引用子表中的列。但是，因为子关系可以返回多行，所以必须在聚合函数中包括对子列的引用。例如，Sum(Child.Price) 将返回子表中名为 Price 的列的总和。  <br />       <br />  如果某个表有多个子表，则语法是：Child(RelationName)。例如，如果某个表有两个子表，它们的名称分别为 Customers 和 Orders，则 DataRelation 对象被命名为 Customers2Orders，引用将为：  <br />       <br />  Avg(Child(Customers2Orders).Quantity)  <br />       <br />  聚合  <br />       <br />  支持下列聚合类型：  <br />       <br />  Sum（求和）  <br />       <br />  Avg（平均）  <br />       <br />  Min（最小值）  <br />       <br />  Max（最大值）  <br />       <br />  Count（计数）  <br />       <br />  StDev（统计标准偏差）  <br />       <br />  Var（统计方差）。  <br />      <br />  聚合通常沿着关系执行。通过使用上面列出的函数之一和上面“父/子关系引用”中详述的子表列，来创建聚合表达式。例如：  <br />      <br />  Avg(Child.Price)  <br />       <br />  Avg(Child(Orders2Details).Price)  <br />       <br />  聚合也可以在单个表上执行。例如，若要为名为“Price”的列中的数字创建汇总，就用：  <br />       <br />  Sum(Price) </font>
		<img height="1" src="" width="1" />
		<br />
<img src ="http://www.blogjava.net/zqli/aggbug/92402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-08 16:15 <a href="http://www.blogjava.net/zqli/archive/2007/01/08/92402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[搜集整理]sql存储过程教程</title><link>http://www.blogjava.net/zqli/archive/2007/01/08/92326.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 08 Jan 2007 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/08/92326.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/92326.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/08/92326.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/92326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/92326.html</trackback:ping><description><![CDATA[
		<span class="bold">[搜集整理]sql存储过程完全教程</span>
		<br />
		<br />
		<div style="FONT-SIZE: 15px">目录<br /><br />1.sql存储过程概述<br />2.SQL存储过程创建<br />3.sql存储过程及应用<br />4.各种存储过程使用指南<br />5.ASP中存储过程调用的两种方式及比较<br />6.SQL存储过程在.NET数据库中的应用 <br />7.使用SQL存储过程要特别注意的问题<br /><br /><table class="t_msg" cellspacing="0" cellpadding="4" border="0"><tbody><tr><td class="line" style="PADDING-TOP: 10px" valign="top" height="100%"><a title="评分 0" href="http://www.54master.com/bbs/misc.php?action=viewratings&amp;tid=86081&amp;pid=1002782" name="pid1002782"></a><span class="bold">1.sql存储过程概述</span><br /><br /><div style="FONT-SIZE: 15px">在大型数据库系统中，存储过程和触发器具有很重要的作用。无论是存储过程还是触发器，都是SQL 语句和流程控制语句的集合。就本质而言，触发器也是一种存储过程。存储过程在运算时生成执行方式，所以，以后对其再运行时其执行速度很快。SQL Server 2000 不仅提供了用户自定义存储过程的功能，而且也提供了许多可作为工具使用的系统存储过程。<br /><br />存储过程的概念<br /><br />    存储过程（Stored Procedure）是一组为了完成特定功能的SQL 语句集，经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数（如果该存储过程带有参数）来执行它。<br /><br />    在SQL Server 的系列版本中存储过程分为两类：系统提供的存储过程和用户自定义存储过程。系统过程主要存储在master 数据库中并以sp_为前缀，并且系统存储过程主要是从系统表中获取信息，从而为系统管理员管理SQL Server 提供支持。通过系统存储过程，MS SQL Server 中的许多管理性或信息性的活动（如了解数据库对象、数据库信息）都可以被顺利有效地完成。尽管这些系统存储过程被放在master 数据库中，但是仍可以在其它数据库中对其进行调用，在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时，一些系统存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建并能完成某一特定功能（如查询用户所需数据信息）的存储过程。在本章中所涉及到的存储过程主要是指用户自定义存储过程。<br /><br />    存储过程的优点<br /><br />    当利用MS SQL Server 创建一个应用程序时，Transaction-SQL 是一种主要的编程语言。若运用Transaction-SQL 来进行编程，有两种方法。其一是，在本地存储Transaction- SQL 程序，并创建应用程序向SQL Server 发送命令来对结果进行处理。其二是，可以把部分用Transaction-SQL 编写的程序作为存储过程存储在SQL Server 中，并创建应用程序来调用存储过程，对数据结果进行处理存储过程能够通过接收参数向调用者返回结果集，结果集的格式由调用者确定；返回状态值给调用者，指明调用是成功或是失败；包括针对数据库的操作语句，并且可以在一个存储过程中调用另一存储过程。 <br /><br />    我们通常更偏爱于使用第二种方法，即在SQL Server 中使用存储过程而不是在客户计算机上调用Transaction-SQL 编写的一段程序，原因在于存储过程具有以下优点：<br /><br />    （1） 存储过程允许标准组件式编程<br /><br />    存储过程在被创建以后可以在程序中被多次调用，而不必重新编写该存储过程的SQL 语句。而且数据库专业人员可随时对存储过程进行修改，但对应用程序源代码毫无影响（因为应用程序源代码只包含存储过程的调用语句），从而极大地提高了程序的可移植性。<br /><br />    （2） 存储过程能够实现较快的执行速度<br /><br />    如果某一操作包含大量的Transaction-SQL 代码或分别被多次执行，那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的，在首次运行一个存储过程时，查询优化器对其进行分析、优化，并给出最终被存在系统表中的执行计划。而批处理的Transaction- SQL 语句在每次运行时都要进行编译和优化，因此速度相对要慢一些。<br /><br />    （3） 存储过程能够减少网络流量<br /><br />    对于同一个针对数据数据库对象的操作（如查询、修改），如果这一操作所涉及到的 Transaction-SQL 语句被组织成一存储过程，那么当在客户计算机上调用该存储过程时，网络中传送的只是该调用语句，否则将是多条SQL 语句，从而大大增加了网络流量，降低网络负载。<br /><br />    （4） 存储过程可被作为一种安全机制来充分利用<br /><br />    系统管理员通过对执行某一存储过程的权限进行限制，从而能够实现对相应的数据访问权限的限制，避免非授权用户对数据的访问，保证数据的安全。（我们将在14 章“SQLServer 的用户和安全性管理”中对存储过程的这一应用作更为清晰的介绍）<br /><br />    注意：存储过程虽然既有参数又有返回值，但是它与函数不同。存储过程的返回值只是指明执行是否成功，并且它不能像函数那样被直接调用，也就是在调用存储过程时，在存储过程名字前一定要有EXEC保留字。</div></td></tr><tr><td valign="bottom"><br /><span class="bold">2.SQL存储过程创建</span><br /><br /><div style="FONT-SIZE: 15px">创建存储过程，存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL 语句的集合。<br />　　<br />　　可以创建一个过程供永久使用，或在一个会话中临时使用（局部临时过程），或在所有会话中临时使用（全局临时过程）。<br />　　<br />　　也可以创建在 Microsoft? SQL Server? 启动时自动运行的存储过程。<br />　　<br />　　语法<br />　　CREATE PROC [ EDURE ] procedure_name [ ; number ]<br />　　　　[ { @parameter data_type }<br />　　　　　　[ VARYING ] [ = default ] [ OUTPUT ]<br />　　　　] [ ,...n ] <br />　　<br />　　[ WITH<br />　　　　{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] <br />　　<br />　　[ FOR REPLICATION ] <br />　　<br />　　AS sql_statement [ ...n ]</div><br /><div style="FONT-SIZE: 15px">参数<br />　　procedure_name<br />　　<br />　　新存储过程的名称。过程名必须符合标识符规则，且对于数据库及其所有者必须唯一。<br />　　要创建局部临时过程，可以在 procedure_name 前面加一个编号符 (#procedure_name)，要创建全局临时过程，可以在 procedure_name 前面加两个编号符 (##procedure_name)。完整的名称（包括 # 或 ##）不能超过 128 个字符。指定过程所有者的名称是可选的。<br />　　<br />　　;number<br />　　<br />　　是可选的整数，用来对同名的过程分组，以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。例如，名为 orders 的应用程序使用的过程可以命名为 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 语句将除去整个组。如果名称中包含定界标识符，则数字不应包含在标识符中，只应在 procedure_name 前后使用适当的定界符。<br />　　<br />　　@parameter<br />　　<br />　　过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值（除非定义了该参数的默认值）。存储过程最多可以有 2.100 个参数。<br />　　<br />　　使用 @ 符号作为第一个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身；相同的参数名称可以用在其它过程中。默认情况下，参数只能代替常量，而不能用于代替表名、列名或其它数据库对象的名称。<br />　　data_type<br />　　<br />　　参数的数据类型。所有数据类型（包括 text、ntext 和 image）均可以用作存储过程的参数。不过，cursor 数据类型只能用于 OUTPUT 参数。如果指定的数据类型为 cursor，也必须同时指定 VARYING 和 OUTPUT 关键字。<br />　　说明　对于可以是 cursor 数据类型的输出参数，没有最大数目的限制。<br />　　<br />　　<br />　　VARYING<br />　　<br />　　指定作为输出参数支持的结果集（由存储过程动态构造，内容可以变化）。仅适用于游标参数。<br />　　<br />　　default<br />　　<br />　　参数的默认值。如果定义了默认值，不必指定该参数的值即可执行过程。默认值必须是常量或 NULL。如果过程将对该参数使用 LIKE 关键字，那么默认值中可以包含通配符（%、_、[] 和 [^]）。<br />　　<br />　　OUTPUT<br />　　<br />　　表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。使用 OUTPUT 参数可将信息返回给调用过程。Text、ntext 和 image 参数可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以是游标占位符。<br />　　<br />　　n<br />　　<br />　　表示最多可以指定 2.100 个参数的占位符。<br />　　<br />　　{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}<br />　　<br />　　RECOMPILE 表明 SQL Server 不会缓存该过程的计划，该过程将在运行时重新编译。在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时，请使用 RECOMPILE 选项。<br />　　<br />　　ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。使用 ENCRYPTION 可防止将过程作为 SQL Server 复制的一部分发布。<br />　　<br />　　<br />　　<br />　　说明　在升级过程中，SQL Server 利用存储在 syscomments 中的加密注释来重新创建加密过程。<br />　　<br />　　<br />　　FOR REPLICATION<br />　　<br />　　指定不能在订阅服务器上执行为复制创建的存储过程。.使用 FOR REPLICATION 选项创建的存储过程可用作存储过程筛选，且只能在复制过程中执行。本选项不能和 WITH RECOMPILE 选项一起使用。<br />　　<br />　　AS<br />　　<br />　　指定过程要执行的操作。<br />　　<br />　　sql_statement<br />　　<br />　　过程中要包含的任意数目和类型的 Transact-SQL 语句。但有一些限制。<br />　　<br />　　n<br />　　<br />　　是表示此过程可以包含多条 Transact-SQL 语句的占位符。<br />　　<br />　　注释<br />　　存储过程的最大大小为 128 MB。</div><br /><table class="t_msg" cellspacing="0" cellpadding="4" border="0"><tbody><tr><td class="line" style="PADDING-TOP: 10px" valign="top" height="100%"><a title="评分 0" href="http://www.54master.com/bbs/misc.php?action=viewratings&amp;tid=86081&amp;pid=1002789" name="pid1002789"></a><div style="FONT-SIZE: 15px">用户定义的存储过程只能在当前数据库中创建（临时过程除外，临时过程总是在 tempdb 中创建）。在单个批处理中，CREATE PROCEDURE 语句不能与其它 Transact-SQL 语句组合使用。 <br />　　<br />　　默认情况下，参数可为空。如果传递 NULL 参数值并且该参数在 CREATE 或 ALTER TABLE 语句中使用，而该语句中引用的列又不允许使用 NULL，则 SQL Server 会产生一条错误信息。为了防止向不允许使用 NULL 的列传递 NULL 参数值，应向过程中添加编程逻辑或为该列使用默认值（使用 CREATE 或 ALTER TABLE 的 DEFAULT 关键字)。<br />　　<br />　　建议在存储过程的任何 CREATE TABLE 或 ALTER TABLE 语句中都为每列显式指定 NULL 或 NOT NULL，例如在创建临时表时。ANSI_DFLT_ON 和 ANSI_DFLT_OFF 选项控制 SQL Server 为列指派 NULL 或 NOT NULL 特性的方式（如果在 CREATE TABLE 或 ALTER TABLE 语句中没有指定的话）。如果某个连接执行的存储过程对这些选项的设置与创建该过程的连接的设置不同，则为第二个连接创建的表列可能会有不同的为空性，并且表现出不同的行为方式。如果为每个列显式声明了 NULL 或 NOT NULL，那么将对所有执行该存储过程的连接使用相同的为空性创建临时表。<br />　　<br />　　在创建或更改存储过程时，SQL Server 将保存 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 的设置。执行存储过程时，将使用这些原始设置。因此，所有客户端会话的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 设置在执行存储过程时都将被忽略。在存储过程中出现的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 语句不影响存储过程的功能。<br />　　<br />　　其它 SET 选项（例如 SET ARITHABORT、SET ANSI_WARNINGS 或 SET ANSI_PADDINGS）在创建或更改存储过程时不保存。如果存储过程的逻辑取决于特定的设置，应在过程开头添加一条 SET 语句，以确保设置正确。从存储过程中执行 SET 语句时，该设置只在存储过程完成之前有效。之后，设置将恢复为调用存储过程时的值。这使个别的客户端可以设置所需的选项，而不会影响存储过程的逻辑。<br />　　<br /><br />天涯风云  19:30:43<br />说明　SQL Server 是将空字符串解释为单个空格还是解释为真正的空字符串，由兼容级别设置控制。如果兼容级别小于或等于 65，SQL Server 就将空字符串解释为单个空格。如果兼容级别等于 70，则 SQL Server 将空字符串解释为空字符串。<br />　　获得有关存储过程的信息<br />　　若要显示用来创建过程的文本，请在过程所在的数据库中执行 sp_helptext，并使用过程名作为参数。 <br />　　<br />　　<br />　　<br />　　说明　使用 ENCRYPTION 选项创建的存储过程不能使用 sp_helptext 查看。<br />　　<br />　　<br />　　若要显示有关过程引用的对象的报表，请使用 sp_depends。 <br />　　<br />　　若要为过程重命名，请使用 sp_rename。</div></td></tr><tr><td valign="bottom"><br /></td></tr></tbody></table>引用对象<br />　　SQL Server 允许创建的存储过程引用尚不存在的对象。在创建时，只进行语法检查。执行时，如果高速缓存中尚无有效的计划，则编译存储过程以生成执行计划。只有在编译过程中才解析存储过程中引用的所有对象。因此，如果语法正确的存储过程引用了不存在的对象，则仍可以成功创建，但在运行时将失败，因为所引用的对象不存在。<br />　　延迟名称解析和兼容级别<br />　　SQL Server 允许 Transact-SQL 存储过程在创建时引用不存在的表。这种能力称为延迟名称解析。不过，如果 Transact-SQL 存储过程引用了该存储过程中定义的表，而兼容级别设置（通过执行 sp_dbcmptlevel 来设置）为 65，则在创建时会发出警告信息。而如果在运行时所引用的表不存在，将返回错误信息。<br />　　执行存储过程<br />　　成功执行 CREATE PROCEDURE 语句后，过程名称将存储在 sysobjects 系统表中，而 CREATE PROCEDURE 语句的文本将存储在 syscomments 中。第一次执行时，将编译该过程以确定检索数据的最佳访问计划。<br />　　<br />　　使用 cursor 数据类型的参数<br />　　存储过程只能将 cursor 数据类型用于 OUTPUT 参数。如果为某个参数指定了 cursor 数据类型，也必须指定 VARYING 和 OUTPUT 参数。如果为某个参数指定了 VARYING 关键字，则数据类型必须是 cursor，并且必须指定 OUTPUT 关键字。<br />　　<br />　　<br />　　<br />　　说明　cursor 数据类型不能通过数据库 API（例如 OLE DB、ODBC、ADO 和 DB-Library）绑定到应用程序变量上。因为必须先绑定 OUTPUT 参数，应用程序才可以执行存储过程，所以带有 cursor OUTPUT 参数的存储过程不能通过数据库 API 调用。只有将 cursor OUTPUT 变量赋值给 Transact-SQL 局部 cursor 变量时，才可以通过 Transact-SQL 批处理、存储过程或触发器调用这些过程。<br />　　<br />　　<br />　　Cursor 输出参数<br />　　在执行过程时，以下规则适用于 cursor 输出参数： <br />　　<br />　　对于只进游标，游标的结果集中返回的行只是那些存储过程执行结束时处于或超出游标位置的行，例如： <br />　　在过程中的名为 RS 的 100 行结果集上打开一个非滚动游标。 <br />　　<br />　　<br />　　过程提取结果集 RS 的头 5 行。<br />　　<br />　　<br />　　过程返回到其调用者。<br />　　<br />　　<br />　　返回到调用者的结果集 RS 由 RS 的第 6 到 100 行组成，调用者中的游标处于 RS 的第一行之前。 <br />　　对于只进游标，如果存储过程完成后，游标位于第一行的前面，则整个结果集将返回给调用批处理、存储过程或触发器。返回时，游标将位于第一行的前面。<br />　　<br />　　<br />　　对于只进游标，如果存储过程完成后，游标的位置超出最后一行的结尾，则为调用批处理、存储过程或触发器返回空结果集。 <br />　　<br />　　<br />　　说明　空结果集与空值不同。<br />　　<br />　　对于可滚动游标，在存储过程执行结束时，结果集中的所有行均会返回给调用批处理、存储过程或触发器。返回时，游标保留在过程中最后一次执行提取时的位置。<br />　　<br />　　<br />　　对于任意类型的游标，如果游标关闭，则将空值传递回调用批处理、存储过程或触发器。如果将游标指派给一个参数，但该游标从未打开过，也会出现这种情况。 <br />　　<br />　　<br />　　说明　关闭状态只有在返回时才有影响。例如，可以在过程中关闭游标，稍后再打开游标，然后将该游标的结果集返回给调用批处理、存储过程或触发器。<br />　　<br />　　<br />　　临时存储过程<br />　　SQL Server 支持两种临时过程：局部临时过程和全局临时过程。局部临时过程只能由创建该过程的连接使用。全局临时过程则可由所有连接使用。局部临时过程在当前会话结束时自动除去。全局临时过程在使用该过程的最后一个会话结束时除去。通常是在创建该过程的会话结束时。<br />　　<br />　　临时过程用 # 和 ## 命名，可以由任何用户创建。创建过程后，局部过程的所有者是唯一可以使用该过程的用户。执行局部临时过程的权限不能授予其他用户。如果创建了全局临时过程，则所有用户均可以访问该过程，权限不能显式废除。只有在 tempdb 数据库中具有显式 CREATE PROCEDURE 权限的用户，才可以在该数据库中显式创建临时过程（不使用编号符命名）。可以授予或废除这些过程中的权限。 <br />　　<br />　　<br />　　<br />　　说明　频繁使用临时存储过程会在 tempdb 中的系统表上产生争用，从而对性能产生负面影响。建议使用 sp_executesql 代替。sp_executesql 不在系统表中存储数据，因此可以避免这一问题。<br /><br /><div style="FONT-SIZE: 15px">自动执行存储过程<br />　　SQL Server 启动时可以自动执行一个或多个存储过程。这些存储过程必须由系统管理员创建，并在 sysadmin 固定服务器角色下作为后台过程执行。这些过程不能有任何输入参数。 <br />　　<br />　　对启动过程的数目没有限制，但是要注意，每个启动过程在执行时都会占用一个连接。如果必须在启动时执行多个过程，但不需要并行执行，则可以指定一个过程作为启动过程，让该过程调用其它过程。这样就只占用一个连接。<br />　　<br />　　在启动时恢复了最后一个数据库后，即开始执行存储过程。若要跳过这些存储过程的执行，请将启动参数指定为跟踪标记 4022。如果以最低配置启动 SQL Server（使用 -f 标记），则启动存储过程也不会执行。<br />　　若要创建启动存储过程，必须作为 sysadmin 固定服务器角色的成员登录，并在 master 数据库中创建存储过程。<br />　　<br />　　使用 sp_procoption 可以： <br />　　<br />　　将现有存储过程指定为启动过程。<br />　　<br />　　<br />　　停止在 SQL Server 启动时执行过程。<br />　　<br />　　<br />　　查看 SQL Server 启动时执行的所有过程的列表。 <br />　　存储过程嵌套<br />　　存储过程可以嵌套，即一个存储过程可以调用另一个存储过程。在被调用过程开始执行时，嵌套级将增加，在被调用过程执行结束后，嵌套级将减少。如果超出最大的嵌套级，会使整个调用过程链失败。可用 @@NESTLEVEL 函数返回当前的嵌套级。<br />　　<br />　　若要估计编译后的存储过程大小，请使用下列性能监视计数器。 <br />　　<br />　　  <br />　　* 各种分类的高速缓存对象均可以使用这些计数器，包括特殊 sql、准备 sql、过程、触发器等。<br />　　<br />　　sql_statement 限制<br />　　除了 SET SHOWPLAN_TEXT 和 SET SHOWPLAN_ALL 之外（这两个语句必须是批处理中仅有的语句），任何 SET 语句均可以在存储过程内部指定。所选择的 SET 选项在存储过程执行过程中有效，之后恢复为原来的设置。 <br />　　<br />　　如果其他用户要使用某个存储过程，那么在该存储过程内部，一些语句使用的对象名必须使用对象所有者的名称限定。这些语句包括： <br />　　<br />　　ALTER TABLE<br />　　<br />　　<br />　　CREATE INDEX<br />　　<br />　　<br />　　CREATE TABLE<br />　　<br />　　<br />　　所有 DBCC 语句<br />　　<br />　　<br />　　DROP TABLE<br />　　<br />　　<br />　　DROP INDEX<br />　　<br />　　<br />　　TRUNCATE TABLE<br />　　<br />　　<br />　　UPDATE STATISTICS <br />　　权限<br />　　CREATE PROCEDURE 的权限默认授予 sysadmin 固定服务器角色成员和 db_owner 和 db_ddladmin 固定数据库角色成员。sysadmin 固定服务器角色成员和 db_owner 固定数据库角色成员可以将 CREATE PROCEDURE 权限转让给其他用户。执行存储过程的权限授予过程的所有者，该所有者可以为其它数据库用户设置执行权限。</div><br />示例<br />　　A. 使用带有复杂 SELECT 语句的简单过程<br />　　下面的存储过程从四个表的联接中返回所有作者（提供了姓名）、出版的书籍以及出版社。该存储过程不使用任何参数。<br />　　<br />　　USE pubs<br />　　IF EXISTS (SELECT name FROM sysobjects <br />　　　　　　 WHERE name = \'au_info_all\' AND type = \'P\')<br />　　　 DROP PROCEDURE au_info_all<br />　　GO<br />　　CREATE PROCEDURE au_info_all<br />　　AS<br />　　SELECT au_lname, au_fname, title, pub_name<br />　　　 FROM authors a INNER JOIN titleauthor ta<br />　　　　　ON a.au_id = ta.au_id INNER JOIN titles t<br />　　　　　ON t.title_id = ta.title_id INNER JOIN publishers p<br />　　　　　ON t.pub_id = p.pub_id<br />　　GO<br />　　<br />　　au_info_all 存储过程可以通过以下方法执行：<br />　　<br />　　EXECUTE au_info_all<br />　　-- Or<br />　　EXEC au_info_all<br />　　<br />　　如果该过程是批处理中的第一条语句，则可使用：<br />　　<br />　　au_info_all<br /><br />天涯风云  19:31:29<br />B. 使用带有参数的简单过程<br />　　下面的存储过程从四个表的联接中只返回指定的作者（提供了姓名）、出版的书籍以及出版社。该存储过程接受与传递的参数精确匹配的值。<br />　　<br />　　USE pubs<br />　　IF EXISTS (SELECT name FROM sysobjects <br />　　　　　　 WHERE name = \'au_info\' AND type = \'P\')<br />　　　 DROP PROCEDURE au_info<br />　　GO<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE au_info <br />　　　 @lastname varchar(40), <br />　　　 @firstname varchar(20) <br />　　AS <br />　　SELECT au_lname, au_fname, title, pub_name<br />　　　 FROM authors a INNER JOIN titleauthor ta<br />　　　　　ON a.au_id = ta.au_id INNER JOIN titles t<br />　　　　　ON t.title_id = ta.title_id INNER JOIN publishers p<br />　　　　　ON t.pub_id = p.pub_id<br />　　　 WHERE　au_fname = @firstname<br />　　　　　AND au_lname = @lastname<br />　　GO<br />　　<br />　　au_info 存储过程可以通过以下方法执行：<br />　　<br />　　EXECUTE au_info \'Dull\', \'Ann\'<br />　　-- Or<br />　　EXECUTE au_info @lastname = \'Dull\', @firstname = \'Ann\'<br />　　-- Or<br />　　EXECUTE au_info @firstname = \'Ann\', @lastname = \'Dull\'<br />　　-- Or<br />　　EXEC au_info \'Dull\', \'Ann\'<br />　　-- Or<br />　　EXEC au_info @lastname = \'Dull\', @firstname = \'Ann\'<br />　　-- Or<br />　　EXEC au_info @firstname = \'Ann\', @lastname = \'Dull\'<br />　　<br />　　如果该过程是批处理中的第一条语句，则可使用：<br />　　<br />　　au_info \'Dull\', \'Ann\'<br />　　-- Or<br />　　au_info @lastname = \'Dull\', @firstname = \'Ann\'<br />　　-- Or<br />　　au_info @firstname = \'Ann\', @lastname = \'Dull\'<br /><br />天涯风云  19:31:41<br />C. 使用带有通配符参数的简单过程<br />　　下面的存储过程从四个表的联接中只返回指定的作者（提供了姓名）、出版的书籍以及出版社。该存储过程对传递的参数进行模式匹配，如果没有提供参数，则使用预设的默认值。<br />　　<br />　　USE pubs<br />　　IF EXISTS (SELECT name FROM sysobjects <br />　　　　　WHERE name = \'au_info2\' AND type = \'P\')<br />　　　 DROP PROCEDURE au_info2<br />　　GO<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE au_info2<br />　　　 @lastname varchar(30) = \'D%\',<br />　　　 @firstname varchar(18) = \'%\'<br />　　AS <br />　　SELECT au_lname, au_fname, title, pub_name<br />　　FROM authors a INNER JOIN titleauthor ta<br />　　　 ON a.au_id = ta.au_id INNER JOIN titles t<br />　　　 ON t.title_id = ta.title_id INNER JOIN publishers p<br />　　　 ON t.pub_id = p.pub_id<br />　　WHERE au_fname LIKE @firstname<br />　　　 AND au_lname LIKE @lastname<br />　　GO<br />　　<br />　　au_info2 存储过程可以用多种组合执行。下面只列出了部分组合：<br />　　<br />　　EXECUTE au_info2<br />　　-- Or<br />　　EXECUTE au_info2 \'Wh%\'<br />　　-- Or<br />　　EXECUTE au_info2 @firstname = \'A%\'<br />　　-- Or<br />　　EXECUTE au_info2 \'[CK]ars[OE]n\'<br />　　-- Or<br />　　EXECUTE au_info2 \'Hunter\', \'Sheryl\'<br />　　-- Or<br />　　EXECUTE au_info2 \'H%\', \'S%\' <br />--------------------------------------------------------------------------------<br /><br /><br /><br /><br />天涯风云  19:32:22<br />D. 使用 OUTPUT 参数<br />　　OUTPUT 参数允许外部过程、批处理或多条 Transact-SQL 语句访问在过程执行期间设置的某个值。下面的示例创建一个存储过程 (titles_sum)，并使用一个可选的输入参数和一个输出参数。<br />　　<br />　　首先，创建过程：<br />　　<br />　　USE pubs<br />　　GO<br />　　IF EXISTS(SELECT name FROM sysobjects<br />　　　　　WHERE name = \'titles_sum\' AND type = \'P\')<br />　　　 DROP PROCEDURE titles_sum<br />　　GO<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE titles_sum @@TITLE varchar(40) = \'%\', @@SUM money OUTPUT<br />　　AS<br />　　SELECT \'Title Name\' = title<br />　　FROM titles <br />　　WHERE title LIKE @@TITLE <br />　　SELECT @@SUM = SUM(price)<br />　　FROM titles<br />　　WHERE title LIKE @@TITLE<br />　　GO<br />　　<br />　　接下来，将该 OUTPUT 参数用于控制流语言。 <br />　　<br />　　<br />　　<br />　　说明　OUTPUT 变量必须在创建表和使用该变量时都进行定义。<br />　　<br />　　<br />　　参数名和变量名不一定要匹配，不过数据类型和参数位置必须匹配（除非使用 @@SUM = variable 形式）。 <br />　　<br />　　DECLARE @@TOTALCOST money<br />　　EXECUTE titles_sum \'The%\', @@TOTALCOST OUTPUT<br />　　IF @@TOTALCOST &lt; 200 <br />　　BEGIN<br />　　　 PRINT \' \'<br />　　　 PRINT \'All of these titles can be purchased for less than $200.\'<br />　　END<br />　　ELSE<br />　　　 SELECT \'The total cost of these titles is $\' <br />　　　　　　 + RTRIM(CAST(@@TOTALCOST AS varchar(20)))<br />　　<br />　　下面是结果集：<br />　　<br />　　Title Name　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 <br />　　------------------------------------------------------------------------ <br />　　The Busy Executive\'s Database Guide<br />　　The Gourmet Microwave<br />　　The Psychology of Computer Cooking<br />　　<br />　　(3 row(s) affected)<br />　　<br />　　Warning, null value eliminated from aggregate.<br />　　 <br />　　All of these titles can be purchased for less than $200.<br /><br />天涯风云  19:32:33<br />E. 使用 OUTPUT 游标参数<br />　　OUTPUT 游标参数用来将存储过程的局部游标传递回调用批处理、存储过程或触发器。<br />　　<br />　　首先，创建以下过程，在 titles 表上声明并打开一个游标：<br />　　<br />　　USE pubs<br />　　IF EXISTS (SELECT name FROM sysobjects <br />　　　　　WHERE name = \'titles_cursor\' and type = \'P\')<br />　　DROP PROCEDURE titles_cursor<br />　　GO<br />　　CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT<br />　　AS<br />　　SET @titles_cursor = CURSOR<br />　　FORWARD_ONLY STATIC FOR<br />　　SELECT *<br />　　FROM titles<br />　　<br />　　OPEN @titles_cursor<br />　　GO<br />　　<br />　　接下来，执行一个批处理，声明一个局部游标变量，执行上述过程以将游标赋值给局部变量，然后从该游标提取行。<br />　　<br />　　USE pubs<br />　　GO<br />　　DECLARE @MyCursor CURSOR<br />　　EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT<br />　　WHILE (@@FETCH_STATUS = 0)<br />　　BEGIN<br />　　　 FETCH NEXT FROM @MyCursor<br />　　END<br />　　CLOSE @MyCursor<br />　　DEALLOCATE @MyCursor<br />　　GO<br /><br />天涯风云  19:32:43<br />　F. 使用 WITH RECOMPILE 选项<br />　　如果为过程提供的参数不是典型的参数，并且新的执行计划不应高速缓存或存储在内存中，WITH RECOMPILE 子句会很有帮助。<br />　　<br />　　USE pubs<br />　　IF EXISTS (SELECT name FROM sysobjects<br />　　　　　WHERE name = \'titles_by_author\' AND type = \'P\')<br />　　　 DROP PROCEDURE titles_by_author<br />　　GO<br />　　CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = \'%\'<br />　　WITH RECOMPILE<br />　　AS<br />　　SELECT RTRIM(au_fname) + \' \' + RTRIM(au_lname) AS \'Authors full name\',<br />　　　 title AS Title<br />　　FROM authors a INNER JOIN titleauthor ta <br />　　　 ON a.au_id = ta.au_id INNER JOIN titles t<br />　　　 ON ta.title_id = t.title_id<br />　　WHERE au_lname LIKE @@LNAME_PATTERN<br />　　GO<br /><br /><br /><br />天涯风云  19:32:59<br />G. 使用 WITH ENCRYPTION 选项<br />　　WITH ENCRYPTION 子句对用户隐藏存储过程的文本。下例创建加密过程，使用 sp_helptext 系统存储过程获取关于加密过程的信息，然后尝试直接从 syscomments 表中获取关于该过程的信息。<br />　　<br />　　IF EXISTS (SELECT name FROM sysobjects<br />　　　　　WHERE name = \'encrypt_this\' AND type = \'P\')<br />　　　 DROP PROCEDURE encrypt_this<br />　　GO<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE encrypt_this<br />　　WITH ENCRYPTION<br />　　AS<br />　　SELECT * <br />　　FROM authors<br />　　GO<br />　　<br />　　EXEC sp_helptext encrypt_this<br />　　<br />　　下面是结果集：<br />　　<br />　　The object\'s comments have been encrypted.<br />　　<br />　　接下来，选择加密存储过程内容的标识号和文本。<br />　　<br />　　SELECT c.id, c.text <br />　　FROM syscomments c INNER JOIN sysobjects o<br />　　　 ON c.id = o.id<br />　　WHERE o.name = \'encrypt_this\'<br />　　<br />　　下面是结果集：<br />　　<br />　　<br />　　<br />　　说明　text 列的输出显示在单独一行中。执行时，该信息将与 id 列信息出现在同一行中。<br />　　<br />　　<br />　　id　　　　 text　　　　　　　　　　　　　　　　　　　　　　　　　　　　<br />　　---------- ------------------------------------------------------------<br />　　1413580074 ?????????????????????????????????e??????????????????????????????????????????????????????????????????????????<br />　　<br />　　(1 row(s) affected)<br /><br />天涯风云  19:33:10<br />H. 创建用户定义的系统存储过程<br />　　下面的示例创建一个过程，显示表名以 emp 开头的所有表及其对应的索引。如果没有指定参数，该过程将返回表名以 sys 开头的所有表（及索引）。<br />　　<br />　　IF EXISTS (SELECT name FROM sysobjects<br />　　　　　WHERE name = \'sp_showindexes\' AND type = \'P\')<br />　　　 DROP PROCEDURE sp_showindexes<br />　　GO<br />　　USE master<br />　　GO<br />　　CREATE PROCEDURE sp_showindexes<br />　　　 @@TABLE varchar(30) = \'sys%\'<br />　　AS <br />　　SELECT o.name AS TABLE_NAME,<br />　　　 i.name AS INDEX_NAME, <br />　　　 indid AS INDEX_ID<br />　　FROM sysindexes i INNER JOIN sysobjects o<br />　　　 ON o.id = i.id <br />　　WHERE o.name LIKE @@TABLE<br />　　GO　　　　 <br />　　USE pubs<br />　　EXEC sp_showindexes \'emp%\'<br />　　GO<br />　　<br />　　下面是结果集：<br />　　<br />　　TABLE_NAME　　　 INDEX_NAME　　　 INDEX_ID <br />　　---------------- ---------------- ----------------<br />　　employee　　　　 employee_ind　　 1<br />　　employee　　　　 PK_emp_id　　　　2<br />　　<br />　　(2 row(s) affected)<br /><br />天涯风云  19:33:24<br />I. 使用延迟名称解析<br />　　下面的示例显示四个过程以及延迟名称解析的各种可能使用方式。尽管引用的表或列在编译时不存在，但每个存储过程都可创建。<br />　　<br />　　IF EXISTS (SELECT name FROM sysobjects<br />　　　　　WHERE name = \'proc1\' AND type = \'P\')<br />　　　 DROP PROCEDURE proc1<br />　　GO<br />　　-- Creating a procedure on a nonexistent table.<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE proc1<br />　　AS<br />　　　 SELECT *<br />　　　 FROM does_not_exist<br />　　GO　<br />　　-- Here is the statement to actually see the text of the procedure.<br />　　SELECT o.id, c.text<br />　　FROM sysobjects o INNER JOIN syscomments c <br />　　　 ON o.id = c.id<br />　　WHERE o.type = \'P\' AND o.name = \'proc1\'<br />　　GO<br />　　USE master<br />　　GO<br />　　IF EXISTS (SELECT name FROM sysobjects<br />　　　　　WHERE name = \'proc2\' AND type = \'P\')<br />　　　 DROP PROCEDURE proc2<br />　　GO<br />　　-- Creating a procedure that attempts to retrieve information from a<br />　　-- nonexistent column in an existing table.<br />　　USE pubs<br />　　GO<br />　　CREATE PROCEDURE proc2<br />　　AS<br />　　　 DECLARE @middle_init char(1)<br />　　　 SET @middle_init = NULL<br />　　　 SELECT au_id, middle_initial = @middle_init<br />　　　 FROM authors<br />　　GO　<br />　　-- Here is the statement to actually see the text of the procedure.<br />　　SELECT o.id, c.text<br />　　FROM sysobjects o INNER JOIN syscomments c <br />　　　 ON o.id = c.id<br />　　WHERE o.type = \'P\' and o.name = \'proc2\'<br /><br /><span class="bold">3.sql存储过程及应用</span><br /><br /><div style="FONT-SIZE: 15px">一、简介：<br />    <br />　　　存储过程（Stored Procedure）， 是一组为了完成特定功能的SQL 语句，集经编译后<br />    存储在数据库中，用户通过指定存储过程的名字并给出参数，如果该存储过程带有参数来执行<br /><br />它，<br />    在SQL Server 的系列版本中，存储过程分为两类：系统提供的存储过程和用户自定义存储过程<br /><br />。<br />    系统SP，主要存储master 数据库中，并以sp_为前缀并且系统存储过程主要是从系统表中获取<br />    信息，从而为系统管理员管理SQL Server。 用户自定义存储过程是由用户创建，并能完成<br />    某一特定功能，如：查询用户所需数据信息的存储过程。<br />    <br />    　　存储过程具有以下优点<br />    1.存储过程允许标准组件式编程(模块化设计)<br />    存储过程在被创建以后，可以在程序中被多次调用，而不必重新编写该存储过程的SQL语句，而<br /><br />且数<br />    据库专业人员可随时对存储过程进行修改，但对应用程序源代码毫无影响。因为应用程序源代<br /><br />码只包含存<br />    储过程的调用语句，从而极大地提高了程序的可移植性。<br />            <br />    2.存储过程能够实现快速的执行速度<br />　　　如果某一操作包含大量的Transaction-SQL 代码,，或分别被多次执行，那么存储过程要比批处理<br /><br />的<br />    执行速度快很多，因为存储过程是预编译的，在首次运行一个存储过程时，查询优化器对其进<br /><br />行分析优<br />    化，并给出最终被存在系统表中的执行计划，而批处理的Transaction-SQL 语句在每次运行时<br /><br />都要进行<br />    编译和优化，因此速度相对要慢一些。<br />                <br />    3.存储过程能够减少网络流量<br />　　　对于同一个针对数据数据库对象的操作，如查询修改，如果这一操作所涉及到的Transaction-SQL <br />    语句被组织成一存储过程，那么当在客户计算机上调用该存储过程时，网络中传送的只是该调<br /><br />用语句，否<br />    则将是多条SQL 语句从而大大增加了网络流量降低网络负载。<br />            <br />    4.存储过程可被作为一种安全机制来充分利用<br />　　　系统管理员通过，对执行某一存储过程的权限进行限制，从而能够实现对相应的数据访问权限的<br /><br />限<br />    制。<br /><br /><br />    二、变量<br /><br />    @I<br /><br />    三、流程控制语句(if else | select case | while )<br />    Select ... CASE 实例<br />    DECLARE @iRet INT, @PKDisp VARCHAR(20)<br />    SET @iRet = '1'<br />    Select @iRet = <br />    CASE<br />        WHEN @PKDisp = '一' THEN 1<br />        WHEN @PKDisp = '二' THEN 2<br />        WHEN @PKDisp = '三' THEN 3<br />        WHEN @PKDisp = '四' THEN 4<br />        WHEN @PKDisp = '五' THEN 5<br />        ELSE 100<br />    END<br /><br />    四、存储过程格式<br />        <br />    创建存储过程<br />    Create Proc dbo.存储过程名<br />    存储过程参数<br />    AS<br />    执行语句<br />    RETURN<br />    执行存储过程<br />    GO<br />*********************************************************/<br /><br /><br />-- 变量的声明,sql里面声明变量时必须在变量前加@符号<br />    DECLARE @I INT<br /><br />-- 变量的赋值，变量赋值时变量前必须加set<br />    SET @I = 30<br /><br />-- 声明多个变量<br />    DECLARE @s varchar(10),@a INT<br /><br />-- Sql 里if语句<br />    IF 条件 BEGIN<br />        执行语句<br />    END<br />    ELSE BEGIN<br />        执行语句<br />    END<br />            <br />    DECLARE @d INT<br />    set @d = 1<br /><br />    IF @d = 1 BEGIN<br /><br />    -- 打印<br />        PRINT '正确'<br />    END<br />    ELSE BEGIN<br />        PRINT '错误'<br />    END<br /><br /><br />-- Sql 里的多条件选择语句.<br />    DECLARE @iRet INT, @PKDisp VARCHAR(20)<br />    SET @iRet = 1<br />    Select @iRet = <br />    CASE<br />        WHEN @PKDisp = '一' THEN 1<br />        WHEN @PKDisp = '二' THEN 2<br />        WHEN @PKDisp = '三' THEN 3<br />        WHEN @PKDisp = '四' THEN 4<br />        WHEN @PKDisp = '五' THEN 5<br />        ELSE 100<br />    END<br /><br />-- 循环语句<br />    WHILE 条件 BEGIN    <br />        执行语句<br />    END<br /><br />    DECLARE @i INT<br />    SET @i = 1<br />    WHILE @i&lt;1000000 BEGIN<br />        set @i=@i+1<br />    END<br />    -- 打印<br />    PRINT @i<br /><br /><br />-- TRUNCATE 删除表中的所有行，而不记录单个行删除操作，不能带条件<br /><br />    /*<br />    TRUNCATE TABLE 在功能上与不带 Where 子句的 Delete 语句相同：二者均删除表中的全部行<br /><br />。但 TRUNCATE TABLE 比 Delete 速度快，且使用的系统和事务日志资源少。 <br />    Delete 语句每次删除一行，并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过<br /><br />释放存储表数据所用的数据页来删除数据，并且只在事务日志中记录页的释放。<br />    TRUNCATE TABLE 删除表中的所有行，但表结构及其列、约束、索引等保持不变。新行标识所用<br /><br />的计数值重置为该列的种子。如果想保留标识计数值，请改用 Delete。如果要删除表定义及其数据，请<br /><br />使用 Drop TABLE 语句。<br />    对于由 FOREIGN KEY 约束引用的表，不能使用 TRUNCATE TABLE，而应使用不带 Where 子句的 <br /><br />Delete 语句。由于 TRUNCATE TABLE 不记录在日志中，所以它不能激活触发器。 <br />    TRUNCATE TABLE 不能用于参与了索引视图的表。<br />    示例<br />        下例删除 authors 表中的所有数据。*/<br />        <br />        TRUNCATE TABLE authors<br />                <br /><br />-- Select INTO 从一个查询的计算结果中创建一个新表。 数据并不返回给客户端，这一点和普通的<br />-- Select 不同。 新表的字段具有和 Select 的输出字段相关联（相同）的名字和数据类型。 <br />        <br />        select * into NewTable<br />            from Uname<br /><br /><br />-- Insert INTO Select<br />        -- 表ABC必须存在<br />        -- 把表Uname里面的字段Username复制到表ABC<br />        Insert INTO ABC Select Username FROM Uname<br /><br />-- 创建临时表<br />        Create TABLE #temp(<br />            UID int identity(1, 1) PRIMARY KEY,<br />            UserName varchar(16),<br />            Pwd varchar(50),<br />            Age smallint,<br />            Sex varchar(6)<br />        )<br />        -- 打开临时表<br />        Select * from #temp<br /><br />-- 存储过程<br />        -- 要创建存储过程的数据库<br />        Use Test<br />        -- 判断要创建的存储过程名是否存在<br />            if Exists(Select name From sysobjects Where name='csp_AddInfo' And <br /><br />type='P')<br />            -- 删除存储过程<br />            Drop Procedure dbo.csp_AddInfo<br />        Go<br />                <br />                <br />        -- 创建存储过程<br />        Create Proc dbo.csp_AddInfo<br />        -- 存储过程参数<br />        @UserName varchar(16),<br />        @Pwd varchar(50),<br />        @Age smallint,<br />        @Sex varchar(6)<br />        AS<br />        -- 存储过程语句体<br />        insert into Uname (UserName,Pwd,Age,Sex)<br />            values (@UserName,@Pwd,@Age,@Sex)<br />        RETURN<br />        -- 执行<br />        GO<br />                <br />        -- 执行存储过程<br />        EXEC csp_AddInfo 'Junn.A','123456',20,'男'</div><br /><span class="bold">4.各种存储过程使用指南</span><br /><br /><div style="FONT-SIZE: 15px">&lt;%@ Language=VBScript %&gt;<br />&lt;%<br /><br />'---开始链接数据库<br />Dim strConnString<br />strConnString = "driver={SQL Server};server=songhp;uid=sa;pwd=;database=XVZDemo"<br />set Conn = Server.CreateObject("ADODB.Connection")<br />Conn.Open strConnstring<br />'---结束链接数据库<br /><br />'---开始为输入参数赋值<br />Dim SelectSql , SelectRs <br />Dim SelectID , SelectName , SelectReturn<br />SelectSql = "Select Max(CompanyID) From Dim_Company"<br />Set SelectRs = Conn.Execute(SelectSql)<br />SelectID = SelectRs(0)<br />'---结束为输入参数赋值<br /><br />Dim TiggerType<br />TiggerType = 3<br /><br />Set Cmd = Server.CreateObject("ADODB.Command") <br />Set Cmd.ActiveConnection = Conn<br />Cmd.CommandType = 4   '---声明此过程为存储过程<br /><br />If TiggerType = 1 then<br /><br />'---开始一个输入参数的存储过程调用<br />Cmd.CommandText = "TransCompany1"<br /><br />Set CmdParam = Cmd.CreateParameter("@TransID",3,1)<br />Cmd.Parameters.Append CmdParam<br />Cmd("@TransID") = SelectID<br />Cmd.Execute<br />'---结束一个输入参数的存储过程调用<br /><br />Elseif TiggerType = 2 then<br /><br />'---开始一个输入参数，一个输出参数的存储过程调用<br />Cmd.CommandText = "TransCompany2"<br /><br />Set CmdParamID = Cmd.CreateParameter("@TransID",3,1)<br />Cmd.Parameters.Append CmdParamID<br />Cmd("@TransID") = SelectID<br />Set CmdParamName = Cmd.CreateParameter("@TransName",202,2,50)<br />Cmd.Parameters.Append CmdParamName<br />Cmd.Execute<br />SelectName = Cmd("@TransName")<br />'---结束一个输入参数，一个输出参数的存储过程调用<br /><br />Elseif TiggerType = 3 then<br /><br />'---开始一个输入参数，一个输出参数，一个返回值的存储过程调用<br />Cmd.CommandText = "TransCompany3"<br />Set CmdParamReturn = Cmd.CreateParameter("Return_Value",3,4)<br />Cmd.Parameters.Append CmdParamReturn<br />Set CmdParamID = Cmd.CreateParameter("@TransID",3,1)<br />Cmd.Parameters.Append CmdParamID<br />Cmd("@TransID") = SelectID<br />Set CmdParamName = Cmd.CreateParameter("@TransName",202,2,50)<br />Cmd.Parameters.Append CmdParamName<br /><br />Cmd.Execute<br />SelectName = Cmd("@TransName")<br />SelectReturn = Cmd("Return_Value")<br />'---结束一个输入参数，一个输出参数，一个返回值的存储过程调用<br /><br /><br />End if<br /><br />Conn.Close<br />Set Conn = Nothing<br />Set Cmd = Nothing<br />Set CmdParamID = Nothing<br />Set CmdParamname = Nothing<br />Set CmdParamReturn = Nothing<br /><br />%&gt;</div><br /><table class="t_msg" cellspacing="0" cellpadding="4" border="0"><tbody><tr><td class="line" style="PADDING-TOP: 10px" valign="top" height="100%"><a title="评分 0" href="http://www.54master.com/bbs/misc.php?action=viewratings&amp;tid=86081&amp;pid=1002805" name="pid1002805"></a><span class="bold">5.ASP中存储过程调用的两种方式及比较</span><br /><br /><div style="FONT-SIZE: 15px">本人用sql server 和asp写了一个简单的留言本，在不断的尝试中发现，分页显示留言的时候，不同的执行方式，时间上的一些差别。<br /><br />下面通过对比来看看几种方式的用时对比。<br /><br />一，使用存储过程分页，这种情况又分为两种方式：<br /><br />第一种，使用command对象，如下：<br /><br />Set Cmd=server.CreateObject("Adodb.Command")<br />Cmd.ActiveConnection=conn<br />Cmd.CommandText="ycuu_gb_getmsg"<br />Cmd.CommandType=4'adCmdStoredProc<br />cmd.prepared=true'<br />set  param=Cmd.CreateParameter("@iPageNo",adInteger,1,2,Page)<br />Cmd.Parameters.Append  param<br />set  param=Cmd.CreateParameter("@iPageSize",adInteger,1,2,PageSizeConst)<br />Cmd.Parameters.Append  param<br />set rs=Cmd.execute<br /><br /><br />第二种，使用connection对象的执行方法直接执行，具体如下：<br /><br />set rs=conn.execute ("execute ycuu_gb_getmsg "&amp;page&amp;", "&amp;pagesizeConst)<br /><br /><br />二，不使用存储过程，直接使用ADODB.RecordSet的功能来分页，具体代码如下：<br /><br />Set rs = Server.CreateObject("ADODB.Recordset")<br />sql = "Select * FROM Guestbook Order By dateandtime Desc"<br />rs.open sql,conn,1,1<br />rs.pagesize = 150'每页显示的留言数量，<br />total = rs.RecordCount<br />mypagesize = rs.pagesize<br />rs.absolutepage = page<br /><br />为了更加明显地显示出速度，我把每页显示的留言数量加大到150(事实上当然不会设置这么大的数值啦)。至于我机器的配置，就省略不说了，因为主要是速度对比。<br /><br />发现，执行的时候时间分别如下：<br /><br />第一种：稳定于0.1953125 秒到0.2109375 秒之间，平均值大概是：0.20秒<br /><br />第二种：稳定于0.1716875 秒到0.1857秒之间，平均值大概是：0.177秒<br /><br />第三种：稳定于0.4375 秒到0.4632秒之间，平均值大概是：0.45秒<br /><br /><br />但是，当读取的记录条数为20的时候，结果如下：<br />发现，执行的时候时间分别如下：<br /><br />第一种：稳定于.0390625  秒到.0546875  秒之间，平均值大概是：0.045秒<br /><br />第二种：稳定于0.046875  秒到.0546875 秒之间，平均值大概是：0.050秒<br /><br />第三种：稳定于.09375 秒到0.1015625 秒之间，平均值大概是：0.97秒<br /><br />在这样看来，似乎conn.execute和command.execute这两种方式似乎差别并不大，<br />而前者的调用方式好像更加简单一点。<br />同时，在这里可以看出分页的存储过程速度确实比recordset的分页速度要快很多。<br /><br />PS：小弟第一次发文，呜呜呜，发现写一篇好的真难，我以后会努力的了。希望大家包涵我这次写得不好。对了，我还想问问各位大侠conn.execute和command.execute这两种方式中那种更加好的，呵呵，因为我在网上找到的都是后者这种方式执行存储过程的。不知道为什么不用前面那种那么简单的。</div></td></tr><tr><td valign="bottom"><br /></td></tr></tbody></table><span class="bold">6.SQL存储过程在.NET数据库中的应用</span><br /><br /><div style="FONT-SIZE: 15px">一．前言： <br /><br />存储过程（Stored Procedure）是一组为了完成特定功能的SQL语句集，经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数（如果该存储过程带有参数）来执行它。存储过程是数据库中的一个重要对象，任何一个设计良好的数据库应用程序都应该用到存储过程。总的来说，存储过程具有以下一些优点： <br /><br />◆存储过程允许标准组件式编程 <br /><br />◆存储过程能够实现较快的执行速度 <br /><br />◆存储过程能够减少网络流量 <br /><br />◆存储过程可被作为一种安全机制来充分利用 <br /><br />本文作者将向大家介绍.NET数据库应用程序中存储过程的应用，以及如何将它与ADO.NET中的SqlDataAdapter对象、DataSet对象等结合使用以提高.NET数据库应用程序的总体性能。 <br /><br />二．系统要求： <br /><br />开发工具：Visual Studio.NET <br /><br />数据库管理系统：SQL Server 2000（其中包含了示例程序所用到的Pubs数据库） <br /><br />三．创建一个简单的存储过程： <br /><br />这里我将向大家介绍如何运用Visual Studio.NET IDE来创建存储过程。运用Visual Studio.NET IDE创建存储过程是非常容易和直观的，你只要在服务器资源管理器中导向到Pubs数据库并展开节点，就会发现包括存储过程在内的各种数据库对象，如图1所示。 <br /><br /><br /><br /><br /><br />在存储过程节点上点击右键便可弹出一个菜单，其中包含了“新建存储过程”的命令。新建一个存储过程后，IDE中的代码编辑窗口便出现如下所示的代码模板： <br /><br /><br /><br />CREATE PROCEDURE dbo.StoredProcedure1 <br />/* <br />( <br />@parameter1 datatype = default value, <br />@parameter2 datatype OUTPUT ) <br />*/ <br />AS <br />/* SET NOCOUNT ON */ <br />RETURN <br /><br /><br /><br />上面的代码模板符合简化的创建存储过程的语法规则，完整的语法规则如下： <br /><br />CREATE PROC [ EDURE ] procedure_name [ ; number ] <br />[ { @parameter data_type } <br />[ VARYING ] [ = default ] [ OUTPUT ] <br />] [ ,...n ] <br />[ WITH <br />{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] <br />[ FOR REPLICATION ] <br />AS sql_statement [ ...n ] <br /><br /><br /><br />限于篇幅，各个参数的含义在此就不多作介绍了，有兴趣的读者可以参考有关SQL Server 2000数据库管理系统的资料。 <br /><br />下面我对该代码模板中的各个语法成分略作介绍。CREATE PROCEDURE声明创建一个存储过程，后面跟着该存储过程的名称。“/*……*/”中的成分是该存储过程的参数，可包括输入参数和输出参数。AS关键字后面的内容是该存储过程的主体部分，其中是任何数量和类型的包含在存储过程中的SQL语句。RETURN关键字表明存储过程结束并能返回整型状态值给调用者。下面我们就来创建一个简单的不带参数的存储过程并运用之： <br /><br />CREATE PROCEDURE dbo.up_GetPublisherInfo <br />AS <br />SELECT pub_id, pub_name, city, state, country <br />FROM publishers <br />RETURN <br /><br /><br /><br /><br /><br /><br />创建以上存储过程后，保存之。保存完毕，与该存储过程相对应的节点就会出现在服务器资源管理器中。同时请注意代码编辑窗口中的CREATE关键字变为ALTER关键字了，该关键字是用于更改任何现有的存储过程的。要运行上述存储过程，只要点击其节点并在右键弹出菜单中选择“运行存储过程”，运行的结果图示如下： <br /><br /><br /><br />四．创建一个带参数的存储过程： <br /><br />以上我们创建了一个简单的不带参数的存储过程，而在实际的应用中往往会用到很多带有参数的存储过程。带有参数的存储过程一般是用于更新数据或是插入数据的。下面我们可以运用同样的操作方法创建一个带参数的存储过程： <br /><br /><br /><br />CREATE PROCEDURE dbo.up_UpdatePublisherInfo <br />( <br />@pub_id char (4), <br />@pub_name varchar (40), <br />@city varchar (20), <br />@state char (2), <br />@country varchar (30) <br />) <br />AS <br />UPDATE publishers <br />SET pub_name = @pub_name, city = @city, state = @state, <br />　country = @country <br />WHERE ( pub_id = @pub_id ) <br />RETURN <br /><br /><br /><br /><br />在上面的创建存储过程的代码中，我们通过在名称前添加一个“@”标志来声明存储过程的局部变量－参数，同时还声明了各个参数的类型，确定了各个参数的方向值，也即表明该参数是输入型的还是输出型的或者是输入输出型的或者是返回值型的。用户通过相应的存储过程名称以及正确有效的参数便可调用该存储过程了。还有，你可以通过运用OUTPUT关键字在参数中添加输出型的参数，具体方法请参考上面的语法规则。输出型的参数能返回给调用者相关的信息。 <br /><br />上面的存储过程能更新publishers表中相应出版商的信息。你可以通过点击该存储过程的节点，在右键弹出菜单中选择“运行存储过程”来执行它。一旦执行，IDE中便弹出一个输入出版商信息的对话框（如图3所示）。在该对话框中填入正确有效的更新信息，注意pub_id的值在原来的表中必须存在，然后点击“确定”按钮便可更新数据了。</div><br /><span class="bold">7.使用SQL存储过程要特别注意的问题</span><br /><br /><div style="FONT-SIZE: 15px">存储过程是一个运行于SQL数据库之中最核心的事务,它通过长驻内存的形式,进行读取\处理\写入最为频繁处理的数据. <br />    ASP虽然在微软的ASPX的侵袭下，仍旧是中小企业继续在用的一种网页语言，但是当要读取海量数据的时候,如果仍旧使用普通的SQL进行读取运行与写入,将导致系统资源的严重浪费，所以我们在ASP中使用存储过程,以提高数据的存取速度,同时通过SQL核心的获取数据的方法,可以有效的减少垃圾数据(不被立即使用,而且也不备较短的时间里被使用的数据)操作. <br />    在ASP中使用存储过程也是相当的容易,例如以下一个通过SQL存储过程进行分页的方法: <br />存储过程: <br />CREATE procedure p_splitpage    <br />@sql nvarchar(4000), --要执行的sql语句 <br />@page int=1,    --要显示的页码 <br />@pageSize int,  --每页的大小 <br />@pageCount int=0 out, --总页数 <br />@recordCount int=0 out --总记录数 <br />as <br />set nocount on <br />declare @p1 int <br />exec sp_cursoropen @p1 output,@sql,@scrollopt=1,@ccopt=1,@rowcount=@pagecount output <br />set @recordCount = @pageCount <br />select @pagecount=ceiling(1.0*@pagecount/@pagesize) <br />,@page=(@page-1)*@pagesize+1 <br />exec sp_cursorfetch @p1,16,@page,@pagesize  <br />exec sp_cursorclose @p1 <br />GO <br />ASP页面的内容 <br />sql = "Select id, c_s_name from tabNews where deleted&lt;&gt;1 Order By id Desc" <br />page = cint(page_get) <br />if page_post&lt;&gt;""then <br />page = cint(page_post) <br />end if <br />if not page &gt; 0 then  <br />page = 1 <br />end if <br />pagesize=20’每页的条数 <br />set cmd = server.CreateObject("adodb.command") <br />cmd.ActiveConnection = conn <br />cmd.CommandType = 4 <br />cmd.CommandText = "p_SplitPage" <br />cmd.Parameters.Append cmd.CreateParameter("@sql",8,1, 4000, sql) <br />cmd.Parameters.Append cmd.CreateParameter("@page",4,1, 4, page) <br />cmd.Parameters.Append cmd.CreateParameter("@pageSize",4,1, 4, pageSize) <br />cmd.Parameters.Append cmd.CreateParameter("@pageCount",4,2, 4, pageCount) <br />cmd.Parameters.Append cmd.CreateParameter("@recordCount",4,2, 4, recordCount) <br />set rs = cmd.Execute <br />set rs = rs.NextRecordSet <br />pageCount = cmd.Parameters("@pageCount").value <br />recordCount = cmd.Parameters("@recordCount").value <br />if pageCount = 0 then pageCount = 1 <br />if page&gt;pageCount then  <br />response.Redirect("?page="&amp;pageCount)  <br />end if <br />set rs = cmd.Execute <br />    我们如此就可以实现对数据的读取并可以进行有效的分页,但是我们往往会发现一个问题,如果我们构造的SQL语句如果使用的是select * from tab ...的话，就经常出现无法读取数据的错误,或者是读取出来,但是有的数据无法显示的错误，经过仔细的检查发现,如果是排列在SQL语句的前列的数据可以被读取,而如果不按照SQL读取出来的字段进行顺序读取,就会出现数据丢失的情况,所以唯一的途径就是进行顺序读取.如: <br />    对于select id, newsTitle, newsContent from tabNews where ...的SQL语句,就应当将所有的数据读取到变量上来，并且要求是按照SQL语句的顺序进行读取，然后这些数据就可以自由的使用了. <br />    id = rs("id") <br />    newsTitle = rs("newsTitle") <br />    ... <br />    分析出现这个的原因是:SQL数据库在构造虚拟表的时候就是以一种先进先出的原则,把所有的数据排列在一个内存段之中,通过顺序的读取,将数据逐一的读取,而如果跳过某个具体的字段获取下一个字段的信息,系统就会将原来的那个字段的信息丢失,以释放内存,这是出于系统构造的简单性和系统的内存最低化的要求,所以这样也保证了有限的内存资源得到最充分的发挥,这也是为什么存储过程比普通的SQL要快的原因.</div><br /></td></tr></tbody></table></div>
<img src ="http://www.blogjava.net/zqli/aggbug/92326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-08 11:08 <a href="http://www.blogjava.net/zqli/archive/2007/01/08/92326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]SQL2000存储过程的基础</title><link>http://www.blogjava.net/zqli/archive/2007/01/08/92324.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 08 Jan 2007 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/08/92324.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/92324.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/08/92324.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/92324.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/92324.html</trackback:ping><description><![CDATA[存储过程的概念<br />       SQL Server提供了一种方法，它可以将一些固定的操作集中起来由SQL Server数据库服务器来完成，以实现某个任务，这种方法就是存储过程。<br />       存储过程是SQL语句和可选控制流语句的预编译集合，存储在数据库中，可由应用程序通过一个调用执行，而且允许用户声明变量、有条件执行以及其他强大的编程功能。<br />       在SQL Server中存储过程分为两类：即系统提供的存储过程和用户自定义的存储过程。<br /><br />       可以出于任何使用SQL语句的目的来使用存储过程，它具有以下优点：<br />       可以在单个存储过程中执行一系列SQL语句。<br />       可以从自己的存储过程内引用其他存储过程，这可以简化一系列复杂语句。<br />       存储过程在创建时即在服务器上进行编译，所以执行起来比单个SQL语句快，而且减少网络通信的负担。<br />       安全性更高。<br />创建存储过程 <br /><br />       在SQL Server中，可以使用三种方法创建存储过程 ：<br />         ①使用创建存储过程向导创建存储过程。<br />         ②利用SQL Server 企业管理器创建存储过程。<br />         ③使用Transact-SQL语句中的CREATE PROCEDURE命令创建存储过程。<br /><br />下面介绍使用Transact-SQL语句中的CREATE PROCEDURE命令创建存储过程<br />    创建存储过程前，应该考虑下列几个事项： <br />     ①不能将 CREATE PROCEDURE 语句与其它 SQL 语句组合到单个批处理中。<br />     ②存储过程可以嵌套使用，嵌套的最大深度不能超过32层。<br />     ③创建存储过程的权限默认属于数据库所有者，该所有者可将此权限授予其他用户。<br />     ④存储过程是数据库对象，其名称必须遵守标识符规则。<br />     ⑤只能在当前数据库中创建存储过程。<br />     ⑥ 一个存储过程的最大尺寸为128M。<br /><br />使用CREATE PROCEDURE创建存储过程的语法形式如下：<br /><br /><div class="msgheader">QUOTE:</div><div class="msgborder">CREATE PROC[EDURE]procedure_name[;number][;number]<br />[{@parameter data_type}<br />[VARYING][=default][OUTPUT]<br />][,...n] WITH   <br />{RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]<br />[FOR REPLICATION] <br />AS sql_statement [ ...n ] <br /><div style="FONT-SIZE: 14px; LINE-HEIGHT: 160%">用CREATE PROCEDURE创建存储过程的语法参数的意义如下： <br /><br />procedure_name：用于指定要创建的存储过程的名称。 <br />number：该参数是可选的整数，它用来对同名的存储过程分组，以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。 <br />@parameter：过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。 <br />data_type：用于指定参数的数据类型。 <br />VARYING：用于指定作为输出OUTPUT参数支持的结果集。 <br />Default：用于指定参数的默认值。 <br />OUTPUT：表明该参数是一个返回参数。 <br /><br /><br />例如：下面创建一个 简单的存储过程productinfo，用于检索产品信息。<br />USE Northwind<br />if exists(select name from sysobjects<br />          where name='productinfo' and type = 'p')<br />   drop procedure productinfo<br />GO<br /><br />create  procedure productinfo<br />as<br />select * from products<br />GO<br />通过下述sql语句执行该存储过程：execute productinfo <br />即可检索到产品信息。<br /><div style="FONT-SIZE: 14px; LINE-HEIGHT: 160%">执行存储过程 <br /><br />直接执行存储过程可以使用EXECUTE命令来执行，其语法形式如下：<br />[[EXEC[UTE]]<br />   {       [@return_status=]<br />          {procedure_name[;number]|@procedure_name_var}            [[@parameter=]{value|@variable[OUTPUT]|[DEFAULT]}      <br />      [,...n] <br />[ WITH RECOMPILE ] <br /><br /><br /><br />使用 EXECUTE 命令传递单个参数，它执行 showind 存储过程，以 titles 为参数值。showind 存储过程需要参数 (@tabname)，它是一个表的名称。其程序清单如下：<br />    EXEC showind titles<br />当然，在执行过程中变量可以显式命名：<br />    EXEC showind @tabname = titles<br />如果这是 isql 脚本或批处理中第一个语句，则 EXEC 语句可以省略：<br />    showind titles或者showind @tabname = titles<br /><br /><br /><br />下面的例子使用了默认参数<br />USE Northwind<br />GO<br />CREATE PROCEDURE insert_Products_1<br />        ( @SupplierID_2         int,<br />         @CategoryID_3         int,<br />                 @ProductName_1 nvarchar(40)='无')<br />AS INSERT INTO Products<br />         (ProductName,SupplierID,CategoryID) <br />VALUES <br />        (@ProductName_1,@SupplierID_2,@CategoryID_3)<br />GO<br />exec insert_Products_1 1,1<br />Select * from Products where SupplierID=1 and CategoryID=1<br />GO<br /><br /><br />下面的例子使用了返回参数<br />USE Northwind<br />GO<br />CREATE PROCEDURE query_products<br />(      @SupplierID_1 int,<br />        @ProductName_2 nvarchar(40) output)<br />AS <br />select @ProductName_2 = ProductName   from products<br />where SupplierID = @SupplierID_1<br /><br />执行该存储过程来查询SupplierID为1的产品名：<br />declare @product nvarchar(40)<br />exec query_products 1,@product output<br />select '产品名'= @product<br />go<br /><br /><div style="FONT-SIZE: 14px; LINE-HEIGHT: 160%">查看存储过程 <br />   存储过程被创建之后，它的名字就存储在系统表sysobjects中，它的源代码存放在系统表syscomments中。可以使用使用企业管理器或系统存储过程来查看用户创建的存储过程。<br /><br /><br />使用企业管理器查看用户创建的存储过程 <br /><br />   在企业管理器中，打开指定的服务器和数据库项，选择要创建存储过程的数据库，单击存储过程文件夹，此时在右边的页框中显示该数据库的所有存储过程。用右键单击要查看的存储过程，从弹出的快捷菜单中选择属性选项，此时便可以看到存储过程的源代码。 <br /><br /><br />使用系统存储过程来查看用户创建的存储过程 <br /><br />可供使用的系统存储过程及其语法形式如下：<br />sp_help：用于显示存储过程的参数及其数据类型<br />   sp_help [[@objname=] name]<br />参数name为要查看的存储过程的名称。 <br />   sp_helptext：用于显示存储过程的源代码 <br />   sp_helptext [[@objname=] name]<br />参数name为要查看的存储过程的名称。<br />   sp_depends：用于显示和存储过程相关的数据库对象<br />   sp_depends [@objname=]’object’<br />参数object为要查看依赖关系的存储过程的名称。<br />   sp_stored_procedures：用于返回当前数据库中的存储过程列表<br /><br /><br /><br /><br /><br />修改存储过程<br /><br /><br />    存储过程可以根据用户的要求或者基表定义的改变而改变。使用ALTER PROCEDURE语句可以更改先前通过执行 CREATE PROCEDURE 语句创建的过程，但不会更改权限，也不影响相关的存储过程或触发器。其语法形式如下：<br />   ALTERPROC[EDURE]procedure_name[;number]<br />[{@parameterdata_type}<br />[VARYING][=default][OUTPUT]][,...n] [WITH<br />   {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]<br />[FOR REPLICATION] <br />AS   <br />sql_statement [ ...n ]<br /><br /><div style="FONT-SIZE: 14px; LINE-HEIGHT: 160%">重命名和删除存储过程<br /><br />1. 重命名存储过程<br />  修改存储过程的名称可以使用系统存储过程sp_rename，其语法形式如下：<br />      sp_rename  原存储过程名称，新存储过程名称<br />      另外，通过企业管理器也可以修改存储过程的名称。 <br /><br /><br /><br />删除存储过程<br /><br /><br />   删除存储过程可以使用DROP命令，DROP命令可以将一个或者多个存储过程或者存储过程组从当前数据库中删除，其语法形式如下：<br />       drop procedure {procedure} [,…n]<br />当然，利用企业管理器也可以很方便地删除存储过程。 <br /><br /><br /><br />存储过程的重新编译 <br /><br />   在我们使用了一次存储过程后，可能会因为某些原因，必须向表中新增加数据列或者为表新添加索引，从而改变了数据库的逻辑结构。这时，需要对存储过程进行重新编译，SQL Server提供三种重新编译存储过程的方法 ：<br />    1、在建立存储过程时设定重新编译<br />       语法格式：CREATE  PROCEDURE   procedure_name    WITH   RECOMPILE    AS   sql_statement<br />     2、在执行存储过程时设定重编译 <br />       语法格式： EXECUTE  procedure_name  WITH  RECOMPILE<br />    3、通过使用系统存储过程设定重编译 <br />        语法格式为：  EXEC  sp_recompile  OBJECT<br /><br /><div style="FONT-SIZE: 14px; LINE-HEIGHT: 160%">系统存储过程与扩展存储过程 <br /><br />1.系统存储过程 <br />           系统存储过程存储在master数据库中，并以sp_为前缀，主要用来从系统表中获取信息，为系统管理员管理SQL Server提供帮助，为用户查看数据库对象提供方便。比如用来查看数据库对象信息的系统存储过程sp_help、显示存储过程和其它对象的文本的存储过程sp_helptext等。<br /><br /><br />2.扩展存储过程：<br />          扩展存储过程以xp_为前缀，它是关系数据库引擎的开放式数据服务层的一部分，其可以使用户在动态链接库(DLL)文件所包含的函数中实现逻辑，从而扩展了Transact-SQL的功能，并且可以象调用Transact-SQL过程那样从Transact-SQL语句调用这些函数。 <br />      例:  利用扩展存储过程xp_cmdshell为一个操作系统外壳执行指定命令串，并作为文本返回任何输出。<br />      执行代码：<br />         use master<br />          exec xp_cmdshell 'dir *.exe'   <br />       执行结果返回系统目录下的文件内容文本信息。<br /><br />最后给大家举一个例子：<br /><br /><div class="msgheader">QUOTE:</div><div class="msgborder">/**<br />1、        在Northwind数据库中，创建一个带查询参数的存储过程，<br />要求在输入一个定购金额总额＠total时，查询超出该值的所<br />有产品的相关信息，包括产品名称和供应商名称、单位数量、<br />单价、以及该产品的定购金额总额，并通过一个输出参数返回<br />满足查询条件的产品数<br />**/<br /><br /><br />IF exists (select * from SysObjects where name='more_than_total' and type='p')<br />   drop procedure more_than_total<br />go<br />CREATE PROCEDURE More_Than_Total<br />        @total money = 0<br />AS<br />Declare @amount smallint<br />BEGIN<br />        select distinct<br />           P.productName,<br />           S.contactName,<br />           P.UnitPrice<br />           <br />    from Products P inner join [order Details] O <br />         on p.productID=o.productID inner join suppliers s <br />         on p.supplierID=s.SupplierID<br />    where O.productID in<br />    (select productID <br />     from   [order Details] <br />     group by productId<br />     having sum(quantity*unitprice)&gt;@total<br />    )<br />END<br />GO</div></div></div></div></div></div></div><img src ="http://www.blogjava.net/zqli/aggbug/92324.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-08 11:01 <a href="http://www.blogjava.net/zqli/archive/2007/01/08/92324.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]存储过程教程（二）</title><link>http://www.blogjava.net/zqli/archive/2007/01/08/92321.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 08 Jan 2007 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/08/92321.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/92321.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/08/92321.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/92321.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/92321.html</trackback:ping><description><![CDATA[
		<p>在MS SQL Server 2000 中，创建一个存储过程有两种方法：一种是使用Transaction-SQL 命令Create Procedure， 另一种是使用图形化管理工具Enterprise Manager。 用Transaction- SQL 创建存储过程是一种较为快速的方法，但对于初学者，使用Enterprise Manager 更易理解，更为简单。<br />当创建存储过程时，需要确定存储过程的三个组成部分； 
</p>
		<p> </p>
		<ul>
				<li>所有的输入参数以及传给调用者的输出参数。 
</li>
				<li>被执行的针对数据库的操作语句，包括调用其它存储过程的语句； 
</li>
				<li>返回给调用者的状态值，以指明调用是成功还是失败。 </li>
		</ul>
		<span class="style2">12.2.1 使用Enterprise Manager 创建存储过程</span>
		<br />按照下述步骤用Enterprise Manager 创建一个存储过程： 
<p> </p><ul><li>启动Enterprise Manager， 登录到要使用的服务器。 
</li><li>选择要创建存储过程的数据库，在左窗格中单击Stored Procedure 文件夹，此时在右窗格中显示该数据库的所有存储过程，如图12-1 所示。 
</li><li>右击Stored Procedure 文件夹，在弹出菜单中选择New Stored Procedure, 此时打开创建存储过程对话框，如图12-2 所示。<img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/284.gif" width="521" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><br /><br /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/285.gif" width="399" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /></li><li>输入存储过程正文。 
</li><li>单击Check Syntax， 检查语法是否正确。 
</li><li>单击OK， 保存。 
</li><li>在右窗格中，右击该存储过程，在弹出菜单中选择All task, 选择ManagePermissions， 设置权限，如图12-3 所示。<br /><p> </p><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/286.gif" width="417" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /></li></ul><span class="style2">12.2.2 用CREATE PROCEDURE 命令创建存储过程</span><br />通过运用Create Procedure 命令能够创建存储过程，在创建存储过程之前，应该考虑到以下几个方面： 
<p> </p><ul><li>在一个批处理中，Create Procedure 语句不能与其它SQL 语句合并在一起； 
</li><li>数据库所有者具有默认的创建存储过程的权限，它可把该权限传递给其它的用户； 
</li><li>存储过程作为数据库对象其命名必须符合命名规则； 
</li><li>只能在当前数据库中创建属于当前数据库的存储过程。 </li></ul>用Create Procedure 创建存储过程的语法规则如下：<br />CREATE PROC [ EDURE ] procedure_name [ ; number ]<br />[ { @parameter data_type }<br />[ VARYING ] [ = default ] [ OUTPUT ]<br />] [ ,...n ]<br />[ WITH<br />{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]<br />[ FOR REPLICATION ]<br />AS sql_statement [ ...n ]<br /><br />各参数的含义如下：<br /><p> </p><ul><li>procedure_name<br />是要创建的存储过程的名字，它后面跟一个可选项number， 它是一个整数，用来区别一组同名的存储过程。存储过程的命名必须符合命名规则，在一个数据库中或对其所有者而言，存储过程的名字必须惟一。 
</li><li>@parameter<br />是存储过程的参数。在Create Procedure 语句中，可以声明一个或多个参数。当调用该存储过程时，用户必须给出所有的参数值，除非定义了参数的缺省值。若参数的形式以 @parameter=value 出现，则参数的次序可以不同，否则用户给出的参数值必须与参数列表中参数的顺序保持一致。若某一参数以@parameter=value 形式给出，那么其它参数也必须以该形式给出。一个存储过程至多有1024 个参数。 
</li><li>Data_type<br />是参数的数据类型。在存储过程中，所有的数据类型包括text 和image 都可被用作参数。但是，游标cursor 数据类型只能被用作OUTPUT 参数。当定义游标数据类型时，也必须对VARING 和OUTPUT 关键字进行定义。对可能是游标型数据类型的OUTPUT 参数而言，参数的最大数目没有限制。 
</li><li>VARYING<br />指定由OUTPUT 参数支持的结果集，仅应用于游标型参数。 
</li><li>Default<br />是指参数的缺省值。如果定义了缺省值，那么即使不给出参数值，则该存储过程仍能被调用。缺省值必须是常数，或者是空值。 
</li><li>OUTPUT<br />表明该参数是一个返回参数。用OUTPUT 参数可以向调用者返回信息。Text 类型参数不能用作OUTPUT 参数。 
</li><li>RECOMPILE<br />指明SQL Server 并不保存该存储过程的执行计划，该存储过程每执行一次都又要重新编译。 
</li><li>ENCRYPTION<br />表明SQL Server 加密了syscomments 表，该表的text 字段是包含有Create procedure语句的存储过程文本，使用该关键字无法通过查看syscomments 表来查看存储过程内容。 
</li><li>FOR REPLICATION<br />选项指明了为复制创建的存储过程不能在订购服务器上执行，只有在创建过滤存储过程时（仅当进行数据复制时过滤存储过程才被执行），才使用该选项。FOR REPLICATION与WITH RECOMPILE 选项是互不兼容的。 
</li><li>AS<br />指明该存储过程将要执行的动作。 
</li><li>Sql_statement<br />是任何数量和类型的包含在存储过程中的SQL 语句。 </li></ul><p> </p>另外应该指出，一个存储过程的最大尺寸为128M， 用户定义的存储过程必须创建在当前数据库中。<br /> 下面将给出几个例子，用来详细介绍如何创建包含有各种保留字的存储过程。<br /><br /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/287.gif" width="402" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/288.gif" width="352" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><br /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/289.gif" width="327" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><br /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/290.gif" width="519" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><br />    <img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.studynew.com/Files/Mssql/291.gif" width="183" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /><br /><img src ="http://www.blogjava.net/zqli/aggbug/92321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-08 10:52 <a href="http://www.blogjava.net/zqli/archive/2007/01/08/92321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]存储过程教程（一）</title><link>http://www.blogjava.net/zqli/archive/2007/01/08/92319.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Mon, 08 Jan 2007 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2007/01/08/92319.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/92319.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2007/01/08/92319.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/92319.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/92319.html</trackback:ping><description><![CDATA[在大型数据库系统中，存储过程和触发器具有很重要的作用。无论是存储过程还是触发器，都是SQL 语句和流程控制语句的集合。就本质而言，触发器也是一种存储过程。存储过程在运算时生成执行方式，所以，以后对其再运行时其执行速度很快。SQL Server 2000 不仅提供了用户自定义存储过程的功能，而且也提供了许多可作为工具使用的系统存储过程。<br /><br /><span class="style2">12.1.1 存储过程的概念</span><br />存储过程（Stored Procedure）是一组为了完成特定功能的SQL 语句集，经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数（如果该存储过程带有参数）来执行它。<br /><br />    在SQL Server 的系列版本中存储过程分为两类：系统提供的存储过程和用户自定义存储过程。系统过程主要存储在master 数据库中并以sp_为前缀，并且系统存储过程主要是从系统表中获取信息，从而为系统管理员管理SQL Server 提供支持。通过系统存储过程，MS SQL Server 中的许多管理性或信息性的活动（如了解数据库对象、数据库信息）都可以被顺利有效地完成。尽管这些系统存储过程被放在master 数据库中，但是仍可以在其它数据库中对其进行调用，在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时，一些系统存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建并能完成某一特定功能（如查询用户所需数据信息）的存储过程。在本章中所涉及到的存储过程主要是指用户自定义存储过程。<br /><br /><span class="style2">12.1.2 存储过程的优点</span><br />    当利用MS SQL Server 创建一个应用程序时，Transaction-SQL 是一种主要的编程语言。若运用Transaction-SQL 来进行编程，有两种方法。其一是，在本地存储Transaction- SQL 程序，并创建应用程序向SQL Server 发送命令来对结果进行处理。其二是，可以把部分用Transaction-SQL 编写的程序作为存储过程存储在SQL Server 中，并创建应用程序来调用存储过程，对数据结果进行处理存储过程能够通过接收参数向调用者返回结果集，结果集的格式由调用者确定；返回状态值给调用者，指明调用是成功或是失败；包括针对数据库的操作语句，并且可以在一个存储过程中调用另一存储过程。 <br /><br />    我们通常更偏爱于使用第二种方法，即在SQL Server 中使用存储过程而不是在客户计算机上调用Transaction-SQL 编写的一段程序，原因在于存储过程具有以下优点：<br /><br />（1） 存储过程允许标准组件式编程<br />存储过程在被创建以后可以在程序中被多次调用，而不必重新编写该存储过程的SQL 语句。而且数据库专业人员可随时对存储过程进行修改，但对应用程序源代码毫无影响（因为应用程序源代码只包含存储过程的调用语句），从而极大地提高了程序的可移植性。<br /><br />（2） 存储过程能够实现较快的执行速度<br />如果某一操作包含大量的Transaction-SQL 代码或分别被多次执行，那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的，在首次运行一个存储过程时，查询优化器对其进行分析、优化，并给出最终被存在系统表中的执行计划。而批处理的Transaction- SQL 语句在每次运行时都要进行编译和优化，因此速度相对要慢一些。<br /><br />（3） 存储过程能够减少网络流量<br />对于同一个针对数据数据库对象的操作（如查询、修改），如果这一操作所涉及到的 Transaction-SQL 语句被组织成一存储过程，那么当在客户计算机上调用该存储过程时，网络中传送的只是该调用语句，否则将是多条SQL 语句，从而大大增加了网络流量，降低网络负载。<br /><br />（4） 存储过程可被作为一种安全机制来充分利用<br />系统管理员通过对执行某一存储过程的权限进行限制，从而能够实现对相应的数据访问权限的限制，避免非授权用户对数据的访问，保证数据的安全。（我们将在14 章“SQLServer 的用户和安全性管理”中对存储过程的这一应用作更为清晰的介绍）<br /><br /><span class="style2">注意：</span>存储过程虽然既有参数又有返回值，但是它与函数不同。存储过程的返回值只是指明执行是否成功，并且它不能像函数那样被直接调用，也就是在调用存储过程时，在存储过程名字前一定要有EXEC保留字<br /><img src ="http://www.blogjava.net/zqli/aggbug/92319.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2007-01-08 10:50 <a href="http://www.blogjava.net/zqli/archive/2007/01/08/92319.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]一些Select检索高级用法</title><link>http://www.blogjava.net/zqli/archive/2006/12/31/91226.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Sun, 31 Dec 2006 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2006/12/31/91226.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/91226.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2006/12/31/91226.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/91226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/91226.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#0000ff">
						<span style="COLOR: #000000">SQL五个集合函数：</span>
						<span style="COLOR: #ff00ff">SUM</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #ff00ff">AVG</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #ff00ff">COUNT</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #ff00ff">MAX</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #ff00ff">MIN</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　通配符的一些用法：(关键字：</span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">%</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">[]</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">-</span>
						<span style="COLOR: #000000">)<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">[A-M]%</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　这样可以选择出column字段中首字母在A</span>
						<span style="COLOR: #808080">-</span>
						<span style="COLOR: #000000">M之间的记录<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">[ABC]%</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　这样可以选择出column字段中首字母是A或者B或者C的记录<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">[A-CG]%</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　这样可以选择出column字段中首字母在A</span>
						<span style="COLOR: #808080">-</span>
						<span style="COLOR: #000000">C之间的或者是G的记录<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">[^C]%</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　这样可以选择出column字段中首字母不是C的记录<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" /><br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　脱字符（关键字：</span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> _）<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　通过使用下滑线字符（_），可以匹配任意单个字符<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">M_crosoft</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　匹配特殊字符：（</span>
						<span style="COLOR: #ff0000">[</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #ff0000">]</span>
						<span style="COLOR: #000000"> _ </span>
						<span style="COLOR: #808080">-</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">%</span>
						<span style="COLOR: #000000">）<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　把他们都放到</span>
						<span style="COLOR: #ff0000">[]</span>
						<span style="COLOR: #000000">中就行了，比如：<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #808080">like</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">%[%]%</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　匹配发音（关键字：</span>
						<span style="COLOR: #ff00ff">SOUNDEX</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff00ff">DIFFERENCE</span>
						<span style="COLOR: #000000">）<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　如果不知道一个名字确切的发音，但是又多少知道一点，可以考虑使用SOUNDEX DIFFERENCE函数。<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #808080">*</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">from</span>
						<span style="COLOR: #000000"> tablename </span>
						<span style="COLOR: #0000ff">where</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #ff00ff">DIFFERENCE</span>
						<span style="COLOR: #000000">(column1,</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">Laofei</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #808080">&gt;</span>
						<span style="FONT-WEIGHT: bold; COLOR: #800000">3</span>
						<span style="COLOR: #000000">)<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　DIFFERENCE返回0</span>
						<span style="COLOR: #808080">-</span>
						<span style="COLOR: #000000">4之间的数字，4是非常接近，0是差异非常大<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　要深入了解DIFFERENCE函数的工作原理，使用SOUNDEX函数返回DIFFERENCE函数所使用的音标码<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">select</span>
						<span style="COLOR: #000000"> column1 </span>
						<span style="COLOR: #0000ff">as</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">column</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #ff00ff">SOUNDEX</span>
						<span style="COLOR: #000000">(column1) </span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #ff0000">sound like</span>
						<span style="COLOR: #ff0000">'</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />
								<br />
								<img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　注意：<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　DIFFERENCE函数比较两个字符串的第一个字母和所有的辅音字母，该函数忽略任何元音字母（包括Y）,除非元音字母是该字符串的第一个字母。<br /><img alt="" src="file:///C:/Documents%20and%20Settings/Administrator/桌面/一些Select检索高级用法%20-%20!Java%20-%20CSDNBlog.files/None.gif" align="top" />　　使用这两个函数在where中执行效果并不好，所以尽量少使用。</span>
						<font color="#000000"> </font>
						<br />
				</font>
		</p>
<img src ="http://www.blogjava.net/zqli/aggbug/91226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2006-12-31 21:50 <a href="http://www.blogjava.net/zqli/archive/2006/12/31/91226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]提高查询速度方法总结 </title><link>http://www.blogjava.net/zqli/archive/2006/12/08/86391.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Fri, 08 Dec 2006 08:35:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2006/12/08/86391.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/86391.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2006/12/08/86391.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/86391.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/86391.html</trackback:ping><description><![CDATA[
		<p>这个帖子主要总结提高查询速度的方法，涉及到减少连接数据库次数、建立索引、优化语句等方面。</p>
		<p>关于索引，推荐转载的这篇文章<br /><a href="http://blog.csdn.net/dutguoyi/archive/2006/01/10/575617.aspx">http://blog.csdn.net/dutguoyi/archive/2006/01/10/575617.aspx</a></p>
		<p>改善SQL语句的效率<br /><a href="http://community.csdn.net/Expert/topic/5087/5087396.xml?temp=.345669">http://community.csdn.net/Expert/topic/5087/5087396.xml?temp=.345669</a><br />数据量很大怎样加快索检速度<br /><a href="http://community.csdn.net/Expert/topic/5058/5058320.xml?temp=.1229517">http://community.csdn.net/Expert/topic/5058/5058320.xml?temp=.1229517</a><br />索引建立方法的区别<br /><a href="http://community.csdn.net/Expert/topic/5068/5068154.xml?temp=.3010218">http://community.csdn.net/Expert/topic/5068/5068154.xml?temp=.3010218</a><br />频繁插入删除数据需要更新索引<br /><a href="http://community.csdn.net/Expert/topic/4937/4937910.xml?temp=.8428614">http://community.csdn.net/Expert/topic/4937/4937910.xml?temp=.8428614</a><br />测试了一下sql server 2005 全文检索<br /><a href="http://community.csdn.net/Expert/topic/4878/4878430.xml?temp=.6049311">http://community.csdn.net/Expert/topic/4878/4878430.xml?temp=.6049311</a></p>
		<p>其他关于效率的高频问题</p>
		<p>判断一个表的数据不在另一个表中最优秀方法？<br /><a href="http://community.csdn.net/Expert/topic/5038/5038742.xml?temp=.4704553">http://community.csdn.net/Expert/topic/5038/5038742.xml?temp=.4704553</a><br />删除千万级表中重复记录的办法<br /><a href="http://community.csdn.net/Expert/topic/5089/5089261.xml?temp=.7907068">http://community.csdn.net/Expert/topic/5089/5089261.xml?temp=.7907068</a></p>
		<p>数据库数据查询变得不正常类型问题</p>
		<p>大数据量，稳定运行一段时候以后无法得到查询结果。<br /><a href="http://community.csdn.net/Expert/topic/4810/4810464.xml?temp=9.014529E-02">http://community.csdn.net/Expert/topic/4810/4810464.xml?temp=9.014529E-02</a><br /></p>
<img src ="http://www.blogjava.net/zqli/aggbug/86391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2006-12-08 16:35 <a href="http://www.blogjava.net/zqli/archive/2006/12/08/86391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>存储技术－NAS与SAN</title><link>http://www.blogjava.net/zqli/archive/2006/10/29/77924.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Sun, 29 Oct 2006 12:18:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2006/10/29/77924.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/77924.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2006/10/29/77924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/77924.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/77924.html</trackback:ping><description><![CDATA[
		<p align="center">NAS与SAN</p>
		<p>    信息时代是一个数据为王的时代。信息在企业的决策、经营和管理中发挥的重要作用，不但改变了企业评估信息的方式，使各企业把信息作为一种超越其竞争对手的战略资产，而且也正在迅速改变企业的商业运作模式，从发展迅猛的中小型公司到拥有广泛资源的全球跨国企业。但是信息时代的来临也给企业带来了新问题--产生海量数据、存储海量数据、访问海量数据。这是因为在互联网商业化后，企业希望通过互联网为客户提供全年无休的服务，同时企业也希望借由互联网汇集、分析一切与客户相关的信息，借此为客户提供更好的服务。此外，数据信息存储设备的容量不断增加，价格却不断下滑，造成了基于Internet和Intranet的电子商务、企业资源计划（ERP）、数据仓库、联机事务处理（OLTP）等数据密集型应用炙手可热，网页数据信息，视频图像信息和静态数据等成为了企业的关键性业务。数据的爆炸性增长不仅要求企业信息系统能存储日益增涨的数据，合理地管理数据，更重要的是，企业信息系统能保证需要数据的人能迅速得到相关数据。这给企业信息数据的存储、共享和安全提出了更高的要求，企业信息数据的存储成为了企业的核心任务。 <br />    在传统的企业数据信息存储架构上，信息存储装置大都是个别依附在服务器后面的信息孤岛，彼此间无法作有效的联结。若要存取某台服务器后面信息存储设备上的信息，必须通过区域网络及该台服务器，这样既占据区域网络的带宽，又浪费服务器CPU的资源。如果要在不同应用程序之间共享数据，还必须从独立的信息存储设备中，将数据复制到另外的信息存储设备。这造成了数据使用上的时间差。从商业角度来看，时间差使得做决策的人，必须依照不正确和不即时的信息作决策。当然，管理分散在各地的数据储存系统，也是一个非常耗费人力的过程。特别不同信息存储产品彼此间的整合性不高，使用者界面亦不尽相同，企业需要聘请许多熟悉不同产品和平台特性的员工，对个别的信息存储系统进行监控及管理工作。此外，传统的数据信息存储架构，是与所支持的应用程序密切结合的，因此当应用程序有所更动时，数据信息存储架构必须随之调整。 <br />    因此建立一个具有大规模可伸缩性的、24×7连续可用性的、跨平台的、能够提供多种信息处理系统的连接、信息保护、信息管理、信息分享的企业信息存储系统，并使之成为网络上的一种公用设施，可在整个网络中为企业的所有应用提供无限的性能和容量，成为了企业整体战略的重要组成部分。显然，传统的数据信息存储架构面对这样的要求已显得力不从心了，这时新的技术--网络附加信息存储（Network Attached Storage；NAS）及信息存储区域网络（Storage Area Network；SAN）便应运而生了。 <br />    通俗地讲，NAS是一个具有很大信息存储容量的设备，它通过集线器（HUB）或交换机（SWITCH）直接连在网络上，使磁盘空间的扩展如同在网络上添加打印机一样的简单方便。NAS设备的物理位置很灵活，既可以可放置在数据中心的工作组内，也可以放在其它地点，通过物理链路与网络连接起来。NAS设备集成了信息存储器件（例如硬盘驱动器阵列、CD或DVD驱动器、磁带驱动器或可移动的信息存储介质）和简易服务器，具有RAID功能和完全的文件服务器功能。集成在NAS设备中的简易服务器可以将有关信息存储的功能与应用服务器执行的其他功能分隔开，允许用户无需应用服务器的干预，就可以在网络上存取数据。这样既可减小CPU的开销，也能显著改善性能。一般认为，NAS具有安装管理方便、价格平民化等优点，是中小企业信息存储的优选方案。而SAN，在最纯粹的意义上，是一个独立于服务器网络系统之外的，几乎拥有无限信息存储能力的高速信息存储网络。特点是基于光纤通道技术（Fiber Channel）的电缆，交换机和集线器，将很多的信息存储设备连接起来，再与有很多不同服务器组成的网络相连接，以多点对多点的方式进行管理。SAN不但具有高传输速度（100Mbps）、远传输距离（10Km）和支持数量众多的设备等优点，更为重要的是，SAN使服务器和存储器之间的连接方式发生了根本性的变革。与传统服务器与磁盘阵列之间的主/从关系不同，光纤通道SAN上的所有设备均处于平等的地位。多台服务器以及多个存储器可以配置在同一个SAN上，其中任何一台服务器均可存取网络中的任何一个信息存储设备，真正实现了在不同的硬件和操作平台之间异构信息存储设备和数据的整合，是新一代企业信息存储架构的主流。 <br />    NAS和SAN的出现，再次体现了把信息存储作为专门设备的趋势。而在未来的几年内，无论NAS还是SAN，都将呈现快速成长的局面。IDC预测，NAS的市场规模将从98年的9亿美元，成长到2002年的105亿美元。Datamation则预估，SAN的市场规模将从98年的30亿美元，成长到2002年的114亿美元。但是，SAN的主要功能是高速信息存储，而NAS则偏重于文件共享。这好比SAN是交通工具里的飞机，而NAS则是火车，二者各有特点，互不替代。<br /></p>
<img src ="http://www.blogjava.net/zqli/aggbug/77924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2006-10-29 20:18 <a href="http://www.blogjava.net/zqli/archive/2006/10/29/77924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是异构数据库?</title><link>http://www.blogjava.net/zqli/archive/2006/10/25/77214.html</link><dc:creator>放水老倌</dc:creator><author>放水老倌</author><pubDate>Wed, 25 Oct 2006 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/zqli/archive/2006/10/25/77214.html</guid><wfw:comment>http://www.blogjava.net/zqli/comments/77214.html</wfw:comment><comments>http://www.blogjava.net/zqli/archive/2006/10/25/77214.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zqli/comments/commentRss/77214.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zqli/services/trackbacks/77214.html</trackback:ping><description><![CDATA[
		<div class="f14 wr">异构数据库系统是相关的多个数据库系统的集合，可以实现数据的共享和透明访问，每个数据库系统在加入异构数据库系统之前本身就已经存在，拥有自己的DMBS。异构数据库的各个组成部分具有自身的自治性，实现数据共享的同时，每个数据库系统仍保有自己的应用特性、完整性控制和安全性控制。异构数据库系统的异构性主要体现在以下几个方面： <br /><br />计算机体系结构的异构 <br /><br />各个参与的数据库可以分别运行在大型机、小型机、工作站、PC或嵌入式系统中。 <br /><br />基础操作系统的异构 <br /><br />各个数据库系统的基础操作系统可以是Unix、Windows NT、 Linux等。 <br /><br />DMBS本身的异构 <br /><br />可以是同为关系型数据库系统的Oracle、 SQL Server等，也可以是不同数据模型的数据库，如关系、模式、层次、网络、面向对象，函数型数据库共同组成一个异构数据库系统。 <br /><br />----异构数据库系统的目标在于实现不同数据库之间的数据信息资源、硬件设备资源和人力资源的合并和共享。其中关键的一点就是以局部数据库模式为基础，建立全局的数据模式或全局外视图。这种全局模式对于建立高级的决策支持系统尤为重要。 <br /><br />----大型机构在许多地点都有分支机构，每个子机构的数据库中都有着自己的信息数据，而决策制订人员一般只关心宏观的、为全局模式所描述的信息。建立在数据仓库技术基础上的异构数据库全局模式的描述是一种好的解决方案。数据仓库可以从异构数据库系统中的多个数据库中收集信息，并建立统一的全局模式，同时收集的数据还支持对历史数据的访问，用户通过数据仓库提供的统一的数据接口进行决策支持的查询。 <br /><br />数据库转换 <br /><br />----对于异构数据库系统，实现数据共享应当达到两点：一是实现数据库转换；二是实现数据的透明访问。由华中科技大学开发的，拥有自主版权的商品化数据库管理系统DM3系统，通过所提供的数据库转换工具和API接口实现了这两点。 <br /><br />----DM3提供了数据库转换工具，可以将一种数据库系统中定义的模型转化为另一种数据库中的模型，然后根据需要再装入数据，这时用户就可以利用自己熟悉的数据库系统和熟悉的查询语言，实现数据共享的目标。数据库转换工具首先进行类型转换，访问源数据库系统，将源数据库的数据定义模型转换为目标数据库的数据定义模型，然后进行数据重组，即将源数据库系统中的数据装入到目的数据库中。 <br /><br />----在转换的过程中，有时要想实现严格的等价转换是比较困难的。首先要确定两种模型中所存在的各种语法和语义上的冲突，这些冲突可能包括： <br /><br />命名冲突：即源模型中的标识符可能是目的模型中的保留字，这时就需要重新命名。 <br />格式冲突：同一种数据类型可能有不同的表示方法和语义差异，这时需要定义两种模型之间的变换函数。 <br />结构冲突：如果两种数据库系统之间的数据定义模型不同，如分别为关系模型和层次模型，那么需要重新定义实体属性和联系，以防止属性或联系信息的丢失。 <br /><br />----总之，在进行数据转换后，一方面源数据库模式中所有需要共享的信息都转换到目的数据库中，另一方面这种转换又不能包含冗余的关联信息。 <br /><br />----数据库转换工具可以实现不同数据库系统之间的数据模型转换，需要进一步研究的问题是：如果数据库转换同时进行数据定义模式转换和数据转换，就可能引起同一数据集合在异构数据库系统中存在多个副本，因此需要引入新的访问控制机制。在保证各个参与数据库自治，维护其完整性、安全性的基础上，对于异构数据库系统提供全局的访问控制、并发机制和安全控制。 <br /><br />----如果数据库转换只进行数据定义转换，不产生数据的副本，那么在新的目的数据库定义模型的框架下访问数据，实现上仍是对源数据库系统中数据的访问。这时利用新的数据库系统中的数据处理语言实现的事务，不能直接访问源数据库，必须进行事务级的翻译才可以执行。 <br /><br />数据的透明访问 <br /><br />----在异构数据系统中实现了数据的透明访问，用户就可以将异构分布式数据库系统看成普通的分布式数据库系统，用自己熟悉的数据处理语言去访问数据库，如同访问一个数据库系统一样。但目前还没有一种广泛使用的数据定义模型和数据查询语言，实现数据的透明访问可以采用多对一转换、双向的中间件等技术。开放式数据库互连（Open DataBase Connectivity,简称ODBC）是一种用来在相关或不相关的数据库管理系统中存取数据的标准应用程序接口（API）。ODBC为应用程序提供了一套高层调用接口规范和基于动态链接库的运行支持环境。目前，常用的数据库应用开发的前端工具如Power Builder、 Delphi等都通过开放数据库互联(ODBC)接口来连接各种数据库系统。而多数数据库管理系统（如：Oracle、Sybase、SQL Server等）都提供了相应的ODBC驱动程序，使数据库系统具有很好的开放性。ODBC接口的最大优点是其互操作能力，理想情况下，每个驱动程序和数据源应支持完全相同的ODBC函数调用和SQL语句，使得ODBC应用程序可以操作所有的数据库系统。然而，实际上不同的数据库对SQL语法的支持程度各不相同，因此，ODBC规范定义了驱动程序的一致性级别，ODBC API的一致性确定了应用程序所能调用的ODBC函数种类，ODBC 2.0规定了三个级别的函数，目前 DM3 ODBC API支持 ODBC 2.0规范中第二级扩展的所有函数。 <br /><br />----随着Internet应用的不断普及，Internet的异构分布式信息系统正在迅速发展，Java以其平台无关性、移植性强，安全性高、稳定性好、分布式、面向对象等优点而成为Internet应用开发的首选语言。在Internet环境下，实现基于异种系统平台的数据库应用，必须提供一个独立于特定数据库管理系统的统一编程界面和一个基于 SQL的通用的数据库访问方法。Java与数据库接口规范JDBC（Java Database Connectivity）是支持基本SQL功能的一个通用的应用程序编程接口，它在不同的数据库功能模块的层次上提供了一个统一的用户界面，为对异构数据库进行直接的Web访问提供了新的解决方案。 JDBC已被越来越多的数据库厂商、连接厂商、Internet服务厂商及应用程序编制者所支持。</div>
		<p> </p>
<img src ="http://www.blogjava.net/zqli/aggbug/77214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zqli/" target="_blank">放水老倌</a> 2006-10-25 15:55 <a href="http://www.blogjava.net/zqli/archive/2006/10/25/77214.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>