焦点新闻

焦点新闻
俄专家称卫星撞击碎片可能波及带核卫星19:52
数十块卫星碎片可能威胁航天员安全
NASA称国际空间站或被迫变轨以避开卫星残骸
【抗旱总动员】因地制宜 多措并举 各地全力抗旱..20:03
新华时评:农民工集中返乡是农村党建的新契机18:25
奥巴马新政”一波三折” 布什的”负遗产”影响深远16:55
火箭飞机齐上阵 人工增雨缓解百日旱情19:03
杭州公务员部分工资欲强变消费券引质疑09:09
2009情人节之夜:京城多种情侣活动一览(图)17:42
解密吴淑珍:要夫要子要钱 扁背后推手大肆”干政”17:17
做,就要做王瑛那样的纪检干部18:16
蒙牛回应特仑苏添加OMP称安全性受FDA认可16:21
香港亚视盛传12日大裁员 三成员工或受影响(图)

Leave a comment

好久没来了,过来发发牢骚。

        断断续续折腾了3天,发现一个简单问题。


        首先BS一下这样乱用的旧同事,然后对着MySQL ODBC 2.5 Driver笑笑。


        MySQL中字段是字符型,数据全是数字,对于开头为0的,如果通过 MySQL ODBC 2.5 Driver去查询,条件是数值型的,将查不到数据。而MySQL可以,MySQLCC也可以。

Posted in 信手涂鸦 | Leave a comment

在程序中调试activeform

常在Delphi里面Debug程序,我们只需要按下 F5 ,就可以设置和取消断点,
这样能够一步一步地调试程序,发现程序中存在的问题。


但是当我们开发基于 Internet Explorer 浏览器的ActiveForm的时候,
调试就成了一个大问题,因为Delphi无法控制 IE。那么说,Delphi就不能
调试基于IE的 ActiveForm 了吗? 事实上并不是这样,只要通过对ActiveForm
的项目工程进行一些设定,你会发现调试一个ActiveForm也是很简单的。


步骤如下:


创建
创建一个 ActiveForm的工程。
填写 Project | Web Deployment Options 对话框
Target Dir 和 HTML Dir 填入同的路径,例如 “c:\activex”
Target URL 填入 ActiveForm 所在的 Web 路径
如果你希望浏览器能够自动更新你的 ActiveForm,请选取 “Include file Version Number”
和 “Auto Increment Release Number” 
调试
因为IE浏览器是ActiveForm的宿主(Host),所以我们通过Delphi IDE里面的 Run | Parameters 对话框。在 Host Application 中 填写 IE 的可执行文件的名称。
Program Files$\Internet Explorer\IEXPLORE.EXE
在 Parameters 中填写 调用 ActiveForm 的HTML文件的名称。
Run | Register 注册这个ocx,然后用Frontpage新建个网页, 插入 | Web组件..高级控件-ActiveX控件,选择这个ocx,保存后就可以用这个网页文件调试了。
两个参数都是必须填写完整的路径名。

说在后面
在IE装载 ActiveForm 的过程中,它会把 ActiveForm 拷贝到一个缓冲文件夹中执行它,而不是我们开头已经设定好了的ActiveForm的分发路径,这个缓冲文件夹通常是诸如“Downloaded Program Files”等等。


 

Posted in 文章:Delphi | Leave a comment

MS SQL Server查询优化方法

MS SQL Server查询优化方法


710905  2003-11-30  来源:陶清论坛(www.pdriver.com)


●查询速度慢的原因很多,常见如下几种:
1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)
2、I/O吞吐量小,形成了瓶颈效应。
3、没有创建计算列导致查询不优化。
4、内存不足
5、网络速度慢
6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)
7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。
9、返回了不必要的行和列
10、查询语句不好,没有优化


●可以通过如下方法来优化查询 :
1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.
2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)
3、升级硬件
4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段
5、提高网速;
6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。
配置虚拟内存:
虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server™ 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:
将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。
将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。
7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT,DELETE还不能并行处理。
8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。
like ‘a%’ 使用索引
like ‘%a’ 不使用索引
用 like ‘%a%’ 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。
9、DB Server 和APPLication Server 分离;OLTP和OLAP分离
10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件’分区视图’)
a、在实现分区视图之前,必须先水平分区表


b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的
名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。
11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE.
设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。


在T-sql的写法上有很大的讲究,下面列出常见的要点:
首先,DBMS处理查询计划的过程是这样的:
1、 查询语句的词法、语法检查
2、 将语句提交给DBMS的查询优化器
3、 优化器做代数优化和存取路径的优化
4、 由预编译模块生成查询规划
5、 然后在合适的时间提交给系统处理执行
6、 最后将执行结果返回给用户
其次,看一下SQL SERVER的数据存放的结构:
一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。
Commit和rollback的区别
Rollback:回滚所有的事物。
Commit:提交当前的事物.
没有必要在动态SQL里写事物,如果要写请写在外面如:
begin tran
exec(@s)
commit trans
或者将动态SQL 写成函数或者存储过程。


13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。
14、SQL的注释申明对执行没有任何影响
15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类:
只进
必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。
可滚动性
可以在游标中任何地方随机提取任意行。
游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。
有四个并发选项
READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。
OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。
选择这个并发选项仁褂没Щ虺绦蛟背械T鹑危砟切┍硎酒渌没б丫云浣辛诵薷牡拇砦蟆Sτ贸绦蚴盏秸庵执砦笫辈扇〉牡湫痛胧┚褪撬⑿掠伪辏竦闷湫轮担缓笕糜没Ь龆ㄊ欠穸孕轮到行薷摹?BR>OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某


个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。
SCROLL LOCKS
这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。
滚动锁
根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。
所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。
锁提示 只读 乐观数值 乐观行版本控制 锁定
无提示 未锁定 未锁定 未锁定 更新
NOLOCK 未锁定 未锁定 未锁定 未锁定
HOLDLOCK 共享 共享 共享 更新
UPDLOCK 错误 更新 更新 更新
TABLOCKX 错误 未锁定 未锁定 更新
其它 未锁定 未锁定 未锁定 更新
*指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。
16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引
17、注意UNion和UNion all 的区别。UNION all好
18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的
19、查询时不要返回不需要的行、列


20、用sp_configure ‘query governor cost limit’或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。SET LOCKTIME设置锁的时间


21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行
22、在SQL2000以前,一般不要用如下的字句: “IS NULL”, “<>”, “!=”, “!>”, “!<”, “NOT”, “NOT EXISTS”, “NOT IN”, “NOT LIKE”, and “LIKE ‘%500′”,因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1) = ‘m’改为WHERE firstname like ‘m%’(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,“NOT”, “NOT EXISTS”, “NOT IN”能优化她,而”<>”等还是不能优化,用不到索引。
23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。
24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引:
SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)
25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。
26、MIN() 和 MAX()能使用到合适的索引。
27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健\主健\Check\UNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。



28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作:
方法:Create procedure p_insert as insert into table(Fimage) values (@image),
在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。


29、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。
select * from chineseresume where title in (‘男’,'女’)
Select * from chineseresume where between ‘男’ and ‘女’
是一样的。由于in会在比较多次,所以有时会慢些。


30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。



31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。
32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索
引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。
33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。
34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。
SELECT top 20 ad.companyname,comid,position,ad.referenceid,worklocation,
convert(varchar(10),ad.postDate,120)
as postDate1,workyear,degreedescription
FROM jobcn_query.dbo.COMPANYAD_query ad
where referenceID
in(‘JCNAD00329667′,’JCNAD132168′,’JCNAD00337748′,’JCNAD00338345′,’JCNAD00333138′,’JCNAD00303570′,
‘JCNAD00303569′,’JCNAD00303568′,’JCNAD00306698′,’JCNAD00231935′,’JCNAD00231933′,’JCNAD00254567′,
‘JCNAD00254585′,’JCNAD00254608′,’JCNAD00254607′,’JCNAD00258524′,’JCNAD00332133′,’JCNAD00268618′,
‘JCNAD00279196′,’JCNAD00268613′)
order by postdate desc


35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。


36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是select INTO.
drop table t_lxh
begin tran
select * into t_lxh from chineseresume where name = ‘XYZ’
–commit
在另一个连接中SELECT * from sysobjects可以看到
SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。
37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快
41、一次更新多条记录比分多次更新每次一条快,就是说批处理好
42、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好
43、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:
a、计算字段的表达是确定的
b、不能用在TEXT,Ntext,Image数据类型
c、必须配制如下选项
ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….
44、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。
以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程
45、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快
46、SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别:
select count(Field of null) from Table 和 select count(Field of NOT null) from Table
的返回值是不同的!!!
47、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;
否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。
48、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就
会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现



49、通过SQL Server Performance Monitor监视相应硬件的负载
Memory: Page Faults / sec计数器
如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。
Process:
1、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。
2、%Processor Time计数器
 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。
3、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。
  4、% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增
加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。


Physical Disk: Curretn Disk Queue Length计数器
该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。
SQLServer:Cache Hit Ratio计数器
该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。
40、分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。
41、查询的关联同写的顺序
select a.personMemberID, * from chineseresume a,personmember b where
personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681′
(A = B ,B = ‘号码’)
select a.personMemberID, * from chineseresume a,personmember b where
a.personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681′
and b.referenceid = ‘JCNPRH39681′
(A = B ,B = ‘号码’, A = ‘号码’)
select a.personMemberID, * from chineseresume a,personmember b where
b.referenceid = ‘JCNPRH39681′ and a.personMemberID = ‘JCNPRH39681′
(B = ‘号码’, A = ‘号码’)


42、(1) IF 没有输入负责人代码 THEN
code1=0
code2=9999
ELSE
code1=code2=负责人代码
END IF
执行SQL语句为:
SELECT 负责人名 FROM P2000 WHERE 负责人代码>=:code1 AND负责人代码 <=:code2
(2) IF 没有输入负责人代码 THEN
 SELECT 负责人名 FROM P2000
ELSE
code= 负责人代码
SELECT 负责人代码 FROM P2000 WHERE 负责人代码=:code
END IF
第一种方法只用了一条SQL语句,第二种方法用了两条SQL语句。在没有输入负责人代码时,第二种方法显然比第一种方法执行效率高,因为它没有限制条件;在输入了负责人代码时,第二种方法仍然比第一种方法效率高,不仅是少了一个限制条件,还因相等运算是最快的查询运算。我们写程序不要怕麻烦


43、关于JOBCN现在查询分页的新方法(如下),用性能优化器分析性能的瓶颈,如果在I/O或者网
络的速度上,如下的方法优化切实有效,如果在CPU或者内存上,用现在的方法更好。请区分如下的方法,说明索引越小越好。
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by ReferenceID
select * from @local_variable where Fid > 40 and fid <= 60
end

begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from @local_variable where Fid > 40 and fid <= 60
end
的不同


begin
create table #temp (FID int identity(1,1),ReferenceID varchar(20))
insert into #temp (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from #temp where Fid > 40 and fid <= 60
drop table #temp
end

Posted in 信手涂鸦 | Leave a comment

《大腕》经典台词 与 对白精选


以下是影片对白精选:


   泰勒:唐纳德-萨瑟兰饰
  尤优:葛优饰
  路易王:英达饰
  露茜:关之琳饰


  泰勒:你看,中国的皇宫是由两种颜色组成的,红色的墙和金色的瓦。红色代表鲜血,黄金象征财富,谁能不惜黄金和鲜血?只有皇帝。这就是东方人对权力的理解,而且是毫不掩饰的。但从人的角度来看,一个孩子当他走上王位的那一天起,作为一个统治者,他的一生都将是非常孤独的。所以贝特鲁奇的皇帝是伤感的。他知道这个角度是最能打动西方人的。


   尤优:NO,他有很多漂亮的女人,如果他有心气的话,可以每天换一个,而且不用花钱,都是朝廷给他养着。我只有一个女人,还跟我离婚了,我的一生才是悲剧的。”


  尤优:No money,no women(没有钱,没有女人。)才是悲剧的。悲剧怎么说?


  泰勒心领神会:No good。


  尤优:耶耶。


  泰勒:Good,I love you (很好,我爱你。)


  尤优:我也I love you您。


  尤优:我们中国有句话,叫早死早脱生,这辈子过不好还有下辈子,轮回转世,坏事变好事。


  泰勒:中国人很会安慰自己。


  尤优:耶耶。(加手势比划着说)Chinese seventy years以上的old people die,no bad finish,is good finish中国人七十岁以上的老人死了,不是坏的结束,是好的结束。……(急得想不出词)Every body cheers(所有的人喝酒干杯)……就是葬礼很happy(高兴)。葬礼怎么说,急死我了。


  露茜:你到底想说什么?


  尤优:我想说,在中国活过七十年以上的老人死了,葬礼是喜丧。


  泰勒:我明白了,他是不是说,中国老人的葬礼象喜剧。


  路易王:根据泰勒先生生前的愿望,我们将为他老人家举行一个节目丰富多彩,形式类似春节晚会、快乐大本营、欢乐总动员,同时又有点象赈灾义演一样的葬礼。使其悲中有喜,喜中有悲,悲喜交加。这次活动的总设计师为泰勒先生本人,监制是露茜小姐,总导演由我本人和尤优联袂担纲,由泛太平洋演出公司承办。


       露茜:联袂担纲是什么意思?


  尤优:就是联合挂帅。


  路易王:葬礼的主题是八个字,团结、奋进、继往开来。


  尤优:这个提法是不是太中国了,不国际。是不是可以改为,和平、友谊、进步。
         路易王重复了一遍,说:怎么听着这么耳熟呵,好象哪次大型活动上用过。


  尤优:亚运会。


  路易王:对对对,我看可以。记下来,六个字,和平、友谊、进步。下面,让我们来讨论一下举行葬礼的地点。


   路易王:泰勒虽是美国人,但他的祖籍在意大利,所以葬礼将以中国著名导演张艺谋执导的意大利歌剧《图兰多》开场。


   露茜:那开场就需要两个小时?


  路易王:当然不能是全剧,只能精选其中的一个经典片段。《今夜无人入睡》怎么样?


   尤优:还是《好一朵美丽的茉莉花》吧。这段旋律是意大利作曲家普契尼根据中国民歌创作的,既是泰勒故乡的音乐,听上去又更中国。


  路易王:接下来便是由著名笑星冯巩、牛群合说的相声悼词,《戏说泰勒》。


  尤优向露茜解释:就是把悼词编成你们美国的脱口秀。


   路易王:然后就该煽点情了。由中国著名摇滚歌手臧天朔演唱他自己创作的歌曲《朋友》。


   路易王:最后的一个单元,我们称之为泰勒的新生。时间太紧了,请你粗略地看一个动画演示吧。


  尤优解释道:这孩子就是泰勒转世。


  露茜:泰勒是白种人,可为什么变出来的小孩是黄种人?


  露茜:但我认为,他是什么是,变出来的就应该还是什么人。


  路易王:那不利于增进中美两国之间的友谊,而且还很可能伤害了热情的中国人民的感情,这是我们不愿意看到的。


  露茜:但你想没想过,会伤害美国人民的感情呢?


   尤优:好了,不要争了。泰勒是国际大腕,世界名导,不能因为他是白种人就一定还变成白种人,你别急露茜,听我说完。当然也不能因为他的葬礼在中国办了就非得变成黄种人,应该是哪里最需要他,他就变成哪儿的人。非洲的电影正处于起步阶段,我觉得他应该变成黑人,一个小黑孩横空出世。(为了安慰露茜,尤优又补充道:)这样吧,小孩的皮肤虽然是黑的,但口音可以保留泰勒的原声。(向路易王解释:)就是电影里,意大利黑手党说话的那种语调。


  露茜心有不甘地:一定要变成黑人吗?


  尤优:没办法,世界上的人就这三种色,除非你同意他变成鸟或鱼什么的,那可以选择的色就多多了。


  路易王:OK,变成黑的。


  张总:我的要求就是,在葬礼的整个过程中,这位蒙着黑纱的神密的女子将始终伴随在泰勒的遗体边。


   尤优:这小狐狸是谁呀?


  张总说:她是泰勒的情人。


  尤优:这不可能,泰勒没有情人。他这岁数就是有这心也没这力了。您这创意搁在克林顿的葬礼上还差不多。


  路易王:当然这不是真的,她的真实身份是张总新签约的女演员。刚在网上选出来的潘金莲。张总想让她以泰勒情人的身份在葬礼上曝光,媒体不是就喜欢搞八卦吗?一夜她就成名了。


   尤优:戏没红人先红了。


  路易王:就是这意思,如果咱们同意,张总愿意支付葬礼的全部费用,五百万。


  张总:你刚才不是说四百万吗?怎么又涨了?


   路易王:四百万她得蒙着黑纱,您要出五百万,我们同意她把黑纱摘了,整个葬礼过程中切她三回特写。


   张总:那得让她爬在泰勒的身上哭三十秒。


   路易王:哭十分钟都成。我再给您打一个狠折,刚才我不是跟您说,葬礼的最后,泰勒不是要变成一小孩吗?


   张总点头:就是泰勒的新生那个单元。


   路易王:您再加五十万,我让这孩子一变出来,谁都不认,就认她,张嘴就能喊出她的名来。(问女子:)你叫什么名呀?


   女子:妮娜。


   尤优:妮娜还是留着给张总自己当情人吧。我觉得张总下这么大的本,不如捧红自己,给您整整容,整成一杂种的样,以泰勒私生子的身份参加葬礼,保证媒体也呜泱呜泱的….


   路易王:搜狗想和咱们合作,对葬礼进行一次大胆的改革,破除旧有的传统观念对葬礼的束缚,充分使之更适合二十一世纪新人类经济发展…..战略,不是战略,刚才你是怎么说的来着汤姆李?


   汤姆李:就是一种新的经济模式,我们IT行业把这种模式称之为:生当做人杰,死亦为鬼雄…..


   尤优:我不太明白,听着怎么那么乱呵?


   路易王:这么跟你说吧,就是挖掘葬礼的经济潜力,向葬礼要效益。


   汤姆李:我们计划建立一个全球最大的“太平网站”首先开通一个“搜狗葬礼在线”,搞网上葬礼,广告词我们都想好了,就叫“上搜狗,搜泰勒”。


   尤优:你们打算出多少钱买我们的授权呀?现在惦记这事的网特多,各种在线都在找我们。


   路易王:我电话都不敢接。


   汤姆李:如果你们同意的话,我们愿意提供搜狗商务网,无偿的,为泰勒的葬礼进行一次广告招商,使名人葬礼成为发布名优新产品的新视窗,新平台,以此作为对你们授权的回报。你们愿意的话,我们还可以负责将葬礼包装上市,用股民的钱办葬礼,再用葬礼的广告收入使股票升值。你算算你们二位能赚多少钱吧?


   路易王;不是两位,是三位,还有我呢。


 

Posted in 信手涂鸦 | Leave a comment

解读C#中的正则表达式

作者:刘彦青  


    多少年来,许多的编程语言和工具都包含对正则表达式的支持,.NET基础类库中包含有一个名字空间和一系列可以充分发挥规则表达式威力的类,而且它们也都与未来的Perl 5中的规则表达式兼容。
  
  此外,regexp类还能够完成一些其他的功能,例如从右至左的结合模式和表达式的编辑等。
  
  在这篇文章中,我将简要地介绍System.Text.RegularExpression中的类和方法、一些字符串匹配和替换的例子以及组结构的详细情况,最后,还会介绍一些你可能会用到的常见的表达式。
  
应该掌握的基础知识


  规则表达式的知识可能是不少编程人员“常学常忘”的知识之一。在这篇文章中,我们将假定你已经掌握了规则表达式的用法,尤其是Perl 5中表达式的用法。.NET的regexp类是Perl 5中表达式的一个超集,因此,从理论上说它将作为一个很好的起点。我们还假设你具有了C#的语法和.NET架构的基本知识。
  
  如果你没有规则表达式方面的知识,我建议你从Perl 5的语法着手开始学习。在规则表达式方面的权威书籍是由杰弗里·弗雷德尔编写的《掌握表达式》一书,对于希望深刻理解表达式的读者,我们强烈建议阅读这本书。
  
RegularExpression组合体


  regexp规则类包含在System.Text.RegularExpressions.dll文件中,在对应用软件进行编译时你必须引用这个文件,例如:


csc r:System.Text.RegularExpressions.dll foo.cs


命令将创建foo.exe文件,它就引用了System.Text.RegularExpressions文件。
  
名字空间简介


  在名字空间中仅仅包含着6个类和一个定义,它们是:
  
  Capture: 包含一次匹配的结果;
  CaptureCollection: Capture的序列;
  Group: 一次组记录的结果,由Capture继承而来;
  Match: 一次表达式的匹配结果,由Group继承而来;
  MatchCollection: Match的一个序列;
  MatchEvaluator: 执行替换操作时使用的代理;
  Regex: 编译后的表达式的实例。


  Regex类中还包含一些静态的方法:


  Escape: 对字符串中的regex中的转义符进行转义;
  IsMatch: 如果表达式在字符串中匹配,该方法返回一个布尔值;
  Match: 返回Match的实例;
  Matches: 返回一系列的Match的方法;
  Replace: 用替换字符串替换匹配的表达式;
  Split: 返回一系列由表达式决定的字符串;
  Unescape:不对字符串中的转义字符转义。
  
简单匹配


  我们首先从使用Regex、Match类的简单表达式开始学习。
  
Match m = Regex.Match(“abracadabra”, “(a|b|r)+”);
  
我们现在有了一个可以用于测试的Match类的实例,例如:if (m.Success)…
如果想使用匹配的字符串,可以把它转换成一个字符串:
  
Console.WriteLine(“Match=”+m.ToString());
  
这个例子可以得到如下的输出: Match=abra。这就是匹配的字符串了。
  
字符串的替换


  简单字符串的替换非常直观。例如下面的语句:
  
string s = Regex.Replace(“abracadabra”, “abra”, “zzzz”);
  
它返回字符串zzzzcadzzzz,所有匹配的字符串都被替换成了zzzzz。


  现在我们来看一个比较复杂的字符串替换的例子:
  
string s = Regex.Replace(” abra “, @”^\s*(.*?)\s*$”, “$1″);
  
这个语句返回字符串abra,其前导和后缀的空格都去掉了。
  
  上面的模式对于删除任意字符串中的前导和后续空格都非常有用。在C#中,我们还经常使用字母字符串,在一个字母字符串中,编译程序不把字符“ \” 作为转义字符处理。在使用字符“\”指定转义字符时,@”…”是非常有用的。另外值得一提的是$1在字符串替换方面的使用,它表明替换字符串只能包含被替换的字符串。
  
匹配引擎的细节


  现在,我们通过一个组结构来理解一个稍微复杂的例子。看下面的例子:
  
string text = “abracadabra1abracadabra2abracadabra3″;
  
    string pat = @”   
      ( # 第一个组的开始   
       abra # 匹配字符串abra   
       ( # 第二个组的开始   
       cad # 匹配字符串cad   
       )? # 第二个组结束(可选)   
      ) # 第一个组结束   
      + # 匹配一次或多次   
      ”;   
    //利用x修饰符忽略注释   
    Regex r = new Regex(pat, “x”);   
    //获得组号码的清单   
    int[] gnums = r.GetGroupNumbers();   
    //首次匹配   
    Match m = r.Match(text);   
    while (m.Success)   
     {   
    //从组1开始   
     for (int i = 1; i < gnums.Length; i++)   
      {   
      Group g = m.Group(gnums[i]);   
    //获得这次匹配的组   
      Console.WriteLine(“Group”+gnums[i]+”=["+g.ToString()+"]“);
    //计算这个组的起始位置和长度   
      CaptureCollection cc = g.Captures;   
      for (int j = 0; j < cc.Count; j++)   
       {   
       Capture c = cc[j];   
       Console.WriteLine(” Capture” + j + “=["+c.ToString()   
         + "] Index=” + c.Index + ” Length=” + c.Length);   
       }   
      }   
    //下一个匹配   
     m = m.NextMatch();   
     }   
 这个例子的输出如下所示:      
    Group1=[abra]   
        Capture0=[abracad] Index=0 Length=7   
        Capture1=[abra] Index=7 Length=4   
    Group2=[cad]   
        Capture0=[cad] Index=4 Length=3   
    Group1=[abra]   
        Capture0=[abracad] Index=12 Length=7   
        Capture1=[abra] Index=19 Length=4   
    Group2=[cad]   
        Capture0=[cad] Index=16 Length=3   
    Group1=[abra]   
        Capture0=[abracad] Index=24 Length=7   
        Capture1=[abra] Index=31 Length=4   
    Group2=[cad]   
        Capture0=[cad] Index=28 Length=3
  我们首先从考查字符串pat开始,pat中包含有表达式。第一个capture是从第一个圆括号开始的,然后表达式将匹配到一个abra。第二个capture组从第二个圆括号开始,但第一个capture组还没有结束,这意味着第一个组匹配的结果是abracad ,而第二个组的匹配结果仅仅是cad。因此如果通过使用?符号而使cad成为一项可选的匹配,匹配的结果就可能是abra或abracad。然后,第一个组就会结束,通过指定+符号要求表达式进行多次匹配。
  
  现在我们来看看匹配过程中发生的情况。首先,通过调用Regex的constructor方法建立表达式的一个实例,并在其中指定各种选项。在这个例子中,由于在表达式中有注释,因此选用了x选项,另外还使用了一些空格。打开x选项,表达式将会忽略注释和其中没有转义的空格。
  
  然后,取得表达式中定义的组的编号的清单。你当然可以显性地使用这些编号,在这里使用的是编程的方法。如果使用了命名的组,作为一种建立快速索引的途径这种方法也十分有效。
  
  接下来是完成第一次匹配。通过一个循环测试当前的匹配是否成功,接下来是从group 1开始重复对组清单执行这一操作。在这个例子中没有使用group 0的原因是group 0是一个完全匹配的字符串,如果要通过收集全部匹配的字符串作为一个单一的字符串,就会用到group 0了。
  
  我们跟踪每个group中的CaptureCollection。通常情况下每次匹配、每个group中只能有一个capture,但本例中的Group1则有两个capture:Capture0和Capture1。如果你仅需要Group1的ToString,就会只得到abra,当然它也会与abracad匹配。组中ToString的值就是其CaptureCollection中最后一个Capture的值,这正是我们所需要的。如果你希望整个过程在匹配abra后结束,就应该从表达式中删除+符号,让regex引擎知道我们只需要对表达式进行匹配。
  
基于过程和基于表达式方法的比较


  一般情况下,使用规则表达式的用户可以分为以下二大类:第一类用户尽量不使用规则表达式,而是使用过程来执行一些需要重复的操作;第二类用户则充分利用规则表达式处理引擎的功能和威力,而尽可能少地使用过程。
  
  对于我们大多数用户而言,最好的方案莫过于二者兼而用之了。我希望这篇文章能够说明.NET语言中regexp类的作用以及它在性能和复杂性之间的优、劣点。
  
基于过程的模式


  我们在编程中经常需要用到的一个功能是对字符串中的一部分进行匹配或其他一些对字符串处理,下面是一个对字符串中的单词进行匹配的例子:


string text = “the quick red fox jumped over the lazy brown dog.”;   
    System.Console.WriteLine(“text=[" + text + "]“);   
    string result = “”;   
    string pattern = @”\w+|\W+”;   
    foreach (Match m in Regex.Matches(text, pattern))   
     {   
    // 取得匹配的字符串   
     string x = m.ToString();   
    // 如果第一个字符是小写   
     if (char.IsLower(x[0]))   
    // 变成大写   
      x = char.ToUpper(x[0]) + x.Substring(1, x.Length-1);   
    // 收集所有的字符   
     result += x;   
     }   
    System.Console.WriteLine(“result=[" + result + "]“);  
   正象上面的例子所示,我们使用了C#语言中的foreach语句处理每个匹配的字符,并完成相应的处理,在这个例子中,新创建了一个result字符串。这个例子的输出所下所示:   
  text=[the quick red fox jumped over the lazy brown dog.]   
  result=[The Quick Red Fox Jumped Over The Lazy Brown Dog.]   


基于表达式的模式
  完成上例中的功能的另一条途径是通过一个MatchEvaluator,新的代码如下所示:   
static string CapText(Match m)   
      {   
    //取得匹配的字符串   
      string x = m.ToString();   
    // 如果第一个字符是小写   
      if (char.IsLower(x[0]))   
    // 转换为大写   
       return char.ToUpper(x[0]) + x.Substring(1, x.Length-1);   
      return x;   
      }   
     static void Main()   
      {   
      string text = “the quick red fox jumped over the   
       lazy brown dog.”;   
      System.Console.WriteLine(“text=[" + text + "]“);   
      string pattern = @”\w+”;   
      string result = Regex.Replace(text, pattern,   
     new MatchEvaluator(Test.CapText));   
      System.Console.WriteLine(“result=[" + result + "]“);   
      }   
  同时需要注意的是,由于仅仅需要对单词进行修改而无需对非单词进行修改,这个模式显得非常简单。


常用表达式
  为了能够更好地理解如何在C#环境中使用规则表达式,我写出一些对你来说可能有用的规则表达式,这些表达式在其他的环境中都被使用过,希望能够对你有所帮助。   


罗马数字
string p1 = “^m*(d?c{0,3}|c[dm])” + “(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$”;   
    string t1 = “vii”;   
    Match m1 = Regex.Match(t1, p1);   


交换前二个单词
string t2 = “the quick brown fox”;   
    string p2 = @”(\S+)(\s+)(\S+)”;   
    Regex x2 = new Regex(p2);   
    string r2 = x2.Replace(t2, “$3$2$1″, 1);
  
关健字=值
string t3 = “myval = 3″;   
    string p3 = @”(\w+)\s*=\s*(.*)\s*$”;   
    Match m3 = Regex.Match(t3, p3);
  
实现每行80个字符
string t4 = “********************”   
     + “******************************”   
     + “******************************”;   
    string p4 = “.{80,}”;   
    Match m4 = Regex.Match(t4, p4);
  
月/日/年 小时:分:秒的时间格式
string t5 = “01/01/01 16:10:01″;   
    string p5 = @”(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)”;   
    Match m5 = Regex.Match(t5, p5);
  
改变目录(仅适用于Windows平台)
string t6 = @”C:\Documents and Settings\user1\Desktop\”;   
  string r6 = Regex.Replace(t6,@”\\user1\\“, @”\\user2\\“);
  
扩展16位转义符
string t7 = “%41″; // capital A   
    string p7 = “%([0-9A-Fa-f][0-9A-Fa-f])”;   
    string r7 = Regex.Replace(t7, p7, HexConvert);
  
删除C语言中的注释(有待完善)
string t8 = @”   
    /*   
     * 传统风格的注释   
     */   
    ”;   
    string p8 = @”   
     /\* # 匹配注释开始的定界符   
     .*? # 匹配注释   
     \*/ # 匹配注释结束定界符   
    ”;   
    string r8 = Regex.Replace(t8, p8, “”, “xs”);
  
删除字符串中开始和结束处的空格
string t9a = ” leading”;   
    string p9a = @”^\s+”;   
    string r9a = Regex.Replace(t9a, p9a, “”);   
    string t9b = “trailing “;   
    string p9b = @”\s+$”;   
    string r9b = Regex.Replace(t9b, p9b, “”);
  
在字符\后添加字符n,使之成为真正的新行
string t10 = @”\ntest\n”;   
string r10 = Regex.Replace(t10, @”\\n“, “\n”);
 
转换IP地址
string t11 = “55.54.53.52″;   
    string p11 = “^” +   
     @”([01]?\d\d|2[0-4]\d|25[0-5])\.” +   
     @”([01]?\d\d|2[0-4]\d|25[0-5])\.” +   
     @”([01]?\d\d|2[0-4]\d|25[0-5])\.” +   
     @”([01]?\d\d|2[0-4]\d|25[0-5])” +   
     “$”;   
    Match m11 = Regex.Match(t11, p11);   


删除文件名包含的路径
string t12 = @”c:\file.txt”;   
    string p12 = @”^.*\\”;   
    string r12 = Regex.Replace(t12, p12, “”);
  
联接多行字符串中的行
string t13 = @”this is   
    a split line”;   
    string p13 = @”\s*\r?\n\s*”;   
    string r13 = Regex.Replace(t13, p13, ” “);
  
提取字符串中的所有数字
string t14 = @”   
    test 1   
    test 2.3   
    test 47   
    ”;   
    string p14 = @”(\d+\.?\d*|\.\d+)”;   
    MatchCollection mc14 = Regex.Matches(t14, p14);
  
找出所有的大写字母
string t15 = “This IS a Test OF ALL Caps”;   
    string p15 = @”(\b[^\Wa-z0-9_]+\b)”; //[A-Z]+  
    MatchCollection mc15 = Regex.Matches(t15, p15);
  
找出小写的单词
string t16 = “This is A Test of lowercase”;   
    string p16 = @”(\b[^\WA-Z0-9_]+\b)”;   
    MatchCollection mc16 = Regex.Matches(t16, p16);
  
找出第一个字母为大写的单词
string t17 = “This is A Test of Initial Caps”;   
    string p17 = @”(\b[^\Wa-z0-9_][^\WA-Z0-9_]*\b)”;   
    MatchCollection mc17 = Regex.Matches(t17, p17);   


找出简单的HTML语言中的链接
string t18 = @”   
    <html>   
    <a href=”"first.htm”">first tag text</a>   
    <a href=”"next.htm”">next tag text</a>   
    </html>   
    ”;   
    string p18 = @”<A[^>]*?HREF\s*=\s*[""']?” + @”([^'"" >]+?)[ '""]?>”;   
    MatchCollection mc18 = Regex.Matches(t18, p18, “si”);

Posted in 文章:web | Leave a comment

修改背景的方法最终版。 再世为虫 提供

<STYLE TYPE=”text/css”>
<!–
body{
    background-attachment:fixed;
    background-image : url(http://www.cndev.org/.imgdb/sn10025/GUID-21E9D0E0-6BA1-4858-A76F-09D00EFE4F32.jpg);
}
#top{
    background-color : transparent;
    background-image : none;
}
#leftmenu{
    background-color : transparent;
}
#main {
    background-color : transparent;
}
div.post
{
    background-color : transparent;
}
div.postTitle
{
    background-color : transparent;
}
div.postText
{
    background-color : transparent;
}
div.postFoot
{
    background-color : transparent;
}
–>
</STYLE>

Posted in 文章:web | Leave a comment

【提取SQL注释,生成数据字典】

【提取SQL注释,生成数据字典】
select A.name as TableName, B.name as ColName, C.Name as Type,B.length,
case when B.isnullable=0 then ‘NOT NULL’ else ‘NULL’ end as ‘NULL’,
D.Value as Memo
from sysobjects A
left join syscolumns B on A.id=B.id
left join systypes C on C.xusertype = B.xusertype
left join sysproperties D on? B.id=D.id and D.smallid=B.colid
where A.type=’U’
and A.name like ‘Table’
order by A.name

Posted in Language | Leave a comment

我也美化一下,谢谢 http://zhong.cndev.org/

谢谢http://zhong.cndev.org/

我也美化一下。

Posted in 信手涂鸦 | Leave a comment

用宏代码清除除Excle2000文档中的宏代码、部分控件


‘removeExcelMacro(“Book1.Xls”,Array(“CheckBox1″,”TextBox1″,”ListBox”))

‘直接删除目标文件的宏代码和控件(可选择保留的控件),Excel文件名称、要删除的控件名称数组
Public Static Function removeExcelMacro(targetExcelFileName As String, killOleObjectType As Variant) As Boolean
    On Error GoTo ErrHand
    Dim i, j, n As Byte
    Dim vbeComp As New VBComponents
    Dim vbaObje As OLEObject
    removeExcelMacro = False
    Set vbeComp = Application.Workbooks(targetExcelFileName).VBProject.VBComponents
    n = vbeComp.Count
    For i = 1 To n
        If i > vbeComp.Count Then Exit For


        If vbeComp(i).Type = 100 Then   ‘   100: xl_Document_Type(Include Workbook , Worksheet)
            ‘删除代码
            If vbeComp(i).CodeModule.CountOfLines > 0 Then vbeComp(i).CodeModule.DeleteLines 1, vbeComp(i).CodeModule.CountOfLines
            ‘删除控件
            vbeComp(i).Activate
            If killOleObjectType(0) <> “” Then
              For Each vbaObje In ActiveSheet.OLEObjects
                 For j = 0 To UBound(killOleObjectType)
                    If UCase(Split(vbaObje.ProgId, “.”)(1)) = UCase(killOleObjectType(j)) Then
                      vbaObje.Select: Selection.Delete
                    End If
                 Next
              Next
            End If
        Else
            ‘删除整个模块
            vbeComp.Remove vbeComp(i)
            i = i – 1
        End If
     Next
    removeExcelMacro = True
    Exit Function
ErrHand:
    MsgBox Err.Description & vbCrLf & vbCrLf & “请与XXX联系!”, vbOKOnly + vbCritical
End Function

Posted in 信手涂鸦 | Leave a comment