星期六, 十二月 15, 2007

电脑打开文件和点击鼠标右键特别慢(拔掉网线恢复正常)

如果电脑打开文件和点击鼠标右键特别慢,但是如果将网线拔掉,速度就会恢复正常,可以试试将以下键值改名:
[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers]

[HKEY_CLASSES_ROOT\*\shellex\PropertySheetHandlers]

右键菜单里的“新建文件夹”不见了,如何恢复?

添加:HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\NEW
值为默认{D969A300-E7FF-11d0-A93B-00A0C90F2719}

星期日, 六月 24, 2007

快毕业啦~!

回顾大学,真是乱七八糟的,刚上大学的时候,报了个双学位。后来想考研,考清华。又后来,想学JAVA。再后来,想出国,要公费的,好像想去什么滑铁卢大学,然后准备托福。后来认识了陈曦,分分合合。再后来,又想考研,考北大。再后来,决心把GRE单词背下来。再后来,想创业,去做什么点菜器。再后来,又想继续考研。考研失败后,想去找工作。刚开始想做JAVA程序员,后来想做C++程序员,后来想搞网络编程。我去北京呆了两个星期,回来后想搞游戏开发。一直到王韵姐结婚典礼上跟虎哥谈完话后,决定考天大。坚持了一段时间,被大姐说服,决定还是工作,还是别做程序员了,搞销售吧。感觉搞技术不刺激,OK,就这样。

【转】如何在毕业答辩中取得高分

如何在毕业答辩中取得高分

http://www.cer.net2003-02-17 10:57北京自考热线

答辩一般是几位相关专业的老师根据你的论文对你提一些问题,同时听取你的个人阐述,以了解你对论文的熟悉性。一般各位学友应按以下步骤进行:

  1、首先阐述个人的论文简介;
  2、边演示边结合你的论文进行讲解;
  3、回答老师的问题(要说明的是老师可能在任何时候提问,不一定要到最后才提问)结合以上的步骤,你可能已经知道自己该怎样做了。但我还要提醒你注意以下几点,这才是一般人容易疏漏的地方,同时又是很行之有效的方法:
   a、一定要显出自信
    答辩老师会时刻盯著您的眼睛,他们也许真的很想看出你的破绽:),自信会很有效的打破他们的任何企图。使你自信的方法只有自己看熟论文、搞懂论文的原理与 步骤。同时,让自己的眼睛注视着各位老师,尽量以站姿进行答辩,并保持中等偏慢的语速。这些措施都能使你显得充满自信!
   b、预先设想老师会问的问题
   如果你已经对老师问的问题有了预先的准备,那答辩还有什么可怕的呢?实战前总结自己的毕设,回忆制作中的难点与重点并结合自己的论文,写出10-15个问题就足够了(一般答辩提问数量在3-6个问题),当然更重要的是一定要准备好这些问题的答案啦!
   计算机类专业答辩一般老师提问都行如以下的问题:
   软件类:这个功能你是如何实现的?使用了怎样的技术?采用了何种数据结构?那些是你编写,那些是自动完成?
   硬件类:使用了那种器件?该器件有何种特点?
   c、准备好了吗?最后,让自己按以上的三个步骤全部演习一遍,别以为没有必要,事实证明它是非常有效的。
   最后,再提醒各位学友一点:请注意你的礼貌问题,上台要向各位来时问好;征求老师的同意后再开始讲述;答辩完后,就算你怎样不情愿,也要谢谢各位老师。记住,给各位老师留一个礼貌自信的形象是对你非常有好处的!

转载自http://zikao.eol.cn/article/20030217/3077481.shtml


星期四, 六月 14, 2007

【转】sql存储过程基础语法

sql存储过程基础语法这是一个储存过程的基础的创建和简单应用,希望对大家有点帮助,不足之处肯定会有,算是抛砖引玉吧。
CREATE PROCEDURE创建存储过程,存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL 语句的集合。
可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时过程)。
也可以创建在 Microsoft® SQL Server™ 启动时自动运行的存储过程。
语法CREATE PROC [ EDURE ] procedure_name [ ; number ] [ { @parameter data_type } [ VARYING ] [ = default ] [ OUTPUT ] ] [ ,...n ]
[ WITH { RECOMPILE ENCRYPTION RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
参数procedure_name
新存储过程的名称。过程名必须符合标识符规则,且对于数据库及其所有者必须唯一。有关更多信息,请参见使用标识符。
要创建局部临时过程,可以在 procedure_name 前面加一个编号符 (#procedure_name),要创建全局临时过程,可以在 procedure_name 前面加两个编号符 (##procedure_name)。完整的名称(包括 # 或 ##)不能超过 128 个字符。指定过程所有者的名称是可选的。
;number
是可选的整数,用来对同名的过程分组,以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。例如,名为 orders 的应用程序使用的过程可以命名为 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 语句将除去整个组。如果名称中包含定界标识符,则数字不应包含在标识符中,只应在 procedure_name 前后使用适当的定界符。
@parameter
过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的默认值)。存储过程最多可以有 2.100 个参数。
使用 @ 符号作为第一个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身;相同的参数名称可以用在其它过程中。默认情况下,参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。有关更多信息,请参见 EXECUTE。
data_type
参数的数据类型。所有数据类型(包括 text、ntext 和 image)均可以用作存储过程的参数。不过,cursor 数据类型只能用于 OUTPUT 参数。如果指定的数据类型为 cursor,也必须同时指定 VARYING 和 OUTPUT 关键字。有关 SQL Server 提供的数据类型及其语法的更多信息,请参见数据类型。
说明 对于可以是 cursor 数据类型的输出参数,没有最大数目的限制。
VARYING
指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变化)。仅适用于游标参数。
default
参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。默认值必须是常量或 NULL。如果过程将对该参数使用 LIKE 关键字,那么默认值中可以包含通配符(%、_、[] 和 [^])。
OUTPUT
表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。使用 OUTPUT 参数可将信息返回给调用过程。Text、ntext 和 image 参数可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以是游标占位符。
n
表示最多可以指定 2.100 个参数的占位符。
{RECOMPILE ENCRYPTION RECOMPILE, ENCRYPTION}
RECOMPILE 表明 SQL Server 不会缓存该过程的计划,该过程将在运行时重新编译。在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时,请使用 RECOMPILE 选项。
ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。使用 ENCRYPTION 可防止将过程作为 SQL Server 复制的一部分发布。
说明 在升级过程中,SQL Server 利用存储在 syscomments 中的加密注释来重新创建加密过程。
FOR REPLICATION
指定不能在订阅服务器上执行为复制创建的存储过程。.使用 FOR REPLICATION 选项创建的存储过程可用作存储过程筛选,且只能在复制过程中执行。本选项不能和 WITH RECOMPILE 选项一起使用。
AS
指定过程要执行的操作。
sql_statement
过程中要包含的任意数目和类型的 Transact-SQL 语句。但有一些限制。
n
是表示此过程可以包含多条 Transact-SQL 语句的占位符。
注释存储过程的最大大小为 128 MB。
用户定义的存储过程只能在当前数据库中创建(临时过程除外,临时过程总是在 tempdb 中创建)。在单个批处理中,CREATE PROCEDURE 语句不能与其它 Transact-SQL 语句组合使用。
默认情况下,参数可为空。如果传递 NULL 参数值并且该参数在 CREATE 或 ALTER TABLE 语句中使用,而该语句中引用的列又不允许使用 NULL,则 SQL Server 会产生一条错误信息。为了防止向不允许使用 NULL 的列传递 NULL 参数值,应向过程中添加编程逻辑或为该列使用默认值(使用 CREATE 或 ALTER TABLE 的 DEFAULT 关键字)。
建议在存储过程的任何 CREATE TABLE 或 ALTER TABLE 语句中都为每列显式指定 NULL 或 NOT NULL,例如在创建临时表时。ANSI_DFLT_ON 和 ANSI_DFLT_OFF 选项控制 SQL Server 为列指派 NULL 或 NOT NULL 特性的方式(如果在 CREATE TABLE 或 ALTER TABLE 语句中没有指定的话)。如果某个连接执行的存储过程对这些选项的设置与创建该过程的连接的设置不同,则为第二个连接创建的表列可能会有不同的为空性,并且表现出不同的行为方式。如果为每个列显式声明了 NULL 或 NOT NULL,那么将对所有执行该存储过程的连接使用相同的为空性创建临时表。
在创建或更改存储过程时,SQL Server 将保存 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 的设置。执行存储过程时,将使用这些原始设置。因此,所有客户端会话的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 设置在执行存储过程时都将被忽略。在存储过程中出现的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 语句不影响存储过程的功能。
其它 SET 选项(例如 SET ARITHABORT、SET ANSI_WARNINGS 或 SET ANSI_PADDINGS)在创建或更改存储过程时不保存。如果存储过程的逻辑取决于特定的设置,应在过程开头添加一条 SET 语句,以确保设置正确。从存储过程中执行 SET 语句时,该设置只在存储过程完成之前有效。之后,设置将恢复为调用存储过程时的值。这使个别的客户端可以设置所需的选项,而不会影响存储过程的逻辑。
说明 SQL Server 是将空字符串解释为单个空格还是解释为真正的空字符串,由兼容级别设置控制。如果兼容级别小于或等于 65,SQL Server 就将空字符串解释为单个空格。如果兼容级别等于 70,则 SQL Server 将空字符串解释为空字符串。有关更多信息,请参见 sp_dbcmptlevel。
获得有关存储过程的信息若要显示用来创建过程的文本,请在过程所在的数据库中执行 sp_helptext,并使用过程名作为参数。
说明 使用 ENCRYPTION 选项创建的存储过程不能使用 sp_helptext 查看。
若要显示有关过程引用的对象的报表,请使用 sp_depends。
若要为过程重命名,请使用 sp_rename。
引用对象SQL Server 允许创建的存储过程引用尚不存在的对象。在创建时,只进行语法检查。执行时,如果高速缓存中尚无有效的计划,则编译存储过程以生成执行计划。只有在编译过程中才解析存储过程中引用的所有对象。因此,如果语法正确的存储过程引用了不存在的对象,则仍可以成功创建,但在运行时将失败,因为所引用的对象不存在。有关更多信息,请参见延迟名称解析和编译。
延迟名称解析和兼容级别SQL Server 允许 Transact-SQL 存储过程在创建时引用不存在的表。这种能力称为延迟名称解析。不过,如果 Transact-SQL 存储过程引用了该存储过程中定义的表,而兼容级别设置(通过执行 sp_dbcmptlevel 来设置)为 65,则在创建时会发出警告信息。而如果在运行时所引用的表不存在,将返回错误信息。有关更多信息,请参见 sp_dbcmptlevel 和延迟名称解析和编译。
执行存储过程成功执行 CREATE PROCEDURE 语句后,过程名称将存储在 sysobjects 系统表中,而 CREATE PROCEDURE 语句的文本将存储在 syscomments 中。第一次执行时,将编译该过程以确定检索数据的最佳访问计划。
使用 cursor 数据类型的参数存储过程只能将 cursor 数据类型用于 OUTPUT 参数。如果为某个参数指定了 cursor 数据类型,也必须指定 VARYING 和 OUTPUT 参数。如果为某个参数指定了 VARYING 关键字,则数据类型必须是 cursor,并且必须指定 OUTPUT 关键字。
说明 cursor 数据类型不能通过数据库 API(例如 OLE DB、ODBC、ADO 和 DB-Library)绑定到应用程序变量上。因为必须先绑定 OUTPUT 参数,应用程序才可以执行存储过程,所以带有 cursor OUTPUT 参数的存储过程不能通过数据库 API 调用。只有将 cursor OUTPUT 变量赋值给 Transact-SQL 局部 cursor 变量时,才可以通过 Transact-SQL 批处理、存储过程或触发器调用这些过程。
Cursor 输出参数在执行过程时,以下规则适用于 cursor 输出参数:
对于只进游标,游标的结果集中返回的行只是那些存储过程执行结束时处于或超出游标位置的行,例如: 在过程中的名为 RS 的 100 行结果集上打开一个非滚动游标。
过程提取结果集 RS 的头 5 行。
过程返回到其调用者。
返回到调用者的结果集 RS 由 RS 的第 6 到 100 行组成,调用者中的游标处于 RS 的第一行之前。 对于只进游标,如果存储过程完成后,游标位于第一行的前面,则整个结果集将返回给调用批处理、存储过程或触发器。返回时,游标将位于第一行的前面。
对于只进游标,如果存储过程完成后,游标的位置超出最后一行的结尾,则为调用批处理、存储过程或触发器返回空结果集。
说明 空结果集与空值不同。
对于可滚动游标,在存储过程执行结束时,结果集中的所有行均会返回给调用批处理、存储过程或触发器。返回时,游标保留在过程中最后一次执行提取时的位置。
对于任意类型的游标,如果游标关闭,则将空值传递回调用批处理、存储过程或触发器。如果将游标指派给一个参数,但该游标从未打开过,也会出现这种情况。
说明 关闭状态只有在返回时才有影响。例如,可以在过程中关闭游标,稍后再打开游标,然后将该游标的结果集返回给调用批处理、存储过程或触发器。
临时存储过程SQL Server 支持两种临时过程:局部临时过程和全局临时过程。局部临时过程只能由创建该过程的连接使用。全局临时过程则可由所有连接使用。局部临时过程在当前会话结束时自动除去。全局临时过程在使用该过程的最后一个会话结束时除去。通常是在创建该过程的会话结束时。
临时过程用 # 和 ## 命名,可以由任何用户创建。创建过程后,局部过程的所有者是唯一可以使用该过程的用户。执行局部临时过程的权限不能授予其他用户。如果创建了全局临时过程,则所有用户均可以访问该过程,权限不能显式废除。只有在 tempdb 数据库中具有显式 CREATE PROCEDURE 权限的用户,才可以在该数据库中显式创建临时过程(不使用编号符命名)。可以授予或废除这些过程中的权限。
说明 频繁使用临时存储过程会在 tempdb 中的系统表上产生争用,从而对性能产生负面影响。建议使用 sp_executesql 代替。sp_executesql 不在系统表中存储数据,因此可以避免这一问题。
自动执行存储过程SQL Server 启动时可以自动执行一个或多个存储过程。这些存储过程必须由系统管理员创建,并在 sysadmin 固定服务器角色下作为后台过程执行。这些过程不能有任何输入参数。
对启动过程的数目没有限制,但是要注意,每个启动过程在执行时都会占用一个连接。如果必须在启动时执行多个过程,但不需要并行执行,则可以指定一个过程作为启动过程,让该过程调用其它过程。这样就只占用一个连接。
在启动时恢复了最后一个数据库后,即开始执行存储过程。若要跳过这些存储过程的执行,请将启动参数指定为跟踪标记 4022。如果以最低配置启动 SQL Server(使用 -f 标记),则启动存储过程也不会执行。有关更多信息,请参见跟踪标记。
若要创建启动存储过程,必须作为 sysadmin 固定服务器角色的成员登录,并在 master 数据库中创建存储过程。
使用 sp_procoption 可以:
将现有存储过程指定为启动过程。
停止在 SQL Server 启动时执行过程。
查看 SQL Server 启动时执行的所有过程的列表。 存储过程嵌套存储过程可以嵌套,即一个存储过程可以调用另一个存储过程。在被调用过程开始执行时,嵌套级将增加,在被调用过程执行结束后,嵌套级将减少。如果超出最大的嵌套级,会使整个调用过程链失败。可用 @@NESTLEVEL 函数返回当前的嵌套级。
若要估计编译后的存储过程大小,请使用下列性能监视计数器。
性能监视器对象名 性能监视计数器名称 SQLServer:缓冲区管理器 高速缓存大小(页面数) SQLServer:高速缓存管理器 高速缓存命中率 高速缓存页 高速缓存对象计数*
* 各种分类的高速缓存对象均可以使用这些计数器,包括特殊 sql、准备 sql、过程、触发器等。
有关更多信息,请参见 SQL Server:Buffer Manager 对象和 SQL Server:Cache Manager 对象。
sql_statement 限制除了 SET SHOWPLAN_TEXT 和 SET SHOWPLAN_ALL 之外(这两个语句必须是批处理中仅有的语句),任何 SET 语句均可以在存储过程内部指定。所选择的 SET 选项在存储过程执行过程中有效,之后恢复为原来的设置。
如果其他用户要使用某个存储过程,那么在该存储过程内部,一些语句使用的对象名必须使用对象所有者的名称限定。这些语句包括:
ALTER TABLE
CREATE INDEX
CREATE TABLE
所有 DBCC 语句
DROP TABLE
DROP INDEX
TRUNCATE TABLE
UPDATE STATISTICS 权限CREATE PROCEDURE 的权限默认授予 sysadmin 固定服务器角色成员和 db_owner 和 db_ddladmin 固定数据库角色成员。sysadmin 固定服务器角色成员和 db_owner 固定数据库角色成员可以将 CREATE PROCEDURE 权限转让给其他用户。执行存储过程的权限授予过程的所有者,该所有者可以为其它数据库用户设置执行权限。
示例A. 使用带有复杂 SELECT 语句的简单过程下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。
USE pubsIF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info_all' AND type = 'P') DROP PROCEDURE au_info_allGOCREATE PROCEDURE au_info_allASSELECT au_lname, au_fname, title, pub_name FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_idGO
au_info_all 存储过程可以通过以下方法执行:
EXECUTE au_info_all-- OrEXEC au_info_all
如果该过程是批处理中的第一条语句,则可使用:
au_info_all
B. 使用带有参数的简单过程下面的存储过程从四个表的联接中只返回指定的作者(提供了姓名)、出版的书籍以及出版社。该存储过程接受与传递的参数精确匹配的值。
USE pubsIF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info' AND type = 'P') DROP PROCEDURE au_infoGOUSE pubsGOCREATE PROCEDURE au_info @lastname varchar(40), @firstname varchar(20) AS SELECT au_lname, au_fname, title, pub_name FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_id WHERE au_fname = @firstname AND au_lname = @lastnameGO
au_info 存储过程可以通过以下方法执行:
EXECUTE au_info 'Dull', 'Ann'-- OrEXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'-- OrEXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'-- OrEXEC au_info 'Dull', 'Ann'-- OrEXEC au_info @lastname = 'Dull', @firstname = 'Ann'-- OrEXEC au_info @firstname = 'Ann', @lastname = 'Dull'
如果该过程是批处理中的第一条语句,则可使用:
au_info 'Dull', 'Ann'-- Orau_info @lastname = 'Dull', @firstname = 'Ann'-- Orau_info @firstname = 'Ann', @lastname = 'Dull'
C. 使用带有通配符参数的简单过程下面的存储过程从四个表的联接中只返回指定的作者(提供了姓名)、出版的书籍以及出版社。该存储过程对传递的参数进行模式匹配,如果没有提供参数,则使用预设的默认值。
USE pubsIF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info2' AND type = 'P') DROP PROCEDURE au_info2GOUSE pubsGOCREATE PROCEDURE au_info2 @lastname varchar(30) = 'D%', @firstname varchar(18) = '%'AS SELECT au_lname, au_fname, title, pub_nameFROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_idWHERE au_fname LIKE @firstname AND au_lname LIKE @lastnameGO
au_info2 存储过程可以用多种组合执行。下面只列出了部分组合:
EXECUTE au_info2-- OrEXECUTE au_info2 'Wh%'-- OrEXECUTE au_info2 @firstname = 'A%'-- OrEXECUTE au_info2 '[CK]ars[OE]n'-- OrEXECUTE au_info2 'Hunter', 'Sheryl'-- OrEXECUTE au_info2 'H%', 'S%'
D. 使用 OUTPUT 参数OUTPUT 参数允许外部过程、批处理或多条 Transact-SQL 语句访问在过程执行期间设置的某个值。下面的示例创建一个存储过程 (titles_sum),并使用一个可选的输入参数和一个输出参数。
首先,创建过程:
USE pubsGOIF EXISTS(SELECT name FROM sysobjects WHERE name = 'titles_sum' AND type = 'P') DROP PROCEDURE titles_sumGOUSE pubsGOCREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUTASSELECT 'Title Name' = titleFROM titles WHERE title LIKE @@TITLE SELECT @@SUM = SUM(price)FROM titlesWHERE title LIKE @@TITLEGO
接下来,将该 OUTPUT 参数用于控制流语言。
说明 OUTPUT 变量必须在创建表和使用该变量时都进行定义。
参数名和变量名不一定要匹配,不过数据类型和参数位置必须匹配(除非使用 @@SUM = variable 形式)。
DECLARE @@TOTALCOST moneyEXECUTE titles_sum 'The%', @@TOTALCOST OUTPUTIF @@TOTALCOST < 200 BEGIN PRINT ' ' PRINT 'All of these titles can be purchased for less than $200.'ENDELSE SELECT 'The total cost of these titles is $' + RTRIM(CAST(@@TOTALCOST AS varchar(20)))
下面是结果集:
Title Name ------------------------------------------------------------------------ The Busy Executive's Database GuideThe Gourmet MicrowaveThe Psychology of Computer Cooking
(3 row(s) affected)
Warning, null value eliminated from aggregate.
All of these titles can be purchased for less than $200.
E. 使用 OUTPUT 游标参数OUTPUT 游标参数用来将存储过程的局部游标传递回调用批处理、存储过程或触发器。
首先,创建以下过程,在 titles 表上声明并打开一个游标:
USE pubsIF EXISTS (SELECT name FROM sysobjects WHERE name = 'titles_cursor' and type = 'P')DROP PROCEDURE titles_cursorGOCREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUTASSET @titles_cursor = CURSORFORWARD_ONLY STATIC FORSELECT *FROM titles
OPEN @titles_cursorGO
接下来,执行一个批处理,声明一个局部游标变量,执行上述过程以将游标赋值给局部变量,然后从该游标提取行。
USE pubsGODECLARE @MyCursor CURSOREXEC titles_cursor @titles_cursor = @MyCursor OUTPUTWHILE (@@FETCH_STATUS = 0)BEGIN FETCH NEXT FROM @MyCursorENDCLOSE @MyCursorDEALLOCATE @MyCursorGO
F. 使用 WITH RECOMPILE 选项如果为过程提供的参数不是典型的参数,并且新的执行计划不应高速缓存或存储在内存中,WITH RECOMPILE 子句会很有帮助。
USE pubsIF EXISTS (SELECT name FROM sysobjects WHERE name = 'titles_by_author' AND type = 'P') DROP PROCEDURE titles_by_authorGOCREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%'WITH RECOMPILEASSELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name', title AS TitleFROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON ta.title_id = t.title_idWHERE au_lname LIKE @@LNAME_PATTERNGO
G. 使用 WITH ENCRYPTION 选项WITH ENCRYPTION 子句对用户隐藏存储过程的文本。下例创建加密过程,使用 sp_helptext 系统存储过程获取关于加密过程的信息,然后尝试直接从 syscomments 表中获取关于该过程的信息。
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'encrypt_this' AND type = 'P') DROP PROCEDURE encrypt_thisGOUSE pubsGOCREATE PROCEDURE encrypt_thisWITH ENCRYPTIONASSELECT * FROM authorsGO
EXEC sp_helptext encrypt_this
下面是结果集:
The object's comments have been encrypted.
接下来,选择加密存储过程内容的标识号和文本。
SELECT c.id, c.text FROM syscomments c INNER JOIN sysobjects o ON c.id = o.idWHERE o.name = 'encrypt_this'
下面是结果集:
说明 text 列的输出显示在单独一行中。执行时,该信息将与 id 列信息出现在同一行中。
id text ---------- ------------------------------------------------------------
(1 row(s) affected)
H. 创建用户定义的系统存储过程下面的示例创建一个过程,显示表名以 emp 开头的所有表及其对应的索引。如果没有指定参数,该过程将返回表名以 sys 开头的所有表(及索引)。
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'sp_showindexes' AND type = 'P') DROP PROCEDURE sp_showindexesGOUSE masterGOCREATE PROCEDURE sp_showindexes @@TABLE varchar(30) = 'sys%'AS SELECT o.name AS TABLE_NAME, i.name AS INDEX_NAME, indid AS INDEX_IDFROM sysindexes i INNER JOIN sysobjects o ON o.id = i.id WHERE o.name LIKE @@TABLEGO USE pubsEXEC sp_showindexes 'emp%'GO
下面是结果集:
TABLE_NAME INDEX_NAME INDEX_ID ---------------- ---------------- ----------------employee employee_ind 1employee PK_emp_id 2
(2 row(s) affected)
I. 使用延迟名称解析下面的示例显示四个过程以及延迟名称解析的各种可能使用方式。尽管引用的表或列在编译时不存在,但每个存储过程都可创建。
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'proc1' AND type = 'P') DROP PROCEDURE proc1GO-- Creating a procedure on a nonexistent table.USE pubsGOCREATE PROCEDURE proc1AS SELECT * FROM does_not_existGO -- Here is the statement to actually see the text of the procedure.SELECT o.id, c.textFROM sysobjects o INNER JOIN syscomments c ON o.id = c.idWHERE o.type = 'P' AND o.name = 'proc1'GOUSE masterGOIF EXISTS (SELECT name FROM sysobjects WHERE name = 'proc2' AND type = 'P') DROP PROCEDURE proc2GO-- Creating a procedure that attempts to retrieve information from a-- nonexistent column in an existing table.USE pubsGOCREATE PROCEDURE proc2AS DECLARE @middle_init char(1) SET @middle_init = NULL SELECT au_id, middle_initial = @middle_init FROM authorsGO -- Here is the statement to actually see the text of the procedure.SELECT o.id, c.textFROM sysobjects o INNER JOIN syscomments c ON o.id = c.idWHERE o.type = 'P' and o.name = 'proc2'
=======================================================================================================================结束===========================================================================================================================
还有另外一个参考的储存过程例子
有关ASP与存储过程的文章不少,这些资料旨在提供一点帮助,仅限于此,现在我基本上通过调用存储过程访问SQL Server,以下的文字虽不敢保证绝对正确,但都是实践的总结,希望对大家能有帮助。 存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令。定义总是很抽象。存储过程其实就是能完成一定操作的一组SQL语句,只不过这组语句是放在数据库中的(这里我们只谈SQL Server)。如果我们通过创建存储过程以及在ASP中调用存储过程,就可以避免将SQL语句同ASP代码混杂在一起。这样做的好处至少有三个:第一、大大提高效率。存储过程本身的执行速度非常快,而且,调用存储过程可以大大减少同数据库的交互次数。第二、提高安全性。假如将SQL语句混合在ASP代码中,一旦代码失密,同时也就意味着库结构失密。第三、有利于SQL语句的重用。
在ASP中,一般通过command对象调用存储过程,根据不同情况,本文也介绍其它调用方法。为了方便说明,根据存储过程的输入输出,作以下简单分类:1. 只返回单一记录集的存储过程假设有以下存储过程(本文的目的不在于讲述T-SQL语法,所以存储过程只给出代码,不作说明): /*SP1*/CREATE PROCEDURE dbo.getUserListasset nocount onbeginselect * from dbo.[userinfo]endgo 以上存储过程取得userinfo表中的所有记录,返回一个记录集。通过command对象调用该存储过程的ASP代码如下:
'**通过Command对象调用存储过程**DIM MyComm,MyRstSet MyComm = Server.CreateObject("ADODB.Command")MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串MyComm.CommandText = "getUserList" '指定存储过程名MyComm.CommandType = 4 '表明这是一个存储过程MyComm.Prepared = true '要求将SQL命令先行编译Set MyRst = MyComm.ExecuteSet MyComm = Nothing 存储过程取得的记录集赋给MyRst,接下来,可以对MyRst进行操作。在以上代码中,CommandType属性表明请求的类型,取值及说明如下:-1 表明CommandText参数的类型无法确定1 表明CommandText是一般的命令类型2 表明CommandText参数是一个存在的表名称4 表明CommandText参数是一个存储过程的名称
还可以通过Connection对象或Recordset对象调用存储过程,方法分别如下: '**通过Connection对象调用存储过程**DIM MyConn,MyRstSet MyConn = Server.CreateObject("ADODB.Connection")MyConn.open MyConStr 'MyConStr是数据库连接字串Set MyRst = MyConn.Execute("getUserList",0,4) '最后一个参断含义同CommandTypeSet MyConn = Nothing '**通过Recordset对象调用存储过程**DIM MyRstSet MyRst = Server.CreateObject("ADODB.Recordset")MyRst.open "getUserList",MyConStr,0,1,4'MyConStr是数据库连接字串,最后一个参断含义与CommandType相同 2. 没有输入输出的存储过程请看以下存储过程: /*SP2*/CREATE PROCEDURE dbo.delUserAllasset nocount onbegindelete from dbo.[userinfo]endgo 该存储过程删去userinfo表中的所有记录,没有任何输入及输出,调用方法与上面讲过的基本相同,只是不用取得记录集: '**通过Command对象调用存储过程**DIM MyCommSet MyComm = Server.CreateObject("ADODB.Command")MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串MyComm.CommandText = "delUserAll" '指定存储过程名MyComm.CommandType = 4 '表明这是一个存储过程MyComm.Prepared = true '要求将SQL命令先行编译MyComm.Execute '此处不必再取得记录集Set MyComm = Nothing 当然也可通过Connection对象或Recordset对象调用此类存储过程,不过建立Recordset对象是为了取得记录集,在没有返回记录集的情况下,还是利用Command对象吧。3. 有返回值的存储过程在进行类似SP2的操作时,应充分利用SQL Server强大的事务处理功能,以维护数据的一致性。并且,我们可能需要存储过程返回执行情况,为此,将SP2修改如下: /*SP3*/CREATE PROCEDURE dbo.delUserAllasset nocount onbeginBEGIN TRANSACTIONdelete from dbo.[userinfo]IF @@error=0 beginCOMMIT TRANSACTIONreturn 1endELSEbeginROLLBACK TRANSACTIONreturn 0end returnendgo 以上存储过程,在delete顺利执行时,返回1,否则返回0,并进行回滚操作。为了在ASP中取得返回值,需要利用Parameters集合来声明参数: '**调用带有返回值的存储过程并取得返回值**DIM MyComm,MyParaSet MyComm = Server.CreateObject("ADODB.Command")MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串MyComm.CommandText = "delUserAll" '指定存储过程名MyComm.CommandType = 4 '表明这是一个存储过程MyComm.Prepared = true '要求将SQL命令先行编译'声明返回值Set Mypara = MyComm.CreateParameter("RETURN",2,4)MyComm.Parameters.Append MyParaMyComm.Execute'取得返回值DIM retValueretValue = MyComm(0) '或retValue = MyComm.Parameters(0)Set MyComm = Nothing
在MyComm.CreateParameter("RETURN",2,4)中,各参数的含义如下:第一个参数("RETURE")为参数名。参数名可以任意设定,但一般应与存储过程中声明的参数名相同。此处是返回值,我习惯上设为"RETURE";第二个参数(2),表明该参数的数据类型,具体的类型代码请参阅ADO参考,以下给出常用的类型代码:adBigInt: 20 ;adBinary : 128 ; adBoolean: 11 ;adChar: 129 ;adDBTimeStamp: 135 ;adEmpty: 0 ;adInteger: 3 ;adSmallInt: 2 ; adTinyInt: 16 ;adVarChar: 200 ;对于返回值,只能取整形,且-1到-99为保留值;第三个参数(4),表明参数的性质,此处4表明这是一个返回值。此参数取值的说明如下:0 : 类型无法确定; 1: 输入参数;2: 输入参数;3:输入或输出参数;4: 返回值
以上给出的ASP代码,应该说是完整的代码,也即最复杂的代码,其实 Set Mypara = MyComm.CreateParameter("RETURN",2,4)MyComm.Parameters.Append MyPara
可以简化为 MyComm.Parameters.Append MyComm.CreateParameter("RETURN",2,4) 甚至还可以继续简化,稍后会做说明。对于带参数的存储过程,只能使用Command对象调用(也有资料说可通过Connection对象或Recordset对象调用,但我没有试成过)。4. 有输入参数和输出参数的存储过程返回值其实是一种特殊的输出参数。在大多数情况下,我们用到的是同时有输入及输出参数的存储过程,比如我们想取得用户信息表中,某ID用户的用户名,这时候,有一个输入参数----用户ID,和一个输出参数----用户名。实现这一功能的存储过程如下: /*SP4*/CREATE PROCEDURE dbo.getUserName@UserID int,@UserName varchar(40) outputasset nocount onbeginif @UserID is null returnselect @UserName=username from dbo.[userinfo] where userid=@UserIDreturnendgo 调用该存储过程的ASP代码如下: '**调用带有输入输出参数的存储过程**DIM MyComm,UserID,UserNameUserID = 1Set MyComm = Server.CreateObject("ADODB.Command")MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串MyComm.CommandText = "getUserName" '指定存储过程名MyComm.CommandType = 4 '表明这是一个存储过程MyComm.Prepared = true '要求将SQL命令先行编译'声明参数MyComm.Parameters.append MyComm.CreateParameter("@UserID",3,1,4,UserID)MyComm.Parameters.append MyComm.CreateParameter("@UserName",200,2,40)MyComm.Execute'取得出参UserName = MyComm(1)Set MyComm = Nothing 在以上代码中,可以看到,与声明返回值不同,声明输入参数时需要5个参数,声明输出参数时需要4个参数。声明输入参数时5个参数分别为:参数名、参数数据类型、参数类型、数据长度、参数值。声明输出参数时,没有最后一个参数:参数值。需要特别注意的是:在声明参数时,顺序一定要与存储过程中定义的顺序相同,而且各参数的数据类型、长度也要与存储过程中定义的相同。如果存储过程有多个参数,ASP代码会显得繁琐,可以使用with命令简化代码: '**调用带有输入输出参数的存储过程(简化代码)**DIM MyComm,UserID,UserNameUserID = 1Set MyComm = Server.CreateObject("ADODB.Command")with MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串.CommandText = "getUserName" '指定存储过程名.CommandType = 4 '表明这是一个存储过程.Prepared = true '要求将SQL命令先行编译.Parameters.append .CreateParameter("@UserID",3,1,4,UserID).Parameters.append .CreateParameter("@UserName",200,2,40).Executeend withUserName = MyComm(1)Set MyComm = Nothing
假如我们要取得ID为1到10,10位用户的用户名,是不是要创建10次Command对象呢?不是的。如果需要多次调用同一存储过程,只需改变输入参数,就会得到不同的输出: '**多次调用同一存储过程**DIM MyComm,UserID,UserNameUserName = ""Set MyComm = Server.CreateObject("ADODB.Command")for UserID = 1 to 10with MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串.CommandText = "getUserName" '指定存储过程名.CommandType = 4 '表明这是一个存储过程.Prepared = true '要求将SQL命令先行编译if UserID = 1 then.Parameters.append .CreateParameter("@UserID",3,1,4,UserID).Parameters.append .CreateParameter("@UserName",200,2,40).Executeelse'重新给入参赋值(此时参数值不发生变化的入参以及出参不必重新声明).Parameters("@UserID") = UserID.Executeend ifend withUserName = UserName + MyComm(1) + "," '也许你喜欢用数组存储nextSet MyComm = Nothing 通过以上代码可以看出:重复调用同一存储过程时,只需为值发生改变的输入参数重新赋值即可,这一方法在有多个输入输出参数,且每次调用时只有一个输入参数的值发生变化时,可以大大减少代码量。5. 同时具有返回值、输入参数、输出参数的存储过程前面说过,在调用存储过程时,声明参数的顺序要与存储过程中定义的顺序相同。还有一点要特别注意:如果存储过程同时具有返回值以及输入、输出参数,返回值要最先声明。为了演示这种情况下的调用方法,我们改善一下上面的例子。还是取得ID为1的用户的用户名,但是有可能该用户不存在(该用户已删除,而userid是自增长的字段)。存储过程根据用户存在与否,返回不同的值。此时,存储过程和ASP代码如下: /*SP5*/CREATE PROCEDURE dbo.getUserName--为了加深对"顺序"的印象,将以下两参数的定义顺序颠倒一下@UserName varchar(40) output,@UserID intasset nocount onbeginif @UserID is null returnselect @UserName=username from dbo.[userinfo] where userid=@UserIDif @@rowcount>0return 1elsereturn 0returnendgo '**调用同时具有返回值、输入参数、输出参数的存储过程**DIM MyComm,UserID,UserNameUserID = 1Set MyComm = Server.CreateObject("ADODB.Command")with MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串.CommandText = "getUserName" '指定存储过程名.CommandType = 4 '表明这是一个存储过程.Prepared = true '要求将SQL命令先行编译'返回值要最先被声明.Parameters.Append .CreateParameter("RETURN",2,4)'以下两参数的声明顺序也做相应颠倒.Parameters.append .CreateParameter("@UserName",200,2,40).Parameters.append .CreateParameter("@UserID",3,1,4,UserID).Executeend withif MyComm(0) = 1 thenUserName = MyComm(1)elseUserName = "该用户不存在"end ifSet MyComm = Nothing6. 同时返回参数和记录集的存储过程有时候,我们需要存储过程同时返回参数和记录集,比如在利用存储过程分页时,要同时返回记录集以及数据总量等参数。以下给出一个进行分页处理的存储过程: /*SP6*/CREATE PROCEDURE dbo.getUserList@iPageCount int OUTPUT, --总页数@iPage int, --当前页号@iPageSize int --每页记录数asset nocount onbegin--创建临时表 create table #t (ID int IDENTITY, --自增字段userid int,username varchar(40))--向临时表中写入数据insert into #t select userid,username from dbo.[UserInfo]order by userid
--取得记录总数 declare @iRecordCount intset @iRecordCount = @@rowcount --确定总页数IF @iRecordCount%@iPageSize=0SET @iPageCount=CEILING(@iRecordCount/@iPageSize)ELSESET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1
--若请求的页号大于总页数,则显示最后一页IF @iPage > @iPageCountSELECT @iPage = @iPageCount --确定当前页的始末记录DECLARE @iStart int --start recordDECLARE @iEnd int --end recordSELECT @iStart = (@iPage - 1) * @iPageSizeSELECT @iEnd = @iStart + @iPageSize + 1 --取当前页记录 select * from #t where ID>@iStart and ID<@iEnd --删除临时表DROP TABLE #t --返回记录总数return @iRecordCountendgo 在上面的存储过程中,输入当前页号及每页记录数,返回当前页的记录集,总页数及记录总数。为了更具典型性,将记录总数以返回值的形式返回。以下是调用该存储过程的ASP代码(具体的分页操作略去): '**调用分页存储过程**DIM pagenow,pagesize,pagecount,recordcountDIM MyComm,MyRstpagenow = Request("pn")'自定义函数用于验证自然数if CheckNar(pagenow) = false then pagenow = 1pagesize = 20Set MyComm = Server.CreateObject("ADODB.Command")with MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串.CommandText = "getUserList" '指定存储过程名.CommandType = 4 '表明这是一个存储过程.Prepared = true '要求将SQL命令先行编译'返回值(记录总量) .Parameters.Append .CreateParameter("RETURN",2,4)'出参(总页数).Parameters.Append .CreateParameter("@iPageCount",3,2)'入参(当前页号).Parameters.append .CreateParameter("@iPage",3,1,4,pagenow)'入参(每页记录数).Parameters.append .CreateParameter("@iPageSize",3,1,4,pagesize)Set MyRst = .Executeend withif MyRst.state = 0 then '未取到数据,MyRst关闭recordcount = -1elseMyRst.close '注意:若要取得参数值,需先关闭记录集对象recordcount = MyComm(0)pagecount = MyComm(1)if cint(pagenow)>=cint(pagecount) then pagenow=pagecountend ifSet MyComm = Nothing '以下显示记录if recordcount = 0 thenResponse.Write "无记录"elseif recordcount > 0 thenMyRst.opendo until MyRst.EOF......loop'以下显示分页信息......else 'recordcount=-1Response.Write "参数错误"end if 对于以上代码,只有一点需要说明:同时返回记录集和参数时,若要取得参数,需先将记录集关闭,使用记录集时再将其打开。7. 返回多个记录集的存储过程本文最先介绍的是返回记录集的存储过程。有时候,需要一个存储过程返回多个记录集,在ASP中,如何同时取得这些记录集呢?为了说明这一问题,在userinfo表中增加两个字段:usertel及usermail,并设定只有登录用户可以查看这两项内容。 /*SP7*/CREATE PROCEDURE dbo.getUserInfo@userid int,@checklogin bitasset nocount onbeginif @userid is null or @checklogin is null returnselect usernamefrom dbo.[usrinfo]where userid=@userid--若为登录用户,取usertel及usermailif @checklogin=1select usertel,usermailfrom dbo.[userinfo]where userid=@useridreturnendgo 以下是ASP代码: '**调用返回多个记录集的存储过程**DIM checklg,UserID,UserName,UserTel,UserMailDIM MyComm,MyRstUserID = 1'checklogin()为自定义函数,判断访问者是否登录checklg = checklogin()Set MyComm = Server.CreateObject("ADODB.Command")with MyComm.ActiveConnection = MyConStr 'MyConStr是数据库连接字串.CommandText = "getUserInfo" '指定存储过程名.CommandType = 4 '表明这是一个存储过程.Prepared = true '要求将SQL命令先行编译.Parameters.append .CreateParameter("@userid",3,1,4,UserID).Parameters.append .CreateParameter("@checklogin",11,1,1,checklg)Set MyRst = .Executeend withSet MyComm = Nothing '从第一个记录集中取值UserName = MyRst(0)'从第二个记录集中取值if not MyRst is Nothing thenSet MyRst = MyRst.NextRecordset()UserTel = MyRst(0)UserMail = MyRst(1)end ifSet MyRst = Nothing 以上代码中,利用Recordset对象的NextRecordset方法,取得了存储过程返回的多个记录集。至此,针对ASP调用存储过程的各种情况,本文已做了较为全面的说明。最后说一下在一个ASP程序中,调用多个存储过程的不同方法。在一个ASP程序中,调用多个存储过程至少有以下三种方法是可行的:1. 创建多个Command对象
DIM MyCommSet MyComm = Server.CreateObject("ADODB.Command")'调用存储过程一......Set MyComm = NothingSet MyComm = Server.CreateObject("ADODB.Command")'调用存储过程二......Set MyComm = Nothing...... 2. 只创建一个Command对象,结束一次调用时,清除其参数 DIM MyCommSet MyComm = Server.CreateObject("ADODB.Command")'调用存储过程一.....'清除参数(假设有三个参数)MyComm.Parameters.delete 2MyComm.Parameters.delete 1MyComm.Parameters.delete 0'调用存储过程二并清除参数......Set MyComm = Nothing 此时要注意:清除参数的顺序与参数声明的顺序相反,原因嘛,我也不知道。 3. 利用Parameters数据集合的Refresh方法重置Parameter对象 DIM MyCommSet MyComm = Server.CreateObject("ADODB.Command")'调用存储过程一.....'重置Parameters数据集合中包含的所有Parameter对象MyComm.Parameters.Refresh'调用存储过程二.....Set MyComm = Nothing
一般认为,重复创建对象是效率较低的一种方法,但是经测试(测试工具为Microsoft Application Center Test),结果出人意料:方法2 >= 方法1 >> 方法3方法2的运行速度大于等于方法1(最多可高4%左右),这两种方法的运行速度远大于方法3(最多竟高达130%),所以建议在参数多时,采用方法1,在参数较少时,采用方法2。
来源:chinazhan
====================================================================================================================结束=====================================================================================================================
这是一个用储存过程实现分页查询的例子,本人没有测试过,先给大家看看。
实现数据分页查询的方案相当多,前台和后台都有很多好方法,这些好方法都有一个共同的特点:在实现分页的同时,考虑了网络资源的占有问题。本文要讨论的是使用SQL Server存储过程的实现方法。
引子

在含有ID主键(且ID连续)的Tab表中,查找第51行到第100行数据,对应的SQL语句为:
SLECET*FROME tab WHERE ID BETWEEN 51 AND 100
如果ID不连续,或者主键为其他,则可以用下SQL语句实现同样的功能:
SELECT TOP 50 * FROM tab WHERE ID NOT IN (SELECT TOP 50 ID FROM tab)
或是SELECT TOP 50 * FROM tab WHERE ID>@lastpage_endidi
如果用变量参数控制输入行,则使用以下语句:
SET ROWCOUNT@pagesize
SELECT * FROM tab WHERE ID>@lastpage_endid
问题

对于没有主键的表,可能存在大量重复的记录,很多SQL Server使用者喜欢用下面的语句:
SELECT IDENTITY(INT,1,1) AS ID,* INTO #T FROM tab
SELECT * FROM #T WHERE ID BETWEEN 51 AND 100
上面的方法非常笨拙,而且相当耗资源。
分析

对于这种没有主键的表,要实现分页查询,笔者认为最好的方法是加一个IDENTITY属性的主键,然后使用文本开头使用的两种方法,效率要高得多。在原表中加入IDENTITY属性的语句如下:
ALTER TABLE tab ADD ID INT IDENTITY PRIMARY KEY
并不是所有用户都有修改表的权限,下面介绍一种通用的方法:使用SQL Server 提供的储存过程sp_cursoropen。具体用法如下:
exec sp_cursoropen @P1 output,@sqlstr
exec sp_cursorfetch @P1,16,@begincol,@pagesize
exec sp_cursorclose @P1
其中第一句的@P1为生成的游标ID,@sqlstr为定义游标的SLELECT字符串;第二句中@begincol为起始行数,@pagesize为输出行数;第三句sp_cursorclose意即关闭游标。
解决

以下是笔者编写的储存过程,通过传入表名,分页取出第N页数据。
Create proc getpage
(@tablename varchar (255), @page count int=1,@pagesize int=99999999)--@tablename为表名
as
begin
set nocount on
declare @P1 int
declare @sqlstr nvarchar(400)
set @pagecount =(@pagecount-1)*@pagecount+1
set @sqlstr=’select * from ’+@tablename
exec sp_cursoropen @P1 output,@sqlstr
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
exec sp_cursorclose @P1
end
调用方法

esec getpage’tab’,10,100
--表名tab ,第10页,每页100行。
进阶

以上存储过程比较通用,不过如果适当修改一下,把@sqlstr当作转入参数,就更灵活了,实现方法如下:
Create proc getpage
(@sqlstr nvarchar (4000),@pagecont int=1,@pagesize int=99999999)
as
begin
set nocount on
declare @P1 int
set @pagecount =(@pagecount-1)*@pagecount+1
exec sp_cursoropen @P1 output,@sqlstr
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
exec sp_cursorclose @P1
end
调用方法

exec getpage’SELECT * FROM tab WHERE条件 ’,10,100
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1543668

星期六, 四月 07, 2007

什么是Windows API

什么是Windows API

2001-10-26· · ··yesky


一、什么是Windows API?

  1.什么是Windows API?

  Windows 这个多作业系统除了协调应用程式的执行、分配内存、管理系统资源…之外, 她同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗、描绘图形、使用周边设备…等目的,由於这些函数服务的对象是应用程式(Application), 所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是MicrosoftWindows 32位平台的应用程序编程接口。

  凡是在 Windows 工作环境底下执行的应用程式, 都可以调用Windows API。

  2.Windows API的历史与现状

  当WINDOWS操作系统开始占据主导地位的时候,开发WINDOWS平台下的应用程序成为人们的需要。而在WINDOWS程序设计领域处于发展的初期,WINDOWS程序员所能使用的编程工具唯有API函数,这些函数是WINDOWS提供给应用程序与操作系统的接口,他们犹如“积木块”一样,可以搭建出各种界面丰富,功能灵活的应用程序。所以可以认为API函数是构筑整个WINDOWS框架的基石,在它的下面是WINDOWS的操作系统核心,而它的上面则是所有的华丽的WINDOWS应用程序。

  但是,没有合适的Windows编程平台,程序员想编写具有Windows风格的软件,必须借助API,API也因此被赋予至高无上的地位。那时的WINDOWS程序开发还是比较复杂的工作,程序员必须熟记一大堆常用的API函数,而且还得对WINDOWS操作系统有深入的了解。然而随着软件技术的不断发展,在WINDOWS平台上出现了很多优秀的可视化编程环境,程序员可以采用“即见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。

  这些优秀可视化编程环境操作简单、界面友好(诸如VB、VC++、DELPHI等),在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能,事实上这些类库和控件都是构架在WIN32 API函数基础之上的,是封装了的API函数的集合。它们把常用的API函数的组合在一起成为一个控件或类库,并赋予其方便的使用方法,所以极大的加速了WINDOWS应用程序开发的过程。有了这些控件和类库,程序员便可以把主要精力放在程序整体功能的设计上,而不必过于关注技术细节。

  实际上如果我们要开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数,虽然类库和控件使应用程序的开发简单的多,但它们只提供WINDOWS的一般功能,对于比较复杂和特殊的功能来说,使用类库和控件是非常难以实现的,这时就需要采用API函数来实现。

  这也是API函数使用的场合,所以我们对待API函数不必刻意去研究每一个函数的用法,那也是不现实的(能用得到的API函数有几千个呢)。正如某位大虾所说:API不要去学,在需要的时候去查API帮助就足够了。但是,许多API函数令人难以理解,易于误用,还会导致出错,这一切都阻碍了它的推广。本专题就是想帮助那些想快速掌握API函数用法的同志们。通过对API函数的分类,结合一些有趣的实例,应该可以达到快速掌握的目的。

星期五, 四月 06, 2007

我要做个程序员~!

我希望以后能创办自己的公司或者做个职业经理人,据我所知,搞技术和做销售的人最可能发展成为职业经理人。我现在年龄较小,长的很年轻又没有社会经验,不适合搞销售,而年龄小却是搞技术的优势,所以我选择了做程序员。尽管我的基础很差,但一定要相信自己,跟别人的差距很快就会缩短,我虽然不对编程着迷,但我对解决难题有强烈的兴趣,我一定会成为一个出色的程序员~!

面朝大海,春暖花开

找工作找了2个礼拜颗粒无收让我十分郁闷,经高人指点后我发现了我的问题。
1、我很不爱写简历,因为我不喜欢回忆不成功的过去。连我自己都不爱写的东西,别人能爱看吗?简历不是一张纸,它是一张牌,面试也是根据简历来问问题。简历要突出你跟别人不一样的地方,项目经验中不仅是写你的项目是什么样的,更重要的是你做了什么?达到什么效果?
2、要沉住气,焦急的心态在面试中出现是要失败的,面试前要想好关于简历上所写内容的全部问题,在家中对着镜子练习,达到对答如流的境界。在家应多出去锻炼身体,踏下心的学习,不要整天坐在电脑前,珍惜上班前最后的轻松时期吧。
3、现在的挫折算不上什么,以后会有更大的挑战,回忆挫折是无比快乐的事情。

星期二, 四月 03, 2007

ie7怎么设置才能在点链接是不打开新窗口,而是打开新标签

只要将"Internet选项"中的"Tabs→When a pop-up is encountered"修改为"Always open pop-ups in a new tab"之后,就能实现"在新标签中打开网页链接"这一功能。

摘自百度知道http://zhidao.baidu.com/question/14297794.html

迅雷乱码

事故原因:操作系统是英文版
解决办法:找到迅雷的安装路径,有个language文件夹,一个是简体中文的,一个是繁体tw的,把繁体的剪切然后复制到另一个地方保存。打开迅雷,你会惊喜的发现变成中文了,但是在以下载的那个地方还有一小部分乱码,这个时候再把刚才剪切的繁体tw复制到原文件夹。再次打开迅雷!HOHO,问题解决了!

摘自百度知道http://zhidao.baidu.com/question/14985700.html

星期日, 四月 01, 2007

单链表的建立

有了动态内存分配的基础,要实现链表就不难了。

  所谓链表,就是用一组任意的存储单元存储线性表元素的一种数据结构。链表又分为单链表、双向链表和循环链表等。我们先讲讲单链表。所谓单链表,是指数据接点是单向排列的。一个单链表结点,其结构类型分为两部分:

  1、数据域:用来存储本身数据

  2、链域或称为指针域:用来存储下一个结点地址或者说指向其直接后继的指针。

  例:

typedef struct node
{
 char name[20];
 struct node *link;
}stud;

  这样就定义了一个单链表的结构,其中char name[20]是一个用来存储姓名的字符型数组,指针*link是一个用来存储其直接后继的指针。

  定义好了链表的结构之后,只要在程序运行的时候爱数据域中存储适当的数据,如有后继结点,则把链域指向其直接后继,若没有,则置为NULL。

  下面就来看一个建立带表头(若未说明,以下所指链表均带表头)的单链表的完整程序。

#include <stdio.h>
#include <malloc.h> /*包含动态内存分配函数的头文件*/
#define N 10 /*N为人数*/
typedef struct node
{
 char name[20];
 struct node *link;
}stud;
stud * creat(int n) /*建立单链表的函数,形参n为人数*/
{
 stud *p,*h,*s; /* *h保存表头结点的指针,*p指向当前结点的前一个结点,*s指向当前结点*/
 int i; /*计数器*/
 if((h=(stud *)malloc(sizeof(stud)))==NULL) /*分配空间并检测*/
 {
  printf("不能分配内存空间!");
  exit(0);
 }
 h->name[0]='\0'; /*把表头结点的数据域置空*/
 h->link=NULL; /*把表头结点的链域置空*/
 p=h; /*p指向表头结点*/
 for(i=0;i<n;i++)
 {
  if((s= (stud *) malloc(sizeof(stud)))==NULL) /*分配新存储空间并检测*/
  {
   printf("不能分配内存空间!");
   exit(0);
  }
  p->link=s; /*把s的地址赋给p所指向的结点的链域,这样就把p和s所指向的结点连接起来了*/
  printf("请输入第%d个人的姓名",i+1);
  scanf("%s",s->name); /*在当前结点s的数据域中存储姓名*/
  s->link=NULL;
  p=s;
 }
 return(h);
}
main()
{
 int number; /*保存人数的变量*/
 stud *head; /*head是保存单链表的表头结点地址的指针*/
 number=N;
 head=creat(number); /*把所新建的单链表表头地址赋给head*/
}

  这样就写好了一个可以建立包含N个人姓名的单链表了。写动态内存分配的程序应注意,请尽量对分配是否成功进行检测。

转载自信任链 10053 的博客http://usrsrc.bokee.com/viewdiary.12089701.html

二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现

注意:程序申请的空间并没有释放^_^
/**//********************************************************************
created: 2005/12/30
created: 30:12:2005 10:39
filename: bintree.h
author: Liu Qi

purpose: 二叉树的3种遍历方式(包括非递归实现),前序,后序和中序,先访问根节点就是
前序(部分书籍称为先根遍历,个人觉得该说法更好^_^),类似的,最后访问根节点就是后序
*********************************************************************/


#ifndef TREE_H
#define TREE_H


#include
#include
#include
#include
#include

using namespace std;



typedef int ElemType;

typedef struct treeT
{
ElemType key;
struct treeT* left;
struct treeT* right;
}treeT, *pTreeT;




/**//*===========================================================================
* Function name: visit
* Parameter: root:树根节点指针
* Precondition:
* Description:
* Return value:
* Author: Liu Qi, //-
===========================================================================*/
static void visit(pTreeT root)
{
if (NULL != root)
{
printf(" %d\n", root->key);
}
}



/**//*===========================================================================
* Function name: BT_MakeNode
* Parameter: target:元素值
* Precondition: None
* Postcondition: NULL != pTreeT
* Description: 构造一个tree节点,置左右指针为空,并且返回指向新节点的指针
* Return value: 指向新节点的指针
* Author: Liu Qi, [12/30/2005]
===========================================================================*/
static pTreeT BT_MakeNode(ElemType target)
{
pTreeT pNode = (pTreeT) malloc(sizeof(treeT));

assert( NULL != pNode );

pNode->key = target;
pNode->left = NULL;
pNode->right = NULL;

return pNode;
}


/**//*===========================================================================
* Function name: BT_Insert
* Parameter: target:要插入的元素值, pNode:指向某一个节点的指针
* Precondition: NULL != ppTree
* Description: 插入target到pNode的后面
* Return value: 指向新节点的指针
* Author: Liu Qi, [12/29/2005]
===========================================================================*/
pTreeT BT_Insert(ElemType target, pTreeT* ppTree)
{
pTreeT Node;

assert( NULL != ppTree );

Node = *ppTree;
if (NULL == Node)
{
return *ppTree = BT_MakeNode(target);
}

if (Node->key == target) //不允许出现相同的元素
{
return NULL;
}
else if (Node->key > target) //向左
{
return BT_Insert(target, &Node->left);
}
else
{
return BT_Insert(target, &Node->right);
}
}




/**//*===========================================================================
* Function name: BT_PreOrder
* Parameter: root:树根节点指针
* Precondition: None
* Description: 前序遍历
* Return value: void
* Author: Liu Qi, [12/29/2005]
===========================================================================*/
void BT_PreOrder(pTreeT root)
{
if (NULL != root)
{
visit(root);
BT_PreOrder(root->left);
BT_PreOrder(root->right);
}
}


/**//*===========================================================================
* Function name: BT_PreOrderNoRec
* Parameter: root:树根节点指针
* Precondition: Node
* Description: 前序(先根)遍历非递归算法
* Return value: void
* Author: Liu Qi, [1/1/2006]
===========================================================================*/
void BT_PreOrderNoRec(pTreeT root)
{
stack s;

while ((NULL != root) !s.empty())
{
if (NULL != root)
{
visit(root);
s.push(root);
root = root->left;
}
else
{
root = s.top();
s.pop();
root = root->right;
}
}
}



/**//*===========================================================================
* Function name: BT_InOrder
* Parameter: root:树根节点指针
* Precondition: None
* Description: 中序遍历
* Return value: void
* Author: Liu Qi, [12/30/2005]
===========================================================================*/
void BT_InOrder(pTreeT root)
{
if (NULL != root)
{
BT_InOrder(root->left);
visit(root);
BT_InOrder(root->right);
}
}


/**//*===========================================================================
* Function name: BT_InOrderNoRec
* Parameter: root:树根节点指针
* Precondition: None
* Description: 中序遍历,非递归算法
* Return value: void
* Author: Liu Qi, [1/1/2006]
===========================================================================*/
void BT_InOrderNoRec(pTreeT root)
{
stack s;
while ((NULL != root) !s.empty())
{
if (NULL != root)
{
s.push(root);
root = root->left;
}
else
{
root = s.top();
visit(root);
s.pop();
root = root->right;
}
}
}



/**//*===========================================================================
* Function name: BT_PostOrder
* Parameter: root:树根节点指针
* Precondition: None
* Description: 后序遍历
* Return value: void
* Author: Liu Qi, [12/30/2005]
===========================================================================*/
void BT_PostOrder(pTreeT root)
{
if (NULL != root)
{
BT_PostOrder(root->left);
BT_PostOrder(root->right);
visit(root);
}
}


/**//*===========================================================================
* Function name: BT_PostOrderNoRec
* Parameter: root:树根节点指针
* Precondition: None
* Description: 后序遍历,非递归算法
* Return value: void
* Author: Liu Qi, // [1/1/2006]
===========================================================================*/
void BT_PostOrderNoRec(pTreeT root)
{
stack s;
pTreeT pre=NULL;

while ((NULL != root) !s.empty())
{
if (NULL != root)
{
s.push(root);
root = root->left;
}
else
{
root = s.top();
if (root->right!=NULL &&amp; pre!=root->right){
root=root->right;
}
else{
root=pre=s.top();
visit(root);
s.pop();
root=NULL;
}
}
}
}
/**//*===========================================================================
* Function name: BT_LevelOrder
* Parameter: root:树根节点指针
* Precondition: NULL != root
* Description: 层序遍历
* Return value: void
* Author: Liu Qi, [1/1/2006]
===========================================================================*/
void BT_LevelOrder(pTreeT root)
{
queue q;
treeT *treePtr;

assert( NULL != root );

q.push(root);

while (!q.empty())
{
treePtr = q.front();
q.pop();
visit(treePtr);

if (NULL != treePtr->left)
{
q.push(treePtr->left);
}
if (NULL != treePtr->right)
{
q.push(treePtr->right);
}

}
}


#endif



测试代码

#include
#include
#include
#include "tree.h"

#define MAX_CNT 5
#define BASE 100

int main(int argc, char *argv[])
{
int i;
pTreeT root = NULL;

srand( (unsigned)time( NULL ) );

for (i=0; i

摘自ngaut的博客http://www.cppblog.com/ngaut/archive/2006/01/01/2351.aspx

星期三, 三月 28, 2007

找工作计划

需要仔细思考的事情:
1.自身的情况(优点、缺点、目标等)
2.雇主的情况(需要什么样的人才、做什么产品、竞争对手、行业发展前景等)

星期五, 三月 16, 2007

星期日, 三月 11, 2007

开机不输入密码自动登录的方法

WIN XP

单击“开始/运行”,输入“rundll32 netplwiz.dll,UsersRunDll”,按回车键后弹出“用户帐

户”窗口,看清楚,这可跟“控制面板”中打开的“用户账户”面板窗口不同哦!然后取消选定“要

使用本机,用户必须输入用户名和密码”选项,单击确定,在弹出的对话框中输入你想让电脑每次自

动登录的账户和密码即可。

摘自1603的博客 http://blog.17yy.com/article.php?tid=25479

星期六, 三月 10, 2007

(转)J2EE架构的银行核心业务系统?

J2EE架构的银行核心业务系统?

放眼看世界银行与保险公司的核心业务系统,真正用J2EE架构的确实很少,但作为IT公司与用户却都叫得要往J2EE架构转,这里的原因有几个:
1、IT公司必须炒作新概念,才能获得新利润
目 前各银行与保险公司都有自己的核心业务系统,一般而言一个系统使用时间越长,系统会越稳定(使用过程实际是一个不断的排除BUG与系统优化的过程),但随 着业务的发展,系统还是要有所发展的,如新增业务功能的处理,新增服务渠道等,一个好的架构,这些扩展都可在原有架构上有序的扩展,当然有的系统基础架构 不好,或由于开发过程中的“大跃进”,使得每一次系统升级都要打快速补丁,最终导致破坏了原有良好的系统架构。
系统升级过程中破坏了原来较好的架 构,这是如何做好软件工程的问题,与是否采用J2EE无关,而且在国内导致这个问题更重要的原因是用户方在软件方面的投入不足,要求的开发周期严重不合 理,而打补丁的方法是最快最省市的方法,很少考虑该补丁对系统结构长远是否有不利的影响,结果是系统在几年后不得不作一次大规模的修改,否则原有系统已经 无法打上新的补丁了。这种系统的维护升级方式实际上更花钱,而且风险更大,但用户似乎更能接受,如果采用平稳的升级方法,每次要投入较多的资金与时间,但 风险小,长远来说更省钱,但国内用户很难接受这种理念,老觉得IT公司是要让用户付出更多的费用。实际上这样的开发方式IT公司更喜欢,因为每过几年可能 会拿到一个较大的单子,但由于新的单子也不一定就落到原来开发公司的口袋里,而每次重新招标都会增加很高的市场成本,因此各公司会把更多的精力放在如何维 护与客户的关系上,而对现有产品增加投入则没有动力。这就是国内软件业的现状,并且已经进入恶性循环,到一天国内的软件公司撑不下去了,则用户可能面临着 不得不选国内的产品,但价格则可能是国内产品的几十倍或上百倍。当然国外的产品会在某些方面好于国内的产品,但如果国内的软件公司能取得合理的利润进入良 性发展,也是可以把自己的产品做得更好的。
正因为在上述大环境下,IT公司当然更愿意鼓吹一切新的技术,而不论该技术是否成熟,也不论该技术是否 适合用户的实际需要,因为只有鼓吹新技术才会使系统不断地重新开发,这样才会把市场的总盘子做大,也只有这样,大家才会有钱赚(因为在国内挣不到维护费, 版权费,只有不断变才会有开发费赚)。但变的风险,开发商是不关心的。

2、用户希望简化客户端的维护
C/S结构,客户端程序的升 级安装总是比较麻烦,再加上可能的病毒破坏,客户端操作人员的误删程序等都可能导致不能正常使用系统。用户方的IT技术人员都希望能捞到一种办法,使客户 端象原来的笨终端一样,加电就能用,这样就省事很多。这样基于J2EE架构的B/S结构就很有吸引力。
用户的想法并不错,但简化客户端的维护,不一定只有采用J2EE架构一条路,而用户以为只有J2EE才是唯一的途径正是IT公司长期“教育”的结果。
用 户方的IT人员,特别是CIO们缺乏战略眼光,即使采用传统的C/S结构,使客户端的升级维护可能会麻烦一些,但这只是战术方面的投入,而由于系统架构长 期处于不稳定,特定是在升级过程中如何保证数据迁移不会导致数据“失真”(由于改变架构往往会换一家公司开发,而新的开发商对原有系统的数据库表结构不能 完全了解,最省事的办法也是不负责任的办法,就是库结构一起改,然后进行数据迁移)这些战略方面的风险则很少关心。

架构变更的风险究竟有哪些呢?我们可作简单的归纳:
1、数据风险
在上述讨论中已经提及。
2、系统稳定性
除 非是已经很成熟的应用了软件产品,否则任何一个开发的应用系统都要经过2—3年才能逐步稳定。而国内用户很少同意购买一个产品,再根据产品的要求来对自己 的业务流程进行重组,这样实际上就没有真正意义上的软件产品,即使有一个产品的基本版本,在任何一个用户单位都要经过大量的修改或客户化才能适应用户要 求,结果就是系统的稳定性被破坏,趋于稳定的周期加长。
3、效率风险
任何一种架构实际都是有一定的适用范围。
2层的C/S架构适用的小型企业应用,因为有很多开发工具支持,开发周期快,即使有变化,重新开发的成本不会太大。
N 层C/S架构(采用IBM-CICS,BEA-TUXEDO中间件),该架构已经把业务逻辑设计成一个一个独立的可供调用的SERVICES,增加或修改 业务逻辑只是增加SERVICES或修改已有的SERVICES,客户端只作界面处理。这样的架构使得业务逻辑的变更极为方便,而这正是银行保险这样的应 用更为关心的。这样的架构是专为OLTP应用设计的。
J2EE架构也可把业务逻辑后移,设计成SAERVICES,也可按连接池方式与数据库连 接,从而减少DBMS的系统开销,但J2EE架构在应用服务的平衡负载方面与N层C/S架构比还是比较低级,特别是对于大型应用(如国内较大的保险公司, 如果全国大集中,保单数都会在上千万,甚至上亿),对于这种规模的应用,不但服务端要构建集群架构,数据库可能也要构建集群架构(即构建多个同构的数据库 (同表名,同库名,但存放在不同的数据库服务器中),数据按某种分片规则存放在不同的数据库中)。这种要求J2EE架构是很难支持的,至少目前这样。

合理的解决方案:
1、大型应用核心业务的架构要采用N层的C/S架构
支持大交易量大数据量的要求。
2、客户端可采用WIN终端方式
WIN 终端的界面与WINDOWS的窗口界面风格相同,也可在WIN终端上运行浏览器,即如果是B/S结构也能支持。WIN终端方式客户端的程序是安装在WIN 终端服务器上的,这样与纯C/S结构比,客户端维护也大为简单了,如果开发客户端程序的自动发布与安装程序,则一样可做到“0”维护。
3、客户端的浏览器化
如果确实需要,客户端也可设计成浏览器风格,但对于业务逻辑是调用TUXEDO或CICS服务,而不是调用J2EE服务,这样可充分利用或重用核心业务系统已有的处理逻辑(这也是保证系统稳定的重要手段),也即核心架构不动,但前端的展现架构可跟上潮流。

国 外的大型应用系统的发展正是这样的,在美国还有很多银行或保险公司其核心系统还是用COBOL语言写的,还是用的VSAM文件系统,但在客户端,包括互联 网上的电子商务可能比国内的同行做得更好,其基本思路就是保留原有的核心系统架构(原系统一般称为LEGACY系统),在外围则可引入新的技术手段。

拿亚马逊公司来说,该公司是互联网时代发展出来的新型公司,但其电子商务的网上交易处理则仍然采用的是TUXEDO这样的中间件就可看出,J2EE不该作为这个时代软件架构的“万金油”。

系 统架构的设计更应着重于库表结构的设计及业务逻辑的SERVICES化,而是用TUXEDO, CICS的SERVICES还是用J2EE的SERVICES来实现则要视具体情况而言,即应用越大,或已有TUXEDO/CICS SERVICES,则不能轻言改变,如果应用规模不大,或者确实是新应用,则可尝试采用全新的架构。即架构是否要改变应是由应用决定的而不是由技术决定 的。

另一个问题也是要注意的,一个新的技术从提出到实用是需要时间的。关系数据库理论是1970年提出的,关系数据库产品是到 1980年代中出现的,但真正把关系数据库应用于大型应用系统的开发则是在1990年代的事了,成熟的时间是20年。小型应用多采用新技术,一是风险小, 二是能加速技术的成熟(如果没有实际应用,新技术也是很难成熟的,因此小型应用的尝试也可看作是必要的贡献),而大型应用则应保守些,因为试验的风险太 大,这方面用户方更需要头脑清新,但中国人赶时髦的热情一直是很高的,并且总是喜欢革命也而是改良,但这种习惯在大型应用系统的规划方面实在是要不得。

最 后希望在推广一种新技术时,IT公司要厚道一些,用户方要理智一些。另外也希望用户方在规划IT投入方面,在软件投入上的比例要更合理一些,特别是要加大 对于服务维护的投入,如果软件公司挣到了该挣的钱,则软件公司会更注重提升产品本身的功能与性能,而不会(至少会少些)变着法子让用户不断换系统了。所谓 买的没有卖的精,由于用户方的问题,逼得开方商另想生财之道也是没有办法的办法,但最终损失的是用户,是中国的软件产业。

原文地址:http://www.itpub.net/487375.html

转载自海阔天空 鹰击云飞的博客http://blog.csdn.net/yhhah/archive/2006/12/12/1439523.aspx

星期五, 三月 09, 2007

vs.net2003安装程序检测到另一个程序要求计算机重新启动

首先要安装第1步visual studio.net系统必备,其它点不了.可点第1步安装就弹出"安装程序检测到另一个程序要求计算机重新启动.必须重新启动计算机后才能安装 visual studio.net系统必备.系统重新启动后,你需要重新启动安装程序.单击"确定"重新启动,单击"取消"退出安装程序,以后再安装."对话框.重启 n次都弹出此对话框,无法安装.

解决办法:

运行->regedit

找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager

删除pendingfilerenameoperations

******************************************************************

SQLServer的安装也有同样问题的话,一样的解决办法,也是把PendingFileRenameOperations删除,就可以了。

转载自 小桥流水人家http://by1945.blog.sohu.com/32155731.html

星期四, 三月 08, 2007

电脑开机的时候噪音很大,过一会就好了

冬天天气寒冷导致机箱内某个风扇润滑油凝固,风扇运转困难。运行一段时间后温度上来了,自动就没声音或声音变小了。
解决办法:
1、如果是用润滑油的风扇,那么时间用长了之后里面的润滑油会渐渐挥发掉,再加上现在气温很低,必然出现噪音的现象,建议给风扇加润滑油。打开机箱开机,仔细听听是哪个风箱发出的噪声,然后把风扇拆下,揭开风扇上的标签,会看到一个轴承,滴二滴润滑油就行了。
2、跟机箱内灰尘也有一定关系,建议定期除尘。
3、机箱外壳与机体衔接不紧,风扇在运转的时候会产生轻微振动导致外壳和机体连接不紧处产生噪音,建议重新安装机箱外壳,再不行就把外壳稍稍弄弯一点点,使得外壳与机体衔接更紧密。
4、电脑主机要放在一个平稳而坚固的台面上(比如地上)。

摘自百度知道 http://zhidao.baidu.com/question/18323358.html?fr=qrl3

星期三, 三月 07, 2007

养生之道

晚上 9-11点为免疫系统(淋巴)排毒时间,此段时间应安静或听音乐 。
晚上 11-凌晨 1点,肝的排毒,需在熟睡中进行。
凌晨 1-3点,胆的排毒,亦同。
凌晨 3-5点,肺的排毒。此即为何咳嗽的人在这段时间咳得最剧烈,因排毒动作已走到肺;不应用止咳药,以免抑制废积物的排除。
清晨 5-7点,大肠的排毒,应上厕所排便。
上午 7-9点,小肠大量吸收营养的时段,应吃早餐。疗病者最好早吃,在6点半前,养生者在7点半前,不吃早餐者应改变习惯,即使拖到9、 10 点吃都比不吃好。
半夜至凌晨4点为脊椎造血时段,必须熟睡,不宜熬夜。 千万劳记:工作不是生活的全部!

转载自测试者家园http://www.cnblogs.com/tester2test/archive/2007/03/07/666982.html

添加I'M标志,参与MSN慈善活动

MSN(Windows Live Messenger)用户在昵称上加上一段代码,即可使昵称加上绿色I'M。通过这样,可以给慈善组织捐款,款项将由微软支付。目前有多个可供选择的组 织,希望PRC的兄弟姐妹们选择能捐助到中国的组织。注意是昵称(显示名称)上,不要加错地方:)

  1.American Red Cross
  ——I'm 准备提供帮助。美国红十字协会。代码 = *red+u
  2.Boys and Girls Clubs of America  
  ——I'm 为孩子提供理想的环境。儿童群益会(美国)。代码 = *bgca
  3.National AIDS Fund          
  ——I'm 与艾滋病(AIDS)抗争。美国国家艾艾滋基金。代码 = *naf
  4.National MS Society         
  ——I'm 参与到解决多发性硬化症。国家多发性硬化症学会。= *mssoc
  5.ninemillion.org
  ——I'm 帮助9百万流离失所的孩子。国际儿童难民援助组织。代码 = *9mil
  6.Sierra Club              
  —— I'm 探索和保护这个星球。地球环境协会/山岳协会(保护自然生态)。代码 = *sierra
  7.StopGlobalWarming.org
  ——I'm 阻止全球变暖。防止全球温室效应恶化相关机构。代码 = *help
  8.Susan G. Komen for the Cure    
  ——I'm 寻找乳腺癌的治愈方法。乳腺癌基金会。代码 = *komen
  9.UNICEF
  ——I'm 救助生死边缘徘徊的孩子。美国地区联合国儿童基金会。代码= *unicef
  10.World Wildlife Fund for Nature  
  ——I'm 希望保护环境和野生动物。世界自然基金会。代码 = *wwf
  11.The Oxford Committee for Famine Relief
  ——I'm 协助解决当时世界各地饥荒以及贫困问题。乐施会。代码 = *oxfam
  12.国际关怀协会。
  ——I'm 帮帮鳏寡孤独,改善人际冷漠。代码 = *care   
  13.The Humane Society of the United States
  ——I'm 展现我的人道主义。代码 = *hsus
  14.American Cancer Society
  ——I'm 帮助癌症研究。代码 = *acs
  15.unknown
  代码 = *one

转载自.NET博客园 http://www.cnblogs.com/life

星期一, 三月 05, 2007

访问网上邻居要密码

 默认情况下,Windows XP的本地安全设置要求进行网络访问的用户全部采用来宾方式。同时,在Windows XP安全策略的用户权利指派中又禁止Guest用户通过网络访问系统。这样两条相互矛盾的安全策略导致了网内其他用户无法通过网络访问使用Windows XP的计算机。你可采用以下方法解决。 

方法一:解除对Guest账号的限制 

点击“开始→运行”,在“运行”对话框中输入“GPEDIT.MSC”,打开组策略编辑器,依次选择“计算机配置→Windows设置→安全设置→本地策略→用户权利指派”,双击“拒绝从网络访问这台计算机”策略,删除里面的“GUEST”账号。这样其他用户就能够用Guest账号通过网络访问使用Windows XP系统的计算机了。 

方法二:更改网络访问模式 

打开组策略编辑器,依次选择“计算机配置→Windows设置→安全设置→本地策略→安全选项”,双击“网络访问:本地账号的共享和安全模式”策略,将默认设置“仅来宾—本地用户以来宾身份验证”,更改为“经典:本地用户以自己的身份验证”。 

现在,当其他用户通过网络访问使用Windows XP的计算机时,就可以用自己的“身份”进行登录了(前提是Windows XP中已有这个账号并且口令是正确的)。 

当该策略改变后,文件的共享方式也有所变化,在启用“经典:本地用户以自己的身份验证”方式后,我们可以对同时访问共享文件的用户数量进行限制,并能针对不同用户设置不同的访问权限。 

不过我们可能还会遇到另外一个问题,当用户的口令为空时,访问还是会被拒绝。原来在“安全选项”中有一个“账户:使用空白密码的本地账户只允许进行控制台登录”策略默认是启用的,根据Windows XP安全策略中拒绝优先的原则,密码为空的用户通过网络访问使用Windows XP的计算机时便会被禁止。我们只要将这个策略停用即可解决问题。

转载自百度知道http://zhidao.baidu.com/question/8974197.html

星期日, 三月 04, 2007

java关键词和保留词

java关键词
abstract continue for new switch boolean
default goto null synchronized break do
if package this byte double implements
private threadsafe byvalue else import protected
throw case extends instanceof public transient
catch false int return true char
final interface short try class finally
long static void const float native
super while




java保留词
cast
future
generic
inneroperator
outer
rest
var
标识符不能与任何关键词相同。

java小贴士

1、变量名(标识符)以小写字母开始,多个单词组成的变量名除第一个单词外其余单词的第一个字母均大写,例如:int firstContactTime;
2、类名的第一个字母大写,例如:Car;
3、给变量赋初值是编程的好习惯。
3、如果数字未加任何字母,默认为double。
4、a&&b,如果a为“假”,则不再计算b的值,而得到a&&b的值为“假”。
a&b,分别计算a和b之后,再得出a&b的值。
5、java规定.java文件中必须有且仅有一个public类。
6、被static修饰符修饰的属性或方法在本类中可以不通过类或对象引用。
7、对象作为行参来传递时只是传递了对象的地址,因此在其他方法中对形参对象的修改表现为原对象成员的改变。
8、创建对象时,对属性赋初值就要用到构造函数。
9、创建对象时,如果系统按照实际参数找不到对应的构造函数,将报错而不再自动生成空构造函数。

访问控制符

属性方法访问控制符 可访问的类
public 所有
private 类自身
protected 同一包中的类,不同包中的子类
private protected 类自身,子类
默认(friendly)
同一包中的类


类访问控制符 可访问的类
public 所有
默认(friendly) 同一包中的类

管理单元初始化失败。名称:组策略CLSID:{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}服务

组策略管理单元初始化失败解决方案

这几天我的电脑不知道怎么回事,在“开始”菜单的“运行”中键入"gpedit.msc"的时候,总是弹出一个对话框“组策略管理单元初始化失败”,我也不知道为什么会出现这个问题,于是就上网搜索,结果发现许多人都出现过这种问题,现归纳解决方法如下:
  方法一:1、 点击『开始』菜单 2、点击“运行” 3、键入"regedit"(不包括感叹号) 4、在注册表键值HKEY_CURRENT_USER\ Software\Policies\Microsoft\MMC请将RestrictTo PermittedSnapins 的值设置为 0
  方法二、1、点击『开始』菜单 2、点击“运行” 3、键入"regedit"(不包括感叹号)
4、 在注册表键值 HKEY_CURRENT_USER\Software\Policies\Microsoft\Mmc\{8FC0B734-A0E1- 11D1-A7D3-0000F87571E3}\Restrict_Run和HKEY_CURRENT_USER\Software\  Policies\Microsoft\MMC\{0F6B957E-509E-11D1-A7CC-0000F87571E3}\Restrict_Run
请将 Restrict_Run 的值设置为 0 5、修改完毕后重启。
  方法三、1、点击『开始』菜单 2、点击“运行” 3、键入"regedit"(不包括感叹号)
4、 在注册表键值HKEY_CLASSES_ROOT\CLSID\{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}\ InProcServer32把其中的default改成:%SystemRoot%\System32\GPEdit.dll 5、修改完毕后重启。
方法四、检 查环境变量:a、点击『开始』菜单 b、点击“控制面板”c、在“控制面板”中打开“系统”d、在“系统属性”中点击“高级”标签 e、在“高级”标签页 中点击“环境变量”按钮 f、在“环境变量”中的“系统变量”框中的变量名为Path中修改变量值为:%Systemroot%\System32;% Systemroot%;%Systemroot%\system32\WBEM
方法五、运行regsvr32 filemgmt.dll a、点击『开始』菜单 b、点击“运行”c、键入"regsvr32 filemgmt.dll"(不包括感叹号)
方法六、如果组策略找不到 framedyn.dll,就可能会出现这种错误。如果使用安装脚本,要确保脚本置于系统路径中的%windir%\system32\wbem 目录下。默认情况下,%windir%\system32\wbem 已经存在于系统路径中,因此,如果您不使用安装脚本,就不可能遇到这个问题。或试着将将Framedyn.dll文件从\windows\system32\wbem目录下拷贝到\windows\system32目录下!
附:如果在方法一/二中提到的MMC项在你的计算机注册表中找不到,那么就手动建立即可。
或者直接将下面内容复制粘贴进入记事本,并保存为后缀名为.reg的文件,双击运行该.reg文件即可。
-----------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\LocalUser\Software\Policies\Microsoft\MMC]

[-HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\LocalUser\Software\Policies\Microsoft\MMC\{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}]
"Restrict_Run"=dword:00000000

[HKEY_CURRENT_USER\Software\Policies\Microsoft\MMC]

[-HKEY_CURRENT_USER\Software\Policies\Microsoft\MMC\{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}]
"Restrict_Run"=dword:00000000

[HKEY_CURRENT_USER\Software\Policies\Microsoft\MMC]
"RestrictToPermittedSnapins"=dword:00000000

转载自“神经蛮人的个人主页” 地址:http://gumanren.139.com/article/1157679.html