<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[小宇飞刀的BLOG]]></title> 
<link>http://vir.jxstnu.edu.cn/xieyunc/index.php</link> 
<description><![CDATA[小宇的网上家园 飞刀的技术博客]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[小宇飞刀的BLOG]]></copyright>
<item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?215</link>
<title><![CDATA[使用SQL语句备份与恢复数据库]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Wed, 04 Jun 2008 05:41:34 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?215</guid> 
<description>
<![CDATA[ 
	1) 覆盖式的备份数据库到文件<br />&nbsp;BACKUP DATABASE 数据库名 TO DISK = '备份文件名' WITH INIT&nbsp;&nbsp;<br />2) 数据恢复<br />&nbsp;USE MASTER ALTER DATABASE 数据库名<br />&nbsp;SET OFFLINE WITH ROLLBACK IMMEDIATE<br />&nbsp;RESTORE DATABASE 数据库名 FROM DISK = '备份文件名'<br />&nbsp;ALTER DATABASE 数据库名<br />&nbsp;SET ONLINE WITH ROLLBACK IMMEDIATE&nbsp;&nbsp; 
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?197</link>
<title><![CDATA[SQL Server 性能调优]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Sat, 26 Apr 2008 03:47:06 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?197</guid> 
<description>
<![CDATA[ 
	1、用程序中，保证在实现功能的基础上，尽量减少对数据库的访问次数；通过搜索参数，尽量减少对表的访问行数,最小化结果集，从而减轻网络负担；能够分开的操作尽量分开处理，提高每次的响应速度；在数据窗口使用SQL时，尽量把使用的索引放在选择的首列；算法的结构尽量简单；在查询时，不要过多地使用通配符如 SELECT * FROM T1语句，要用到几列就选择几列如：SELECT COL1,COL2 FROM T1；在可能的情况下尽量限制尽量结果集行数如：SELECT TOP 300 COL1,COL2,COL3 FROM T1,因为某些情况下用户是不需要那么多的数据的。不要在应用中使用数据库游标，游标是非常有用的工具，但比使用常规的、面向集的SQL语句需要更大的开销；按照特定顺序提取数据的查找。<br/><br/>2、&nbsp;&nbsp; 避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:<br/>SELECT name FROM employee WHERE salary ＞ 60000<br/>在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。<br/><br/>3、&nbsp;&nbsp; 尽量避免在WHERE子句中对字段进行函数或表达式操作，这将导致引擎放弃使用索引而进行全表扫描。如：<br/>SELECT * FROM T1 WHERE F1/2=100<br/>应改为:<br/>SELECT * FROM T1 WHERE F1=100*2<br/><br/>SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’<br/>应改为:<br/>SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’<br/><br/>SELECT member_number, first_name, last_name&nbsp;&nbsp;FROM members<br/>WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21<br/>应改为:<br/>SELECT member_number, first_name, last_name&nbsp;&nbsp;FROM members<br/>WHERE dateofbirth < DATEADD(yy,-21,GETDATE())<br/>即：任何对列的操作都将导致表扫描，它包括数据库函数、计算表达式等等，查询时要尽可能将操作移至等号右边。<br/><br/>4、&nbsp;&nbsp; 避免使用!=或＜＞、IS NULL或IS NOT NULL、IN ，NOT IN等这样的操作符,因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如:<br/>SELECT id FROM employee WHERE id != 'B%'<br/>优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。<br/> <br/>5、&nbsp;&nbsp; 尽量使用数字型字段，一部分开发人员和数据库管理人员喜欢把包含数值信息的字段<br/>设计为字符型，这会降低查询和连接的性能，并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符，而对于数字型而言只需要比较一次就够了。<br/><br/>6、&nbsp;&nbsp; 合理使用EXISTS,NOT EXISTS子句。如下所示：<br/>1.SELECT SUM(T1.C1)FROM T1 WHERE(<br/>(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)<br/>2.SELECT SUM(T1.C1) FROM T1WHERE EXISTS(<br/>&nbsp;&nbsp;SELECT * FROM T2 WHERE T2.C2=T1.C2)<br/>两者产生相同的结果，但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。<br/>如果你想校验表里是否存在某条纪录，不要用count(*)那样效率很低，而且浪费服务器资源。可以用EXISTS代替。如：<br/>IF (SELECT COUNT(*) FROM table_name WHERE column_name = 'xxx')<br/>可以写成：<br/>IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx')<br/><br/>经常需要写一个T_SQL语句比较一个父结果集和子结果集，从而找到是否存在在父结果集中有而在子结果集中没有的记录，如：<br/>1.SELECT a.hdr_key&nbsp;&nbsp;FROM hdr_tbl a---- tbl a 表示tbl用别名a代替<br/>WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)<br/><br/>2.SELECT a.hdr_key&nbsp;&nbsp;FROM hdr_tbl a<br/>LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key&nbsp;&nbsp;WHERE b.hdr_key IS NULL<br/><br/>3.SELECT hdr_key&nbsp;&nbsp;FROM hdr_tbl<br/>WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;三种写法都可以得到同样正确的结果，但是效率依次降低。<br/><br/>7、&nbsp;&nbsp; 尽量避免在索引过的字符数据中，使用非打头字母搜索。这也使得引擎无法利用索引。 <br/>见如下例子：<br/>SELECT * FROM T1 WHERE NAME LIKE ‘%L%’<br/>SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’<br/>SELECT * FROM T1 WHERE NAME LIKE ‘L%’<br/>即使NAME字段建有索引，前两个查询依然无法利用索引完成加快操作，引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。<br/><br/>8、&nbsp;&nbsp; 分利用连接条件，在某种情况下，两个表之间可能不只一个的连接条件，这时在&nbsp;&nbsp;WHERE 子句中将连接条件完整的写上，有可能大大提高查询速度。<br/>例：<br/>SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO<br/>SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO&nbsp;&nbsp;AND A.ACCOUNT_NO=B.ACCOUNT_NO<br/>第二句将比第一句执行快得多。<br/><br/>9、&nbsp;&nbsp;&nbsp;&nbsp;消除对大型表行数据的顺序存取<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;尽管在所有的检查列上都有索引，但某些形式的WHERE子句强迫优化器使用顺序存取。如：<br/>SELECT * FROM orders WHERE (customer_num=104&nbsp;&nbsp;AND order_num>1001) OR<br/>order_num=1008<br/>解决办法可以使用并集来避免顺序存取：<br/>SELECT ＊ FROM orders WHERE customer_num=104 AND order_num>1001<br/>UNION<br/>SELECT ＊ FROM orders WHERE order_num=1008<br/>这样就能利用索引路径处理查询。<br/><br/>10、 避免困难的正规表达式<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LIKE关键字支持通配符匹配，技术上叫正规表达式。但这种匹配特别耗费时间。例如：SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”<br/>即使在zipcode字段上建立了索引，在这种情况下也还是采用顺序扫描的方式。如<br/>果把语句改为SELECT ＊ FROM customer WHERE zipcode >“98000”，在执行查询<br/>时就会利用索引来查询，显然会大大提高速度。<br/>11、 使用视图加速查询<br/>把表的一个子集进行排序并创建视图，有时能加速查询。它有助于避免多重排序<br/>操作，而且在其他方面还能简化优化器的工作。例如：<br/>SELECT cust.name，rcvbles.balance，……other columns<br/>FROM cust，rcvbles<br/>WHERE cust.customer_id = rcvlbes.customer_id<br/>AND rcvblls.balance>0<br/>AND cust.postcode>“98000”<br/>ORDER BY cust.name<br/>如果这个查询要被执行多次而不止一次，可以把所有未付款的客户找出来放在一个<br/>视图中，并按客户的名字进行排序：<br/>CREATE VIEW DBO.V_CUST_RCVLBES<br/>AS<br/>SELECT cust.name，rcvbles.balance，……other columns<br/>FROM cust，rcvbles<br/>WHERE cust.customer_id = rcvlbes.customer_id<br/>AND rcvblls.balance>0<br/>ORDER BY cust.name<br/><br/>然后以下面的方式在视图中查询：<br/>SELECT ＊ FROM&nbsp;&nbsp;V_CUST_RCVLBES<br/>WHERE postcode>“98000”<br/>视图中的行要比主表中的行少，而且物理顺序就是所要求的顺序，减少了磁盘<br/>I/O，所以查询工作量可以得到大幅减少。<br/><br/>12、 能够用BETWEEN的就不要用IN<br/>SELECT * FROM T1 WHERE ID IN (10,11,12,13,14)<br/>改成：<br/>SELECT * FROM T1 WHERE ID BETWEEN 10 AND 14<br/>因为IN会使系统无法使用索引,而只能直接搜索表中的数据。<br/><br/>13、 能用DISTINCT的就不用GROUP BY<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SELECT OrderID&nbsp;&nbsp;FROM Details WHERE UnitPrice > 10 GROUP BY OrderID<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可改为：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10<br/>&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>14、&nbsp;&nbsp; 部分利用索引<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.SELECT employeeID, firstname, lastname<br/>FROM names<br/>WHERE dept = 'prod' or city = 'Orlando' or division = 'food'<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.SELECT employeeID, firstname, lastname FROM names WHERE dept = 'prod'<br/>UNION ALL<br/>SELECT employeeID, firstname, lastname FROM names WHERE city = 'Orlando'<br/>UNION ALL<br/>SELECT employeeID, firstname, lastname FROM names WHERE division = 'food'<br/>如果dept 列建有索引则查询2可以部分利用索引，查询1则不能。<br/><br/>15、&nbsp;&nbsp; 能用UNION&nbsp;&nbsp;ALL就不要用UNION<br/>UNION&nbsp;&nbsp;ALL不执行SELECT DISTINCT函数，这样就会减少很多不必要的资源<br/><br/>16、&nbsp;&nbsp; 不要写一些不做任何事的查询<br/>如：SELECT COL1 FROM T1 WHERE 1=0<br/>&nbsp;&nbsp;&nbsp;&nbsp;SELECT COL1 FROM T1 WHERE COL1=1 AND COL1=2<br/>这类死码不会返回任何结果集，但是会消耗系统资源。<br/><br/>17、&nbsp;&nbsp;尽量不要用SELECT INTO语句。<br/>SELECT INOT 语句会导致表锁定，阻止其他用户访问该表。<br/><br/>18、 必要时强制查询优化器使用某个索引<br/>&nbsp;&nbsp;&nbsp;&nbsp; SELECT * FROM T1 WHERE nextprocess = 1 AND processid IN (8,32,45)<br/>改成：<br/>SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess = 1 AND processid IN (8,32,45)<br/>则查询优化器将会强行利用索引IX_ProcessID 执行查询。<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>19、&nbsp;&nbsp;虽然UPDATE、DELETE语句的写法基本固定，但是还是对UPDATE语句给点建议：<br/>a) 尽量不要修改主键字段。<br/>b) 当修改VARCHAR型字段时，尽量使用相同长度内容的值代替。<br/>c) 尽量最小化对于含有UPDATE触发器的表的UPDATE操作。<br/>d) 避免UPDATE将要复制到其他数据库的列。<br/>e) 避免UPDATE建有很多索引的列。<br/>f) 避免UPDATE在WHERE子句条件中的列。<br/><br/><br/>　　上面我们提到的是一些基本的提高查询速度的注意事项,但是在更多的情况下,往往需要反复试验比较不同的语句以得到最佳方案。最好的方法当然是测试，看实现相同功能的SQL语句哪个执行时间最少，但是数据库中如果数据量很少，是比较不出来的，这时可以用查看执行计划，即：把实现相同功能的多条 SQL语句考到查询分析器，按CTRL+L看查所利用的索引，表扫描次数（这两个对性能影响最大），总体上看询成本百分比即可。<br/>　　简单的存储过程可以用向导自动生成：在企业管理器工具栏点击运行向导图标，点击”数据库”、”创建存储过程向导”。复杂存储过程的调试：在查询分析器左边的对象浏览器（没有？按F8）选择要调试的存储过程,点右键，点调试，输入参数执行，出现一个浮动工具条，上面有单步执行，断点设置等。<br/>Tags - <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=sql" rel="tag">sql</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=server" rel="tag">server</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=%25E6%2580%25A7%25E8%2583%25BD%25E8%25B0%2583%25E4%25BC%2598" rel="tag">性能调优</a>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?151</link>
<title><![CDATA[SQL Server 2000订阅与发布的具体操作 ]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Fri, 09 Nov 2007 03:27:42 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?151</guid> 
<description>
<![CDATA[ 
	同步过程 <br/><br/>一、准备工作，如果完成则可跳过。 <br/><br/>1、内网DB服务器作为发布服务器，外网DB服务器作为订阅服务器。 <br/><br/>发布服务器和订阅服务器上分别创建Windows用户jl,密码jl，隶属于administrators，注意要保持一致。 <br/><br/>2、发布服务器上创建一个共享目录，作为发布快照文件的存放目录。例如：在D盘根目录下建文件夹名为SqlCopy，设置用户jl，权限为完全控制。 <br/><br/>3、确定发布服务器和订阅服务器的数据库autoweb保持一致。 <br/><br/>4、在发布服务器和订阅服务器的SQL Server中创建用户登陆名jl，作为发布数据库autoweb的拥有者（设置为dbo_owner和public）。用户名和密码都一致。 <br/><br/>5、打开服务(控制面板---管理工具---服务) <br/><br/>---右击SQLSERVER AGENT---属性---登录---选择“此帐户” <br/><br/>---输入或选择第一步中创建的WINDOWS 用户jl, <br/><br/>---“密码“中输入该用户密码jl <br/><br/>6、开启SQL Server 2005的网络协议TCP/IP和管道命名协议并重启网络服务。 <br/><br/>7、设置SQL SERVER 身份验证，解决连接时的权限问题（发布、订阅服务器均设置） <br/><br/>步骤为：对象资源管理器----右击SQL实例-----属性----安全性----服务器身份验证------选“SQL Server和WINDOWS“，然后点确定。 <br/><br/>8、发布服务器和订阅服务器互相注册 <br/><br/>步骤如下：视图----单击以注册服务器----右键数据库引擎----新建服务器注册-----填写要注册的远程服务器名称------身份验证选“SQL Server验证“-----用户名(sa) 密码------创建组（也可不建）-----完成。对于只能用IP，不能用计算机名的，为其注册服务器别名 <br/><br/>二、发布和订阅 <br/><br/>如下工作都在发布服务器上配置，包括发布和订阅。 <br/><br/>快照发布和订阅 <br/><br/>1、 选择 复制 节点，右键本地发布 ----下一步---------系统弹出对话框看提示----直到“指定快照文件夹”----在“快照文件夹“中输入准备工作中创建的目录(指向步骤3所建的共享文件夹)------选择发布数据库-------选择发布类型 <br/><br/>下一步―――选择要发布的数据库autoweb中的表，将b(B)开头的表去掉，V开头的表去掉，c_开头的表去掉，t_开头的表去掉，剩下的表作为快照发布到订阅服务器上（单向传输） <br/><br/>根据情况决定执行发布的间隔时间，如图每天每20分钟执行一次。 <br/><br/>下一步快照代理安全性，设置如图，连接到发布服务器用户jl,密码jl. <br/><br/><br/>-------填写发布名称。 <br/><br/><br/>2、 选择 复制 节点，右键本地订阅，选择发布服务器-------选择订阅方式（选择推送订阅））-------填加订阅服务器--------选择代理计划（一般选择连续运行）---------其余选择默认项。 <br/><br/>至此完成快照发布和订阅。 <br/><br/><br/>合并发布和订阅 <br/><br/><br/>1、选择如下三个表作为合并发布的对象，用于双向通讯 <br/><br/><br/>根据情况决定执行发布的间隔时间，如图每天每20分钟执行一次。 <br/><br/><br/>2、 选择 复制 节点，右键本地订阅，选择发布服务器-------选择订阅方式（选择推送订阅））-------填加订阅服务器--------选择代理计划（一般选择连续运行）---------其余选择默认项。 <br/><br/>至此完成合并发布和订阅 <br/><br/><br/>------------------------------------------------------------------- <br/><br/><br/>主要是要注意权限的问题,一般做发布/订阅,建议你做如下准备工作: <br/><br/>1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户 <br/><br/>我的电脑 <br/><br/>--控制面板 <br/><br/>--管理工具 <br/><br/>--计算机管理 <br/><br/>--用户和组 <br/><br/>--右键用户 <br/><br/>--新建用户 <br/><br/>--建立一个隶属于administrator组的登陆windows的用户 <br/><br/>2.在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作: <br/><br/>我的电脑--D: 新建一个目录,名为: PUB <br/><br/>--右键这个新建的目录 <br/><br/>--属性--共享 <br/><br/>--选择"共享该文件夹" <br/><br/>--通过"权限"按纽来设置具体的用户权限,保证第一步中创建的用户具有对该文件夹的所有权限 <br/><br/>--确定 <br/><br/>3.设置SQL代理(SQLSERVERAGENT)服务的启动用户(发布/订阅服务器均做此设置) <br/><br/>开始--程序--管理工具--服务 <br/><br/>--右键SQLSERVERAGENT <br/><br/>--属性--登陆--选择"此账户" <br/><br/>--输入或者选择第一步中创建的windows登录用户名 <br/><br/>--"密码"中输入该用户的密码 <br/><br/>4.设置SQL Server身份验证模式,解决连接时的权限问题(发布/订阅服务器均做此设置) <br/><br/>企业管理器 <br/><br/>--右键SQL实例--属性 <br/><br/>--安全性--身份验证 <br/><br/>--选择"SQL Server 和 Windows" <br/><br/>--确定 <br/><br/>5.在发布服务器和订阅服务器上互相注册 <br/><br/>企业管理器 <br/><br/>--右键SQL Server组 <br/><br/>--新建SQL Server注册... <br/><br/>--下一步--可用的服务器中,输入你要注册的远程服务器名--添加 <br/><br/>--下一步--连接使用,选择第二个"SQL Server身份验证" <br/><br/>--下一步--输入用户名和密码 <br/><br/>--下一步--选择SQL Server组,也可以创建一个新组 <br/><br/>--下一步--完成 <br/><br/>6.对于只能用IP,不能用计算机名的,为其注册服务器别名 <br/><br/>(在连接端配置,比如,在订阅服务器上配置的话,服务器名称中输入的是发布服务器的IP) <br/><br/>开始--程序--Microsoft SQL Server--客户端网络实用工具 <br/><br/>--别名--添加 <br/><br/>--网络库选择"tcp/ip"--服务器别名输入SQL服务器名 <br/><br/>--连接参数--服务器名称中输入SQL服务器ip地址 <br/><br/>--如果你修改了SQL的端口,取消选择"动态决定端口",并输入对应的端口号 <br/><br/>Tags - <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=sql" rel="tag">sql</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=server" rel="tag">server</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=2000" rel="tag">2000</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=%25E5%258F%2591%25E5%25B8%2583%25E6%259C%258D%25E5%258A%25A1%25E5%2599%25A8" rel="tag">发布服务器</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=%25E8%25AE%25A2%25E9%2598%2585%25E6%259C%258D%25E5%258A%25A1%25E5%2599%25A8" rel="tag">订阅服务器</a>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?120</link>
<title><![CDATA[临时表操作的一些见解(解决了我在存储过程中使用临时表的困惑）]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Mon, 28 May 2007 06:25:31 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?120</guid> 
<description>
<![CDATA[ 
	本人在调试以下存储过程中遇到了很大的困扰（主要是临时表操作）：<br/><textarea name="code" class="sql" rows="15" cols="100">CREATE PROCEDURE [c_readtop] @eachrow int=10 AS
declare @tmpcat varchar(16)
create table #tmp_result (arid int,cat2 varchar(16),title varchar(100),upday datetime)
declare rt_cursor cursor
for select cat2 from category where cat1='电脑手册' and catl=2
open rt_cursor
fetch from rt_cursor into @tmpcat
while @@fetch_status=0
 &nbsp;Begin
 &nbsp; set rowcount @eachrow
 &nbsp; Insert into #tmp_result (arid,cat2,title,upday) Select top 10 arid,cat2,title,upday from article as a left join category as b on a.sortid=b.catid where b.cat1='电脑手册' 
 &nbsp; and b.cat2=@tmpcat order by upday desc
 &nbsp; fetch from rt_cursor into @tmpcat
 &nbsp;End
select * from #tmp_result
drop table #tmp_result
close rt_cursor
deallocate rt_cursor
</textarea><br/>此存储过程的作用是取出每个分类的最新10条记录。<br/>出现的错误信息是（一旦操作返回的记录集时就出现）：<br/>ADODB.Recordset 错误 '800a0e78' <br/><br/>The operation requested by the application is not allowed if the object is closed. <br/><br/> &nbsp; &nbsp;此存储过程能在qa中正常运行且能得到正确结果，使用odbc连接数据库的话，也能得到正确的结果。于是首先怀疑oledb方式连接没能返回记录集。进行了下面的调试：<br/>（一）加调试标记，在调用记录集前用set rs=rs.nextrecordset测试是不是命中返回的记录集……<br/>（二）由于该过存原来是另一个过程的一部分，怀疑存储过程中有些语句不能同时使用，于是将该过程分离成一个独立的存储过程，错误依旧。<br/>（三）怀疑调用该过程的Asp有问题，于是重做一个只是调用该存储过程的Asp程序，错误依旧。<br/>（四）将连接方式改为odbc方式连接（建dsn，设sql server的login ID，设权限），该错误消失。重新使用oledb连接，错误依旧。<br/>（五）怀疑对临时表的数据插入有问题，取消去临时表插入数据，能返回一个空的记录集。<br/>（六）经Bigeagle提示，将临时表建在临时数据库tempdb上，错误依旧（七）把存储过程中的drop table去掉，在qa中运行该存储过程，观察临时表的生成情况，发现临时表正确生成且有正确的数据插入，百思不得其解，数据输出到哪了？<br/>（八）经Bigeagle提示create table一句返回了记录集，于是重新在输出记录集前使用多个set rs=rs.nextrecordset（最多放上了4个），错误提示依旧。<br/>（九）怀疑临时表操作有问题，将临时表改为固定表，不插入数据时返回空记录集，插入记录时仍然提示错误。在记录集输出前先执行一个或多个set rs=rs.nextrecordset，终于有一次没有提示出错（检测到rs.eof为false），于是才恍然大悟——不但是create table返回了记录集，而且连insert into语句也返回了记录集，不过该记录集得一种特别的记录集（没有字段，不能对该记录集进行任何操作——连检测rs.eof都不允许），我在此将它称为特殊的记录集，方便下面引用。<br/>（十）知道了问题的症结，就马上解决了，在存储过程中不希望返回记录集前执行set nocount on，要返回记录集时，先执行set nocount off。<br/><br/>也就是改成：<br/><textarea name="code" class="sql" rows="15" cols="100">
CREATE PROCEDURE [c_readtop] @eachrow int=10 AS
declare @tmpcat varchar(16)
set nocount on
create table #tmp_result (arid int,cat2 varchar(16),title varchar(100),upday datetime)
declare rt_cursor cursor
for select cat2 from category where cat1='电脑手册' and catl=2
open rt_cursor
fetch from rt_cursor into @tmpcat
while @@fetch_status=0
 &nbsp;Begin
 &nbsp; set rowcount @eachrow
 &nbsp; Insert into #tmp_result (arid,cat2,title,upday) Select top 10 arid,cat2,title,upday from article as a left join category as b on a.sortid=b.catid where b.cat1='电脑手册'
 and b.cat2=@tmpcat order by upday desc
 &nbsp; fetch from rt_cursor into @tmpcat
 &nbsp;End
set nocount off
select * from #tmp_result
drop table #tmp_result
close rt_cursor
deallocate rt_cursor
</textarea><br/>问题解决。<br/><br/> &nbsp; &nbsp;在该存储过程调试过程中，发现oledb和odbc存在一个很大的差别，asp向odbc取记录集时，odbc过滤了上面所称的特殊记录集（那种只占位置但不能进行任何操作的记录集——多由create table或insert into产生），而asp向oledb取记录集时，oledb并没有将特殊记录集过滤。<br/> &nbsp; &nbsp;同时，认识到在使用存储过程返回记录集时，在不希望返回记录的地方，应该使用set nocount on禁止存储过程返回记录集，否则可能会绕很多弯路。<br/> &nbsp; &nbsp;终于明白了为什么绕了这么多弯路：没有想到oledb返回了这么多特殊的记录集（还是由一个循环产生的，该循环执行次数5、6次），怪不得在取记录集前虽然执行了set rs=rs.nextrecordset，但终因数据不够多而未能发现错误症结所在。<br/> &nbsp; &nbsp;特别感谢在调试过程中bigeagle给予的提示，多谢。<br/><br/><br/>Tags - <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=mssql" rel="tag">mssql</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=%25E4%25B8%25B4%25E6%2597%25B6%25E8%25A1%25A8" rel="tag">临时表</a>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?56</link>
<title><![CDATA[Mircosoft SQL Server无法安装的解决办法]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Fri, 02 Mar 2007 02:46:34 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?56</guid> 
<description>
<![CDATA[ 
	一、安装SQL Server 遇到错误提示：以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机<br/><br/> &nbsp; &nbsp;安装SQL Server 2000个人版用作开发，可是每次安装都提示“以前的某个程序安装已在安装计算计上创建挂起的文件操作。运行安装程序之前必须重新启动计算机。”重新启动了计算机之后，问题却丝毫没有解决，依然提示这样的话。 <br/><br/>解决方法：<br/><br/><br/>1）添加/删除程序中彻底删除Microsoft &nbsp;SQL &nbsp;Server。 <br/><br/>2）再把安装时产生的Microsoft &nbsp;SQL &nbsp;Server 文件夹删掉。 <br/><br/>3）打开注册表编辑器，在HKEY_LOCAL_MACHINE&#92;SYSTEM&#92;CurrentControlSet&#92;Control&#92;Session Manager中找到PendingFileRenameOperations项目，并删除它。这样就可以清除安装暂挂项目。 <br/><br/>此时，不用重启计算机应该就可以正常地安装Micrsoft SQL Server了。<br/><br/>如果依然无法安装，继续下面的步骤：<br/><br/>4）删除注册表中跟sql server相关的键。<br/><br/> &nbsp; &nbsp;其实估计只要做第3步就可以搞定，这样就可以清除安装暂挂项目。自己是先走了1，2，4，最后做了3才搞定。所以估计3才是最关键的。再装就应该没有问题了！<br/><br/><br/>二、Windows 2000 下常见的装不上Microsoft SQL Server 2000 的问题<br/>// &nbsp; (1)配置服务器时中断.<br/>// &nbsp; (2)注册 ActiveX 时中断.<br/>// &nbsp; (3)显示到100%的时候中断. <br/>当然重新安装 Windows 2000 完全可以安装 SQL Server 2000。<br/><br/>安全起见:<br/>1>先备份您的注册表。<br/>2>备份您的数据。如果进不了SQL Server 2000,可以备份 Program Files&#92;&#92;Microsoft SQL Server&#92;&#92;MSSQL&#92;&#92;Data 文件夹的文件。<br/><br/>您必须知道:<br/> &nbsp; &nbsp;Windows 2000 Server 可以安装SQL Server 2000的任何版本。<br/> &nbsp; &nbsp;Windows 2000 Professional &nbsp;仅可以安装SQL Server 2000的个人版和桌面版。<br/><br/>有两种办法:<br/><br/>1、先卸载您的 SQL Server 2000,必要的时候删除 Program Files&#92;&#92;Microsoft SQL Server 文件夹.<br/>2、放入 SQL Server 2000 光盘.<br/>3、在"开始"--"运行"键入 "X:&#92;&#92;x86&#92;&#92;setup.exe k=dbg" [此命令的意思单步运行安装 SQL Server 2000]<br/>4、98%安装不成功,没有任何的提示.可能是:<br/> &nbsp; (1)配置服务器时中断.<br/> &nbsp; (2)注册 ActiveX 时中断.<br/> &nbsp; (3)显示到100%的时候中断. <br/> &nbsp; &nbsp; <br/>这样一来,您只能使用下面的办法了!否则,您只有 FORMAT了!<br/>1、打开注册表 <br/> &nbsp; 在"开始"--"运行"键入 "regedit" &nbsp; &nbsp; <br/><br/>2、按下列顺序点击打开<br/> &nbsp; + HKEY_LOCAL_MACHINE <br/> &nbsp; &nbsp; &nbsp;+ SOFTWART<br/> &nbsp; &nbsp; &nbsp; &nbsp; + Microsoft<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ Windows<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CurrentVersion<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ Setup &nbsp; &nbsp; &nbsp;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ExceptionComponents<br/>3、将 ExceptionComponents 下面的文件夹全部删除!<br/> &nbsp; 如 &nbsp;&#123;60BFF50D-FB2C-4498-A577-C9548C390BB9&#125;<br/> &nbsp; &nbsp; &nbsp; &#123;60BFF50D-FB2C-4498-A577-C9548C390BB9&#125;<br/> &nbsp; &nbsp; &nbsp; &#123;60BFF50D-FB2C-4498-A577-C9548C390BB9&#125;<br/> &nbsp; &nbsp; &nbsp; &#123;60BFF50D-FB2C-4498-A577-C9548C390BB9&#125;<br/> &nbsp; &nbsp; &nbsp; .......<br/><br/>4、重新启动，重新安装 SQL Server 2000。<br/><br/> <br/><br/>Tags - <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=ms" rel="tag">ms</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=sql" rel="tag">sql</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=2000" rel="tag">2000</a>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?59</link>
<title><![CDATA[MS SQL Server中的日期格式化大全]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Wed, 07 Feb 2007 02:51:12 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?59</guid> 
<description>
<![CDATA[ 
	MS SQL Server中的日期格式化大全<br/><br/>CONVERT<br/>将某种数据类型的表达式显式转换为另一种数据类型。由于某些需求经常用到取日期格式的不同.现以下可在<br/>SQL Server中　将日期格式化.<br/><br/>使用 CONVERT：<br/><br/>CONVERT (data_type[(length)], expression [, style])<br/><br/><br/>select CONVERT(varchar, getdate(), 120 ) <br/>2004-09-12 11:06:08 <br/><br/>select replace(replace(replace(CONVERT(varchar, getdate(), 120 ),'-',''),'-',''),':','') <br/>20040912110608 <br/><br/>select CONVERT(varchar(12) , getdate(), 111 ) <br/>2004/09/12 <br/><br/>select CONVERT(varchar(12) , getdate(), 112 ) <br/>20040912 <br/><br/>select CONVERT(varchar(12) , getdate(), 102 ) <br/>2004.09.12 <br/><br/>select CONVERT(varchar(12) , getdate(), 101 ) <br/>09/12/2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 103 ) <br/>12/09/2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 104 ) <br/>12.09.2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 105 ) <br/>12-09-2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 106 ) <br/>12 09 2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 107 ) <br/>09 12, 2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 108 ) <br/>11:06:08 <br/><br/>select CONVERT(varchar(12) , getdate(), 109 ) <br/>09 12 2004 1 <br/><br/>select CONVERT(varchar(12) , getdate(), 110 ) <br/>09-12-2004 <br/><br/>select CONVERT(varchar(12) , getdate(), 113 ) <br/>12 09 2004 1 <br/><br/>select CONVERT(varchar(12) , getdate(), 114 ) <br/>11:06:08.177
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?55</link>
<title><![CDATA[MS SQL Server和Access分别取得随机记录（随机抽题）之完美篇]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Fri, 02 Feb 2007 02:44:42 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?55</guid> 
<description>
<![CDATA[ 
	 &nbsp; &nbsp;这是博主用在一个项目上的源码片断，无论是速度、均衡性，还是随机度都非常好，当然这更不可能抽到重复记录了。<br/><br/>一、在MS SQL Server 2000中生成随机记录的最好办法：<br/><textarea name="code" class="delphi" rows="15" cols="100">
 &nbsp;with tk_query do
 &nbsp;begin
 &nbsp; &nbsp;Close;
 &nbsp; &nbsp;sql.clear;
 &nbsp; &nbsp;sql.Add('select top '+inttostr(st_count)+' tk.ID,标准答案 from 题库表 tk');
 &nbsp; &nbsp;sql.Add('where pid is null and tk.题型='+quotedstr(tx)+' and tk.知识点='+quotedstr(zsd));
 &nbsp; &nbsp;sql.add('and tk.难易度='+quotedstr(nyd)+' and tk.课程号='+quotedstr(kcdm)+' order by newid()');
 &nbsp; &nbsp;Open; 
 &nbsp;end; 
</textarea><br/> &nbsp;注：关键就是 order by newid() 这条语句！随机因子就是从这里产生的。<br/><br/>二、数据库为Access 2000时生成随机记录的最好办法： <br/><br/> &nbsp; &nbsp; 由于Access中没有newid()这一随机函数，故要想在Access中直接由SQL语句生成我们所希望的随机记录不太可能，因此我们只好在开发语言中生成合适SQL语句，让Access执行了（博主的开发工具为Delphi）。 <br/><textarea name="code" class="delphi" rows="15" cols="100">
//获取题库表中的随机ID，组成一个字符串，类似这样 (3,8,2,25,49,1,7,10,6,83....)
//kcdm:课程代码,tx:题型,zsd:知识点,nyd:难易度,t_count:某一题型某一知识点某一难度下的要抽取的题量 
function TTest_Srv_RDataForm.Get_Random_ID(const kcdm,tx,zsd,nyd,t_count:string):string;
var
 &nbsp;sl: TStrings;
 &nbsp;i,ii,kk: integer;
begin
 &nbsp;try
 &nbsp; &nbsp;Result := '';
 &nbsp; &nbsp;sl := TStringList.Create;
 &nbsp; &nbsp;with TADOQuery.Create(nil) do
 &nbsp; &nbsp;begin
 &nbsp; &nbsp; &nbsp;try
 &nbsp; &nbsp; &nbsp; &nbsp;Connection := Adoconnection1;
 &nbsp; &nbsp; &nbsp; &nbsp;SQL.Text := ' select ID from 题库表 where pid is null and 题型='+quotedstr(tx)+
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' and 知识点='+quotedstr(zsd)+' and 难易度='+quotedstr(nyd)+
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' and 课程号='+quotedstr(Kcdm);
 &nbsp; &nbsp; &nbsp; &nbsp;Open;
 &nbsp; &nbsp; &nbsp; &nbsp;while not Eof do
 &nbsp; &nbsp; &nbsp; &nbsp;begin
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sl.Add(Fields[0].AsString);
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Next;
 &nbsp; &nbsp; &nbsp; &nbsp;end;
 &nbsp; &nbsp; &nbsp; &nbsp;Close;
 &nbsp; &nbsp; &nbsp;finally
 &nbsp; &nbsp; &nbsp; &nbsp;Free;
 &nbsp; &nbsp; &nbsp;end;
 &nbsp; &nbsp;end; //end with ....
 &nbsp; &nbsp;if sl.Count=0 then
 &nbsp; &nbsp; &nbsp; Exit; 

 &nbsp; &nbsp;for i := 0 to StrToIntDef(t_count,0)-1 do
 &nbsp; &nbsp;begin
 &nbsp; &nbsp; &nbsp;kk := sl.Count;//随机因子

 &nbsp; &nbsp; &nbsp;Randomize;
 &nbsp; &nbsp; &nbsp;ii := Random(kk); //取得随机数
 &nbsp; &nbsp; &nbsp;if Result='' then
 &nbsp; &nbsp; &nbsp; &nbsp;Result := sl.Strings[ii]
 &nbsp; &nbsp; &nbsp;else
 &nbsp; &nbsp; &nbsp; &nbsp;Result := Result+','+sl.Strings[ii];

 &nbsp; &nbsp; &nbsp;sl.Delete(ii); //为了避免有可能出现的重复，此ID被抽取过后把它删了
 &nbsp; &nbsp; &nbsp;if sl.Count=0 then //如果无题可抽了退出循环
 &nbsp; &nbsp; &nbsp; &nbsp;Break;
 &nbsp; &nbsp;end;
 &nbsp; &nbsp;Result := '('+Result+')'; //给结果串前后加上(......)，最终形成(24,36,5,89,72,3,6,1....)的串样

 &nbsp;finally
 &nbsp; &nbsp;sl.Free;
 &nbsp;end;
end;
//=============================================== 课程号,题型,知识点,难易度,题量
function TTest_Srv_RDataForm.Get_Random_Sql(const kcdm,tx,zsd,nyd,t_count:string):string;
begin
 &nbsp;Result := Get_Random_ID(kcdm,tx,zsd,nyd,t_count);
 &nbsp;if Result <> '' then
 &nbsp; &nbsp; Result := ' select top '+t_count+' tk.ID,标准答案 from 题库表 tk where id in '+Result
 &nbsp;else
 &nbsp; &nbsp; Result := ' select top '+t_count+' tk.ID,标准答案 from 题库表 tk where 1=1 ';
end;


 &nbsp;//以下为调用上述函数生成随机抽题的代码片断
 &nbsp;....... 
 &nbsp;with tk_query do
 &nbsp;begin 
 &nbsp; &nbsp;Close;
 &nbsp; &nbsp;sql.Clear;
 &nbsp; &nbsp;sql.Text := Get_Random_Sql(Kcdm,tx_str,zsd_str,nyd_str,txzsd_count_str);
 &nbsp; &nbsp;Open;
 &nbsp;end; 
 &nbsp;..........
</textarea><br/><br/>Tags - <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=ms" rel="tag">ms</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=sql" rel="tag">sql</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=server%25E5%2592%258Caccess%25E5%2588%2586%25E5%2588%25AB%25E5%258F%2596%25E5%25BE%2597%25E9%259A%258F%25E6%259C%25BA%25E8%25AE%25B0%25E5%25BD%2595" rel="tag">server和access分别取得随机记录</a> , <a href="http://vir.jxstnu.edu.cn/xieyunc/tag.php?tag=%25E5%25B0%258F%25E5%25AE%2587%25E9%25A3%259E%25E5%2588%2580" rel="tag">小宇飞刀</a>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?58</link>
<title><![CDATA[Access与Sql Server之ASP代码比较]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Thu, 01 Feb 2007 02:48:59 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?58</guid> 
<description>
<![CDATA[ 
	[一]连接问题（举例) <br/>[Microsoft Access] <br/>constr = "DBQ=c:&#92;data&#92;clwz.mdb; DRIVER=&#123;Microsoft Access Driver (*.mdb)&#125;" <br/>[Microsoft Sql Server] <br/>constr = "DRIVER=&#123;SQL Server&#125;;SERVER=host;DATABASE=mydata;uid=sa;pwd=" <br/><br/>[二]相似函数（举例） <br/><br/>[1]DATEDIFF(datepart, startdate, enddate) <br/>其中“datepart”参数可选项如下： <br/>设置 描述 <br/>———————————— <br/>[Microsoft Access] <br/>年 yyyy <br/>季度 q <br/>月 m <br/>一年的日数 y <br/>日 d <br/>一周的日数 w <br/>周 ww <br/>小时 h <br/>分钟 n <br/>秒 s <br/><br/>[Microsoft Sql Server] <br/>year yy, yyyy <br/>quarter qq, q <br/>month mm, m <br/>dayofyear dy, y <br/>day dd, d <br/>week wk, ww <br/>hour hh <br/>minute mi, n <br/>second ss, s <br/>millisecond ms <br/><br/>------------------------- <br/><br/>基本上差不多，但注意的是在写的时候， <br/>[Microsoft Access]要加引号，如：datediff('d',enddate,'2004/08/01') <br/>[Microsoft Sql Server]则不需要，如：datediff(d,enddate,'2004/08/01') <br/><br/>[2][Microsoft Access]中可用如cstr等转数据类型函数，而 <br/>[Microsoft Sql Server]中则用convert或cast函数，如： <br/>convert(varchar,[amount])等。 <br/><br/>[3][Microsoft Sql Server] <br/>取当前时间用getdate等等... <br/><br/>[三]语句 <br/>[Microsoft Sql Server] <br/>可以用 <br/>CASE <br/>WHEN THEN <br/>WHEN THEN <br/>... <br/>ELSE <br/>END <br/>语句，而 <br/>[Microsoft Access] <br/>不支持。 <br/>[Microsoft Access]也不支持between语句 <br/>[Microsoft Sql Server]则可以这样写： <br/>[date] between @date1 and @date2 <br/>[四]查询表 <br/>[Microsoft Sql Server] <br/>可三个及以上表join查询，而 <br/>[Microsoft Access] <br/>好像只能两个表联接查询（待权威确认）, <br/>而且[Microsoft Sql Server]可用“*=”和“=*”连接符。[五]除零问题 <br/>[Microsoft Access] <br/>在碰到除数为零时，自动丢掉相关记录，而 <br/>[Microsoft Sql Server] <br/>则会报错，且查询中止。删除代码： <br/>[Microsoft Access] <br/>可以这样写：delete * from [table] <br/>[Microsoft SQL Server] <br/>只能这样写：delete from [table] <br/>多*会报错 <br/>_____________________________________ <br/>当前日期： <br/>[Microsoft Access] <br/>用date() <br/>[Microsoft SQL Server] <br/>用getdate()如果数据库可能会更换类型的话，可以 <br/>在ASP代码中加上如这样： <br/>if inStr(constr,"Microsoft Access") > 0 then <br/>sqlstr=[Microsoft Access][sql代码] <br/>else <br/>sqlstr=[Microsoft Sql Server][sql代码] <br/>end if <br/>(constr--连接字符串) <br/>这样即使改了数据库，也不用改数据库查询更新代码了。 <br/>再加：access中有true、false的字段记录，而sql里只有smallint，对应如果在access里有“字段名=true”的，在sql里要改成“字段名=1” <br/>网上大部分的免费asp程序使用的是access数据库。但是access数据库作为一个中小型的单机数据库系统，在承担访问量、数据量大的网站应用时，往往就不堪重负了。一般认为，超过50M的access数据库性能就开始明显下降，超过100M以后，出错、运行慢的问题会更加突出。尽管可以如动网7.0以后那样，从程序的角度尽量优化以图提高性能，但是不能从根本上解决问题。 <br/>这时也许使用微软的SQL Server数据库就是最可能的办法，当然也可以使用其它的如Oracle、MySQL等等，但是作为改写来说，由于同为微软的产品，改写成SQL Server应该是最省力的办法。 <br/><br/>一、改写前提： <br/><br/>系统已经安装好SQL Server2000并且打上了SP3补丁；安装好Office套件里面的Access；使用一个支持纯文本编辑并且带有行号显示的编辑器，推荐Ultra Edit，当然也可以使用FrontPage2003，不过以前的版本行号显示不太好用。 <br/><br/>个人能力要求：会基本的asp语法、access数据库的操作、SQLServer企业管理器的基本操作。 <br/><br/>二、数据库的准备 <br/><br/>一般来说有两种情况： <br/>1、程序提供了SQL数据库格式：有一个MDF文件，或者提供了创建SQL数据库的SQL脚本文件（后缀名为.sql）。 <br/>如果有mdf文件，可以用企业管理器直接附加上，如果提供的是sql脚本文件，那么就先用企业管理器自己创建一个sql数据库，然后数据库用企业管理器中的查询分析器运行这个脚本创建数据库表。 <br/>这样建立的数据库基本不用再去改写什么了。 <br/>2、更多的是没有提供SQL数据库或脚本文件的，这时，就要自己来做这一切了，这也是我们这个帖子主要解决的问题。一般这样的程序会提供一个access数据库，这样你就用企业管理器导入access数据库，导入后需要改写下面一些东西： <br/>对照原来的access，改写下面的部分： <br/>（1）sql数据库表是没有自动字段的，因此原来access中的自动字段被转换成了普通字段，需要手工改成标识类型，增量为1。 <br/>（2）所有的时间字段，如果定义了默认值，那么原来肯定是now()，需要改成getdate() <br/>（3）原来字段的默认值一般都不会自动引入，需要对照原表的字段手工添加。 <br/>（4）由于数据库的不同，access和sql的字段类型很多转换后就变化了，比如原来的《是否》字段会被转换成bit或者int，备注字段被转换成longtext，text字段转换成varchar等等，一般来说不会影响程序运行，如果有问题，我们在下面的程序改写部分再说。 <br/>（5）如果你要用一个For SQL的程序，里面用到了存储过程，那么你应该有这个程序本身建立SQL数据库的方法：有其本身的SQL数据库文件，或者sql脚本；如果没有的话，采用导入access数据库的方式是无法建立存储过程的，这样你最好放弃这个For SQL的程序版本，使用同样版本的For Access的程序，导入access数据库，然后用下面的改写方法自己改成SQL版本的程序。 <br/><br/>三、连接字符串的改写 <br/><br/>可参考动网的这段，分别是针对access和SQL的 <br/>Dim ConnStr <br/>If IsSqlDataBase = 1 Then <br/>'sql数据库连接参数：数据库名、用户密码、用户名、连接名（本地用local，外地用IP） <br/>Dim SqlDatabaseName,SqlPassword,SqlUsername,SqlLocalName <br/>SqlDatabaseName = "dvbbs7" <br/>SqlPassword = "" <br/>SqlUsername = "dvbbs" <br/>SqlLocalName = "(local)" <br/>ConnStr = "Provider = Sqloledb; User & SqlUsername & "; Password = " & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source = " & SqlLocalName & ";" <br/>Else <br/>'免费用户第一次使用请修改本处数据库地址并相应修改data目录中数据库名称，如将dvbbs6.mdb修改为dvbbs6.asp <br/>'http://www.knowsky.com/<br/>Db = "data/fengerqingqing.mdb" <br/>ConnStr = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = " & Server.MapPath(db) <br/>End If <br/>On Error Resume Next <br/>Set conn = Server.CreateObject("ADODB.Connection") <br/>conn.open ConnStr <br/><br/>当然你使用SQL的话，有关access的使用语句可以删除，就是else后面到on error resume next前面，变成这样： <br/><br/>Dim ConnStr <br/>'sql数据库连接参数：数据库名、用户密码、用户名、连接名（本地用local，外地用IP） <br/>Dim SqlDatabaseName,SqlPassword,SqlUsername,SqlLocalName <br/>SqlDatabaseName = "dvbbs7" <br/>SqlPassword = "" <br/>SqlUsername = "dvbbs" <br/>SqlLocalName = "(local)" <br/>ConnStr = "Provider = Sqloledb; User & SqlUsername & "; Password = " & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source = " & SqlLocalName & ";" <br/>On Error Resume Next <br/>Set conn = Server.CreateObject("ADODB.Connection") <br/>conn.open ConnStr <br/><br/>也可以简洁一些，写成这样： <br/>Set conn = Server.CreateObject("ADODB.Connection") <br/>conn.open "Provider = Sqloledb; User Password = 1234567; Initial Catalog = dvbbs7; Data Source = (local);" <br/>里面的数据库名称、数据源、用户、密码根据自己的实际情况改写一下。 <br/><br/>四、程序的改写 <br/><br/>这也有两种情况 <br/>1、如果你幸运，拿到的是For SQL的程序，那么如果上面的数据库建立过程没有遇到麻烦，程序基本上就可以运行了，出错的话，只是程序本身的bug，如何修改不是这个帖子讨论的内容，就不赘述了。 <br/>2、大多数情况，程序本身是For Access的，与For SQL的程序差别主要是程序中使用到的SQL查询语句。注意，SQL查询语句是数据库应用不可缺少的部分，不管是For SQL还是For Aceess的程序使用的语法大体差不多，但是有一些微妙的差别，正是这些差别，造成了程序的不通用，也是我们需要修改的主要内容。这样一般要修改的部分如下： <br/>（1）时间函数的问题：SQL数据库的时间函数与access不同，最常见的是取现在时间的函数，access是now()，SQL是getdate()。因此凡是在where子句中使用了now()的地方都要改成getdate();注意，now()函数在asp程序本身也要使用，凡是不在数据库查询或执行语句中使用的now()函数千万不要改。 <br/>（2）时间比较函数：datediff('d','时间1'，‘时间2’)这是access查询用的格式，SQl中这些引号都要去掉，同时时间格式的前后可能加上了#，这也要去掉。同样这也是指在sql语句中的，在asp语句中的要保持原样。 <br/>（3）空值的表示：在access中，判断空值一般用是否＝""来表示，但是这在SQL中往往出错，如果遇到出错的问题或者程序运行不正常，可以改成如这样判断：where (name is null) <br/>（4）真假值判断：access中可以用＝true、＝false来判断，但是在SQL中就会出错，因此在SQL查询或执行语句中这类判断要分别改成＝1、＝0。注意一点：有些程序虽然写成＝“true”，但是由于有引号，所以这个字段是字符类型的，你不能改成＝1，保持原样即可。 <br/><br/>以上是比较常见的改写的地方，还有一些不太常见，如果遇到了可以在此回帖讨论。 <br/><br/>五、程序的调试 <br/><br/>前面推荐使用带有行号的编辑器，是因为上述的改写不大可能是直接搜索程序源码来做，很难找全。 <br/>我采取的方式一般这样：数据库改写完成，直接调试程序，出错后，看看出错的提示，找到相应文件的代码行，但是根源往往不是那行，比如出错的语句是：conn.execute(sql)，但是这句本身是没有错的，错误原因是里面的这个sql字符串，那就向上看这个sql字符串是如何生成的，按照上面所说的程序修改办法修改。 <br/><br/>数据库导入以后，自动增加字段需要重写，所有的数字类型需要增加长度，最好用decimal。 <br/><br/>所有的默认值都丢失了。主要是数字类型和日期类型。 <br/><br/>所有now()，time()，date()要改成getdate()。 <br/><br/>所有datediff('d', 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数据库进行删除纪录时用："delete * from user where ,而对SQL SERVER数据库进行删除是用："delete user where . <br/><br/>日期函数不相同，在对ACCESS数据库处理中，可用date()、time()等函数，但对SQL SERVER数据库处理中，只能用datediff,dateadd等函数，而不能用date()、time()等函数。 <br/><br/>在对ACCESS数据库处理中,sql语句中直接可以用一些VB的函数，像cstr()函数，而对SQL SERVER数据库处理中，却不能用。 <br/>下表比较了MicrosoftAccess数据库（MicrosoftAccess数据库：数据和对象（如表、查询或窗体）组成的集合，与特定的主题或用途有关。MicrosoftJet数据库引擎用于管理数据。）和MicrosoftAccess项目（MicrosoftAccess项目：与MicrosoftSQLServer数据库连接且用于创建客户/服务器应用程序的Access文件。项目文件中不包含任何数据或基于数据定义的对象（如表或视图）。）的数据类型（数据类型：决定字段可拥有的数据类型的字段特征。数据类型包括Boolean、Integer、Long、Currency、Single、Double、Date、String和Variant（默认））。 <br/><br/><br/>MicrosoftAccess数据类型SQLServer数据类型 <br/>是/否（“是/否”数据类型：一种字段数据类型，用于只有两种可能值（如是或否、True或False）的字段。不允许有Null值。）bit（bit数据类型：在Access项目中，一种存储值为1或0的数据类型。接受1和0以外的整数值，但总是将其解释为1。） <br/>数字（“数字”数据类型：MicrosoftAccess数据库中的一种字段数据类型，用于将在数学运算中使用的数值数据。但是，若要显示或计算货币值，则应使用“货币”数据类型。）（字节）tinyint（tinyint数据类型：Access项目中的一种占一个字节（8位）的数据类型，用于存储从0到255范围内的整数。） <br/>数字（整型）smallint（smallint数据类型：Access项目中的一种2字节（16位）数据类型，存储位于-2^15(-32,768)与2^15-1(32,767)之间的数字。） <br/>数字（长整型）int（int数据类型：Access项目中的一种4字节（32位）数据类型，存储位于-2^31(-2,147,483,648)与2^31-1(2,147,483,647)之间的数字。） <br/>数字（单精度浮点型）real（real数据类型：在Access项目中，一种近似的数值数据类型，精度为7位，正值取值范围大致从1.18E-38到3.40E+38，负值取值范围大致从-1.18E-38到-3.40E+38，也可以取0。） <br/>（无等价的数据类型）bigint（bigint数据类型：Access项目中的一种8字节（64位）数据类型，存储位于-2^63(-9,223,372,036,854,775,808)与2^63-1(9,223,372,036,854,775,807)之间的数字。） <br/>数字（双精度浮点型）float（float数据类型：在Access项目中，一种近似的数值数据类型，精度为15位。它所存储的正值范围大致是从2.23E-308到1.79E+308，负值范围大致是从-2.23E-308到-1.79E+308，也可以为0。） <br/>货币（“货币”数据类型：MicrosoftAccess数据库中的一种数据类型，用于与货币有关的计算或其精确度极其重要的定点计算。）money（money数据类型：在Access项目中，用于存储货币值的数据类型，取值范围从-922,337,203,685,477.5707到922,337,203,685,477.5807，精确度为万分之一个货币单位。） <br/><br/>smallmoney（smallmoney数据类型：Access项目中的一种存储货币值的数据类型，取值范围从-214,748.3648到214,748.3647，精确度为万分之一个货币单位。当显示smallmoney值时，会将它们四舍五入为两个小数位。） <br/>小数/数值（decimal数据类型（Access数据库）：精确的数值数据类型，用于存储-10^38-1到10^38-1的值。可以指定数值范围（最大总位数）和精度（小数点右边的最大位数）。）decimal（decimal数据类型（Access项目）：精确的数值数据类型，用于存储-10^38-1到10^38-1的值。可以指定数值范围（最大总位数）和精度（小数点右边的最大位数）。） <br/><br/>numeric（numeric数据类型：在Access项目中，一种精确的数值数据类型，取值从-10^38-1到10^38-1。可以指定数值范围（最大总位数）和精度（小数点右边的最大位数）。） <br/>日期/时间（“日期/时间”数据类型：Access数据库的一种数据类型，用来存放日期和时间信息。）datetime（datetime数据类型：在Access项目中，日期和时间的数据类型，范围从1753年1月1日到9999年12月31日，精确度为三百分之一秒，即3.33毫秒。） <br/><br/>smalldatetime（smalldatetime数据类型：Access项目中的一种日期和时间数据类型，精度不如datetime时间数据类型。数据取值范围从1900年1月1日到2079年6月6日，精确度为一分钟。） <br/>自动编号（“自动编号”数据类型：MicrosoftAccess数据库中的一种字段数据类型，当向表中添加一条新记录时，这种数据类型会自动为每条记录存储一个唯一的编号。可以产生三种编号：顺序号、随机号和同步复制ID。）（递增）int（int数据类型：Access项目中的一种4字节（32位）数据类型，存储位于-2^31(-2,147,483,648)与2^31-1(2,147,483,647)之间的数字。）（定义了Identity属性） <br/>文本（“文本”数据类型：MicrosoftAccess数据库中的一种字段数据类型。“文本”数据类型最多可以包含255个字符，或者是由FieldSize属性指定的一个小一些的字符数。）(n)varchar(n)（varchar(n)数据类型：Access项目中的一种可变长度的数据类型，最大长度为8,000个ANSI字符。） <br/><br/>nvarchar(n)（nvarchar(n)数据类型：在Access项目中，一种可变长度的数据类型，最多可含4,000个Unicode字符。Unicode字符每字符占两个字节，而且支持所有国际字符。） <br/>备注（“备注”数据类型：在MicrosoftAccess数据库中的一种字段数据类型。“备注”字段最多可以包含65,535个字符。）text（text数据类型：Access项目中的一种长度可变的数据类型，最多可存储2^31-1(2,147,483,647)个字符；默认长度为16。） <br/>OLE对象（“OLE对象”数据类型：字段的数据类型之一，用于在其他应用程序中创建的、可链接或嵌入（插入）到Access数据库中的对象。）image（image数据类型：在Access项目中，一种长度可变的数据类型，最多可存储2^31-1(2,147,483,647)字节的二进制数据。image数据类型用来存储BLOB（二进制大对象），如图片、文档、声音和已编译代码。） <br/>同步复制ID（又名全局唯一标识符（GUID：在Access数据库中，一种用于建立同步复制唯一标识符的16字节字段。GUID用于标识副本、副本集、表、记录和其他对象。在Access数据库中，GUID是指同步复制ID。）(GUID)）uniqueidentifier（uniqueidentifier数据类型：在Access项目中，16字节的全局唯一标识符(GUID)。）（仅适于SQLServer7.0或更高版本） <br/>超链接（“超链接”数据类型：存储超链接地址的Access数据库字段的数据类型。地址最多可以包含四部分，用以下语法格式编写：displaytext#address#subaddress#。）char（char数据类型：在Access项目中，一种固定长度的数据类型，最多可含8,000个ANSI字符。）, <br/><br/>nchar（nchar数据类型：在Access项目中，一种固定长度的数据类型，最多可含4,000个Unicode字符。Unicode字符每字符占两个字节，而且支持所有国际字符。）,varchar,nvarchar（Hyperlink属性设为Yes） <br/>（无等价的数据类型）varbinary（varbinary数据类型：Access项目中的一种可变长度的数据类型，最多可存储8,000字节的二进制数据。） <br/>（无等价的数据类型）smallint（smallint数据类型：Access项目中的一种2字节（16位）数据类型，存储位于-2^15(-32,768)与2^15-1(32,767)之间的数字。） <br/>（无等价的数据类型）timestamp（timestamp数据类型：在Access项目中，一种每插入或更新一行就会自动更新的数据类型。timestamp列中的值不是datetime数据，而是binary(8)或varbinary(8)，标明了数据修改的顺序。） <br/>（无等价的数据类型）charnchar <br/>（无等价的数据类型）sql_variant（sql_variant数据类型：Access项目中的一种数据类型，存储除text、ntext、image、timestamp和sql_variant类型以外的多种数据类型的值。在列、参数、变量或用户定义函数的返回值中使用。） <br/>（无等价的数据类型）用户定义（用户定义的数据类型：在MicrosoftSQLServer数据库中，允许某列包含的数据的类型定义，由用户利用现有的系统数据类型定义。规则和默认值仅可以绑定到用户定义的数据类型。） <br/><br/>注释在Access项目或SQLServer数据库中，前缀“n”代表“国家/地区”，意思是这个数据类型是启用Unicode的。在Access数据库中，全部文本列在默认情况下都是启用Unicode的。 <br/>ACCESS转SQL需要注意的问题 <br/>2006-2-13 16:01:20 <br/>很多朋友想用SQL2000数据库的编程方法，但是却又苦于自己是学ACCESS的，对SQL只是一点点的了解而已，这里我给大家提供以下参考---将ACCESS转化成SQL2000的方法和注意事项 <br/>一，首先，我说的是在ACCESS2000，SQL2000之间转换，其他的我也还没有尝试过，希望大家多多试验，肯定是有办法的； <br/>二，转换的方法 <br/>1，打开”控制面板“下”管理工具“中的”数据库源“； <br/>2，按”添加“添加一个新的数据源，在选择栏里选”DriverdomicrosoftAccess <br/>(*.mdb)”,完成后将出现一个框, <br/><br/>在”数据库源“里面输入你想写的名称，我取名叫“ABC”,说明不需要填，接着，按下面的选择，寻找你的数据库地址和选中（注意，请先备份自己的ACCESS数据库），然后确定。 <br/>数据源在这里建好了，剩下转换了。 <br/><br/>3，打开SQL2000企业管理器，进入数据库，新建一个空的数据库“ABC”； <br/>4，选择新建立的数据库，按鼠标右键，选择“所有任务”下“导入数据”，按“下一步”继续； <br/>5，在数据库源下拉但中选择”DriverdomicrosoftAccess(*.mdb)“，在”用户/系统DSN“中，选种你刚才添加的”ABC“，按”下一步“； <br/>6，“目的”不需要修改，选择服务器（一般下为自己的本机"local",也可以选择服务器地址或者局域网地址,确定你的权限是否可以操作,),"使用WINDOWS身份验证"指用自己的系统管理员身份操作,"使用SQL身份操作验证"可以用于网站的操作,推荐用后者; <br/>7,选上"使用SQL身份操作验证"后,填写你的用户名和密码,我自己选择的是系统默认号码"sa","****",数据库选择刚新建的"ABC",按"下一步"; <br/>8,这一步的两个单项选择,"从数据源复制表和视图"与"用一条查询指令指定要传输的数据",选择前者,按"下一步"继续; <br/>9,这里将出现你自己ACCESS数据库的表,按"全选"后,下一步; <br/>10,"DTS导入/导出向导",看"立即运行"被选中按"下一步", <br/>11,按"完成"继续; <br/>12,这个步骤你将看到你的数据被导入SQL2000里面,当出现"已经成功把XXX个表导入到数据库"的字样,而且所有的表前面都有绿色的勾,就表示成功导入所有数据,如果中途出现问题或者表前面有红色的*的话,说明该表没有成功导入,这时就要回去查看自己的操作是否正确了. <br/><br/>三,数据修改 <br/>1,由于SQL2000里面没有"自动编号",所以你的以"自动编号"设置的字段都会变成非空的字段,这就必须手工修改这些字段,并把他的"标示"选择"是",种子为"1",增量为"1", <br/>2,另外,ACCESS2000转换成SQL2000后,原来属性为"是/否"的字段将被转换成非空的"bit",这时候你必须修改成自己想要的属性了; <br/>3,另外,大家要注意对时间函数的把握.ACCESS与SQL是有很多不同的. <br/><br/><br/>四、相关的字段问题 <br/>1.ACCESS的数据库中的自动编号类型在转化时，sqlserver并没有将它设为自动编号型，我们需在SQL创建语句中加上identity，表示自动编号！ <br/>2.转化时，跟日期有关的字段，SQLSERVER默认为smalldatetime型，我们最好将它变为datetime型，因为datetime型的范围比smalldatetime型大。我遇见这种情况，用smalldatetime型时，转化失败，而用datetime型时，转化成功。 <br/>3.对此两种数据库进行操作的sql语句不全相同，例如：在对ACCESS数据库进行删除纪录时用："delete*fromuserwhereid=10",而对SQLSERVER数据库进行删除是用："deleteuserwhereid=10". <br/>4.日期函数不相同，在对ACCESS数据库处理中，可用date()、time()等函数，但对SQLSERVER数据库处理中，只能用datediff,dateadd等函数，而不能用date()、time()等函数。 <br/>5.在对ACCESS数据库处理中,sql语句中直接可以用一些VB的函数，像cstr()函数，而对SQLSERVER数据库处理中，却不能用。 <br/><br/>五、相关语句问题 <br/>自动增加字段需要重写。在access中经常使用的自动编号字段，导入到mssql后，他并不是自增型的int，需要手工设置，把导入后的自动编号字段的标识的“否”改为“是”，“种子”和“递增量”都为“1”，才能成为自动编号 <br/><br/><br/>所有的默认值都丢失了。主要是数字类型和日期类型 <br/><br/><br/>所有now()，time()，date()要改成getdate() <br/><br/><br/>所有datediff('d',time1,time2)要改成datediff(day,time1,time2) <br/><br/><br/>所有datediff('ww',time1,time2)要改成datediff(week,time1,time2) <br/><br/><br/>所有datediff('d',time1,time2)要改成datediff(day,time1,time2) <br/><br/><br/>在mssqlserver中，有许多保留字，在access中是没有的，当你把数据导入到mssql的时候，问题就出来了。mssql在导入的时候，会自动给这些字段（包括数据库中的表名）加上“[字段名]”，因此，你必须修改你的脚本，把相应的字段名字（或者表名字）加上中括号，或改变字段名字为不是mssql的保留字 <br/><br/><br/>在用access关于时间的使用，大家喜欢使用“select*fromaaaawhiletime="&now()”这样的sql语句，然而，在mssql中没有“now()”这个函数，而是使用“getdate()”，所以，所有的sql语句中的“now()”必须换成“getdate()”。 <br/><br/><br/>日期函数不相同，在对ACCESS数据库处理中，可用date()、time()等函数，但对 <br/>SQLSERVER数据库处理中，只能用datediff,dateadd等函数，而不能用date()、time()等函数。 <br/><br/>转化时，跟日期有关的字段，SQLSERVER默认为smalldatetime型，我们最好将它变为datetime型。<br/>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?57</link>
<title><![CDATA[ADO连接Access的几种规范做法]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Thu, 01 Feb 2007 02:48:23 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?57</guid> 
<description>
<![CDATA[ 
	ADO数据对象用来连接数据库的方式有两种,分别是ODBC和OLE DB方式 <br/><br/>(一) 使用OLE DB方式<br/>******************************************************** <br/>*** OLE DB Provider for Microsoft Jet<br/>******************************************************** <br/>Dim oConn,strConn<br/>Set oConn=Server.CreateObject("ADODB.Connection")<br/>StrConn= "Provider=Microsoft.Jet.OLEDB.4.0;" & _<br/>"Data Source=c:&#92;somepath&#92;myDb.mdb;" & _ <br/>"User & _<br/>"Password=;"<br/>oConn.Open strConn<br/><br/><br/>********************************************************<br/>*** OLE DB Provider for ODBC Databases <br/>******************************************************** <br/>访问MS Access数据库<br/>Dim oConn,strConn<br/>Set oConn=Server.CreateObject("ADODB.Connection")<br/>StrConn= "Provider=MSDASQL;" & _ <br/>"Driver=&#123;Microsoft Access Driver (*.mdb)&#125;;" & _<br/>"Dbq=c:&#92;somepath&#92;mydb.mdb;" & _<br/>"Uid=myUsername;" & _<br/>"Pwd=myPassword;"<br/>oConn.Open strConn<br/><br/>(二) 使用ODBC方式<br/>******************************************************** <br/>*** ODBC Driver for Access<br/>******************************************************** <br/>Dim oConn,strConn<br/>Set oConn=Server.CreateObject("ADODB.Connection")<br/>StrConn= "Driver=&#123;Microsoft Access Driver (*.mdb)&#125;;" & _ <br/>"Dbq="&Server.MapPath("Testdb.mdb"); & _<br/>"Uid=AdminAccount;" & _<br/>"Pwd=Password;"<br/>oConn.Open strConn<br/><br/>
]]>
</description>
</item><item>
<link>http://vir.jxstnu.edu.cn/xieyunc/read.php?60</link>
<title><![CDATA[利用数据库复制技术 实现MS-SQL数据同步更新]]></title> 
<author>xieyunc &lt;xieyunc@jxstnu.cn&gt;</author>
<category><![CDATA[数据库　]]></category>
<pubDate>Sat, 02 Dec 2006 02:51:40 +0000</pubDate> 
<guid>http://vir.jxstnu.edu.cn/xieyunc/read.php?60</guid> 
<description>
<![CDATA[ 
	********* &nbsp; 利用数据库复制技术 &nbsp; 实现数据同步更新 &nbsp; ********* &nbsp;<br/> &nbsp; &nbsp; <br/> &nbsp;复制的概念 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;Microsoft SQL Server 2000 的复制是在数据库之间对数据和数据库对象进行复制和分发并<br/> &nbsp;进行同步以确保其一致性的一组技术。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;使用复制可以将数据分发到不同位置，通过局域网、使用拨号连接、通过 Internet分 &nbsp; <br/> &nbsp;发给远程或移动用户。复制还能够使用户提高应用程序性能，根据数据的使用方式物理 &nbsp; <br/> &nbsp;分隔数据（例如，将联机事务处理 &nbsp; (OLTP) &nbsp; 和决策支持系统分开），或者跨越多个服务 &nbsp; <br/> &nbsp;器分布数据库处理。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; <br/> &nbsp;SQL复制的基本元素包括 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;发布服务器、订阅服务器、分发服务器、发布、项目 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;发布服务器 &nbsp; <br/> &nbsp;发布服务器是提供数据以便复制到其它服务器的服务器。发布服务器可以具有一个或多个 &nbsp; <br/> &nbsp;发布，每个发布代表一组逻辑相关的数据。除了指定其中哪些数据需要复制之外，发布服 &nbsp; <br/> &nbsp;务器还检测事务复制期间发生更改的数据并维护有关此站点上所有发布的信息。 &nbsp; &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;分发服务器 &nbsp; <br/> &nbsp;分发服务器是作为分发数据库宿主并存储历史数据和/或事务以及元数据的服务器。分发 &nbsp; <br/> &nbsp;服务器的角色根据执行的复制类型而不同。有关更多信息，请参见复制类型。 &nbsp; <br/> &nbsp;远程分发服务器是独立于发布服务器并配置为复制的分发服务器的服务器。本地分发服务 &nbsp; <br/> &nbsp;器是既配置为复制的发布服务器又配置为复制的分发服务器的服务器。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;订阅服务器 &nbsp; <br/> &nbsp;订阅服务器是接收复制数据的服务器。订阅服务器订阅的是发布而不是发布中分离的项目； &nbsp; <br/> &nbsp;并且订阅服务器只订阅其需要的发布，而不是发布服务器上所有可用的发布。根据复制的类 &nbsp; <br/> &nbsp;型和所选择的复制选项，订阅服务器还可以将数据更改传播回发布服务器或将数据重新发布 &nbsp; <br/> &nbsp;到其它订阅服务器。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;发布 &nbsp; <br/> &nbsp;发布是一个数据库中的一个或多个项目的集合。这种多个项目的分组使得指定逻辑相关的一 &nbsp; <br/> &nbsp;组数据和数据库对象以一起复制变得更容易。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;项目 &nbsp; <br/> &nbsp;项目是指定要复制的数据表、数据分区或数据库对象。项目可以是完整的表、某几列（使用垂 &nbsp; <br/> &nbsp;直筛选）、某几行（使用水平筛选）、存储过程或视图定义、存储过程的执行、视图、索引视图 &nbsp; <br/> &nbsp;或用户定义函数。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;订阅 &nbsp; <br/> &nbsp;订阅是对数据或数据库对象的复本的请求。订阅定义将接收的发布和接收的时间、地点。订阅的 &nbsp; <br/> &nbsp;同步或数据分发可以由发布服务器（强制订阅）或订阅服务器（请求订阅）请求。发布可以支持 &nbsp; <br/> &nbsp;强制订阅和请求订阅的混合。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; <br/> &nbsp;SQL复制的工作原理 &nbsp; <br/> &nbsp;SQL &nbsp; SERVER &nbsp; 主要采用出版物、订阅的方式来处理复制。源数据所在的服务器是出版服务 &nbsp; <br/> &nbsp;器，负责发表数据。出版服务器把要发表的数据的所有改变情况的拷贝复制到分发服务器 &nbsp; <br/> &nbsp;分发服务器包含有一个分发数据库，可接收数据的所有改变，并保存这些改变，再把这些 &nbsp; <br/> &nbsp;改变分发给订阅服务器 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; <br/> &nbsp;SQL &nbsp; SERVER复制技术类型,三种复制技术，分别是(详细的说明参考SQL联机帮助)： &nbsp; <br/> &nbsp;1、快照复制 &nbsp; <br/> &nbsp;2、事务复制 &nbsp; <br/> &nbsp;3、合并复制 &nbsp; <br/> &nbsp;Top<br/><br/>zjcxc（邹建）回复于 2004-06-15 07:42:45 得分 0 <br/>下介绍实现复制的步骤。(以快照复制为例) &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;准备工作: &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;1.在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作: &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;我的电脑--D:&#92; &nbsp; 新建一个目录,名为: &nbsp; PUB &nbsp; <br/> &nbsp;--右键这个新建的目录 &nbsp; <br/> &nbsp;--属性--共享 &nbsp; <br/> &nbsp;--选择"共享该文件夹"(另外还可以通过"权限"按纽来设置具体的用户权限 &nbsp; <br/> &nbsp;--确定 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;2.设置SQL代理(SQLSERVERAGENT)服务的启动用户 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;开始--程序--管理工具--服务 &nbsp; <br/> &nbsp;--右键SQLSERVERAGENT &nbsp; <br/> &nbsp;--属性--登陆--选择"此账户" &nbsp; <br/> &nbsp;--输入".&#92;Administrator",或者选择其他系统管理员 &nbsp; <br/> &nbsp;--"密码"中输入该用户的密码 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;3.设置SQL &nbsp; Server身份验证模式,解决连接时的权限问题 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;企业管理器 &nbsp; <br/> &nbsp;--右键SQL实例--属性 &nbsp; <br/> &nbsp;--安全性--身份验证 &nbsp; <br/> &nbsp;--选择"SQL &nbsp; Server &nbsp; 和 &nbsp; Windows" &nbsp; <br/> &nbsp;--确定 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;4.在发布服务器和订阅服务器上互相注册 &nbsp; <br/> &nbsp;企业管理器 &nbsp; <br/> &nbsp;--右键SQL &nbsp; Server组 &nbsp; <br/> &nbsp;--新建SQL &nbsp; Server注册... &nbsp; <br/> &nbsp;--下一步--可用的服务器中,输入你要注册的远程服务器名 --添加 &nbsp; <br/> &nbsp;--下一步--连接使用,选择第二个"SQL &nbsp; Server身份验证" &nbsp; <br/> &nbsp;--下一步--输入用户名和密码 &nbsp; <br/> &nbsp;--下一步--选择SQL &nbsp; Server组,也可以创建一个新组 &nbsp; <br/> &nbsp;--下一步--完成 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; &nbsp;<br/> &nbsp;正式开始: &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;1.配置发布服务器 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;a. &nbsp; 选中指定 &nbsp; [服务器] &nbsp; 节点 &nbsp; <br/> &nbsp;b. &nbsp; 从 &nbsp; [工具] &nbsp; 下拉菜单的 &nbsp; [复制] &nbsp; 子菜单中选择 &nbsp; [发布、订阅服务器和分发] &nbsp; 命令 &nbsp; <br/> &nbsp;c. &nbsp; 系统弹出一个对话框点 &nbsp; [下一步] &nbsp; 然后看着提示操作 &nbsp; <br/> &nbsp;--直到"指定快照文件夹" &nbsp; <br/> &nbsp;--在"快照文件夹"中输入准备工作中创建的目录: &nbsp; &#92;&#92;<服务器名>&#92;pub &nbsp; <br/> &nbsp;一[下一步] &nbsp; 直操作到完成。 &nbsp; <br/> &nbsp;d. &nbsp; 当完成了出版服务器的设置以后系统会为该服务器的树形结构中添加一个复制监视器 &nbsp; <br/> &nbsp;同时也生成一个分发数据库(distribution) &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;2.创建发布 &nbsp; <br/> &nbsp;a. &nbsp; 选中指定的服务器 &nbsp; <br/> &nbsp;b. &nbsp; 从 &nbsp; [工具] &nbsp; 菜单的 &nbsp; [复制] &nbsp; 子菜单中选择 &nbsp; [创建和管理发布] &nbsp; 命令。此时系统会弹出 &nbsp; <br/> &nbsp;一个对话框 &nbsp; <br/> &nbsp;c. &nbsp; 选择要创建发布的数据库，然后单击 &nbsp; [创建发布] &nbsp; <br/> &nbsp;d. &nbsp; 在 &nbsp; [创建发布向导] &nbsp; 的提示对话框中单击 &nbsp; [下一步] &nbsp; 系统就会弹出一个对话框。对话 &nbsp; <br/> &nbsp;框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个 &nbsp; <br/> &nbsp;大家可以去看看帮助) &nbsp; &nbsp; <br/> &nbsp;e. &nbsp; 单击 &nbsp; [下一步] &nbsp; 系统要求指定可以订阅该发布的数据库服务器类型，SQLSERVER允许在 &nbsp; <br/> &nbsp;不同的数据库如 &nbsp; ORACLE或ACCESS之间进行数据复制。但是在这里我们选择运行 &nbsp; <br/> &nbsp;"SQL &nbsp; SERVER &nbsp; 2000"的数据库服务器 &nbsp; <br/> &nbsp;f. &nbsp; 单击 &nbsp; [下一步] &nbsp; ,选择要发布的对象(如表,视图,存储过程,一般是表) &nbsp; <br/> &nbsp;g. &nbsp; 然后 &nbsp; [下一步] &nbsp; 直到操作完成。当完成出版物的创建后创建出版物的数据库也就变成了 &nbsp; <br/> &nbsp;一个共享数据库。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;--------------------------------------------------------------------------- &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;3.设计订阅 &nbsp; <br/> &nbsp;a. &nbsp; 选中指定的订阅服务器 &nbsp; <br/> &nbsp;b. &nbsp; 从 &nbsp; [工具] &nbsp; 下拉菜单中选择 &nbsp; [复制] &nbsp; 子菜单的 &nbsp; [请求订阅] &nbsp; <br/> &nbsp;c. &nbsp; 按照提示单击 &nbsp; [下一步] &nbsp; 操作直到系统会提示检查SQL &nbsp; SERVER代理服务的运行状态，执行 &nbsp; <br/> &nbsp;复制操作的前提条件是SQL &nbsp; SERVER代理服务必须已经启动。 &nbsp; <br/> &nbsp;d. &nbsp; 单击 &nbsp; [完成] &nbsp; 完成订阅操作。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp;---------------------------------------------------------------------------- &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;完成上面的步骤其实复制也就是成功了。但是如何来知道复制是否成功了呢？ &nbsp; <br/> &nbsp;这里可以通过这种方法来快速看是否成功。 &nbsp; <br/> &nbsp;展开出版服务器下面的复制——发布内容——右键发布内容——属性——击活——状态然后点立即运行代理程序接着点代理程序属性击活调度 &nbsp; <br/> &nbsp;把调度设置为每一天发生，每一分钟，在0：00：00和23：59：59之间。 &nbsp; <br/> &nbsp;接下来就是判断复制是否成功了打 &nbsp; <br/> &nbsp;开C:&#92;Program &nbsp; Files&#92;Microsoft &nbsp; SQL &nbsp; Server&#92;MSSQL&#92;REPLDATA&#92;unc&#92;XIAOWANGZI_database_database下面 &nbsp; <br/> &nbsp;看是不是有一些以时间做为文件名的文件夹差不多一分中就产生一个。 &nbsp; <br/> &nbsp;要是你还不信的话就打开你的数据库看在订阅的服务器的指定订阅数据库下看是不是看到了你刚才所发布的表 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;Top<br/><br/>zjcxc（邹建）回复于 2004-06-15 07:42:57 得分 0 <br/> &nbsp;<br/> &nbsp;/***************** &nbsp; 常见问题：权限问题 &nbsp; &nbsp; &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;启动代理的域用户账号必须具有读取发布-分发服务器目录的权限 &nbsp; <br/> &nbsp;你用的账号没有读取&#92;&#92;ServerA&#92;D$&#92;Program &nbsp; Files&#92;Microsoft &nbsp; SQL &nbsp; Server&#92;MSSQL&#92;repldata&#92;unc&#92;这个目录下的文件的权限。 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp;<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;启动代理的域用户账号必须具有读取发布-分发服务器目录的权限 &nbsp; <br/> &nbsp;----^^^^^^^^^^^^^^^在控制面板-->管理-->服务-->sqlagent-->属性里的那个启动用户 &nbsp; <br/> &nbsp; &nbsp;<br/> &nbsp;Top<br/><br/>netcoder（朱二）回复于 2004-06-15 12:39:39 得分 0 <br/>SQL控件是什么？Top<br/><br/>Pasu_Player（）回复于 2004-06-15 21:03:56 得分 0 <br/>各位大大，我想问的是它的存储过程有什么。 &nbsp; <br/> &nbsp;最好有一些底层一点的文章。 &nbsp; <br/> &nbsp;谢谢！！！谢谢！！！谢谢！！！谢谢！！！谢谢！！！Top<br/><br/>wqf0103（）回复于 2004-06-17 13:04:12 得分 0 <br/>非常谢谢，Top<br/><br/>你可能对以下的问题也比较感兴趣....<br/>SQL 7 复制问题。快照复制，为什么老是主键冲突？急！！！ <br/>怎么直接复制MS SQL Server的数据库？？？？？ <br/>delphi+MS SQL server 的数据库合并复制的实现？？？ <br/>求一sql语句(数据复制问题),急 <br/>MS SQLServer的复制？ <br/>sql的复制问题 <br/>特急：sql server数据库复制到另一计算机上后打不开 <br/>求一 SQL 语句，消除相同数据，复制到同一表(急) <br/>在线等待_MS SQL SERVER和ORACLE两结构相同的表之间数据的复制问题 <br/>
]]>
</description>
</item>
</channel>
</rss>