<![CDATA[chinayaowei.bokee.com]]> zh_cn Tue,17 Jul 2007 12:21:44 CST Thu,17 Jul 2008 15:08:25 CST http://www.bokee.com http://reg.bokee.com/account/web/img/logo.gif 博客网 http://www.bokee.com 您好,欢迎访问yunle110.bokee.com <![CDATA[伤心了,走了,到新家去了:http://blog.163.com/cn_yw/]]> .html 伤心了,走了,到新家去了:

 

1.文章,生活   http://blog.163.com/cn_yw/

 

2.技术         http://blog.csdn.net/cn_yw 

 

 

不信就没有一个可以让说真话的地方都没有?

 

还是那句话:那个贴子是国家网监局通知你们要删除的么?不是吧!那就是你们自己胆怯,以小人之心,度国家威威尊严.

伤心地走了

 

欢迎各位朋友到我的新家:

 

 

http://blog.163.com/cn_yw/

 

http://blog.csdn.net/cn_yw

 

]]>
Thu,17 Jul 2008 15:08:25 CST 0
<![CDATA[BOKEE网,你无权掠夺我的著作]]> .html BOKEE网,你无权掠夺我的著作

 

 

       关于本人在BOKEE网发表的“ 人见人转<<贵州省瓮安副县长惨无人道 6.28事件>>希望我国政府摆正姿态 ”,你们无权掠夺我的著作!著作权,是属于我的。虽然你们以“小人之心”把他删除。但,我有权要回我的文章。请速归还!

 

 

 

 

]]>
Mon,07 Jul 2008 08:49:59 CST 0
<![CDATA[利用索引提高Informix查询效率]]> .html

 

 

]]>
Fri,20 Jun 2008 14:05:37 CST 0
<![CDATA[现场目击"贵阳犯警方击毙劫持"视频]]> .html http://www.daqi.com/bbs/20/2043641.html

]]>
Thu,19 Jun 2008 17:07:07 CST 0
<![CDATA[英汉翻译方法]]> .html  

英汉翻译方法

英汉两种语言在句法、词汇、修辞等方面均存在着很大的差异,因此在进行英汉互译时必然会遇到很多困难,需要有一定的翻译技巧作指导。常用的翻译技巧有增译法、省译法、转换法、拆句法、合并法、正译法、反译法、倒置法、包孕法、插入法、重组法和综合法等。这些技巧不但可以运用于笔译之中,也可以运用于口译过程中,而且应该用得更加熟练,因为口译工作的特点决定了译员没有更多的时间进行思考。 
 
1增译法:指根据英汉两种语言不同的思维方式、语言习惯和表达方式,在翻译时增添一些词、短句或句子,以便更准确地表达出原文所包含的意义。这种方式多半用在汉译英里。汉语无主句较多,而英语句子一般都要有主语,所以在翻译汉语无主句的时候,除了少数可用英语无主句、被动语态或
"There be…"结构来翻译以外,一般都要根据语境补出主语,使句子完整。英汉两种语言在名词、代词、连词、介词和冠词的使用方法上也存在很大差别。英语中代词使用频率较高,凡说到人的器官和归某人所有的或与某人有关的事物时,必须在前面加上物主代词。因此,在汉译英时需要增补物主代词,而在英译汉时又需要根据情况适当地删减。英语词与词、词组与词组以及句子与句子的逻辑关系一般用连词来表示,而汉语则往往通过上下文和语序来表示这种关系。因此,在汉译英时常常需要增补连词。英语句子离不开介词和冠词。另外,在汉译英时还要注意增补一些原文中暗含而没有明言的词语和一些概括性、注释性的词语,以确保译文意思的完整。总之,通过增译,一是保证译文语法结构的完整,二是保证译文意思的明确。如: 
(1)What about calling him right away? 
马上给他打个电话,你觉得如何? (增译主语和谓语) 
(2)If only I could see the realization of the four mod
ernizations. 
要是我能看到四个现代化实现该有多好啊!(增译主句) 
(3) Indeed, the reverse is true  
实际情况恰好相反。(增译名词) 
(4) 就是法西斯国家本国的人民也被剥夺了人权。 
Even the people in the fascist countries were stripped of their human  
rights.(增译物主代词) 
(5)只许州官放火,不许百姓点灯。 
While the magistrates were free to burn down house, the common people were  
forbidden to light lamps. (增译连词) 
(6)这是我们两国人民的又一个共同点。 
This is yet another common point between the people of our two  
countries.(增译介词) 
(7)在人权领域,中国反对以大欺小、以强凌弱。 
In the field of human rights, China opposes the practice of the big  
oppressing the small and the strong bullying the weak.(增译暗含词语) 
(8)三个臭皮匠,合成一个诸葛亮。 
Three cobblers with their wits combined equal Zhuge Liang the  
mastermind.(增译注释性词语) 
 
2. 省译法:这是与增译法相对应的一种翻译方法,即删去不符合目标语思维习惯、语言习惯和表达方式的词,以避免译文累赘。增译法的例句反之即可。又如: 
(1)You will be staying in this hotel during your visit in Beijing. 
你在北京访问期间就住在这家饭店里。(省译物主代词) 
(2) I hope you will enjoy your stay here. 
希望您在这儿过得愉快。(省译物主代词) 
(3)中国政府历来重视环境保护工作。 
The Chinese government has always attached great importance to  
environmental protection. (
省译名词
3转换法:指翻译过程中为了使译文符合目标语的表述方式、方法和习惯而对原句中的词类、句型和语态等进行转换。具体的说,就是在词性方面,把名词转换为代词、形容词、动词;把动词转换成名词、形容词、副词、介词;把形容词转换成副词和短语。在句子成分方面,把主语变成状语、定语、宾语、表语;把谓语变成主语、定语、表语;把定语变成状语、主语;把宾语变成主语。在句型方面,把并列句变成复合句,把复合句变成并列句,把状语从句变成定语从句。在语态方面,可以把主动语态变为被动语态。如: 
(1) 我们学院受教委和市政府的双
重领导。 
Our institute is co-administrated by the States Education Commission and  
the municipal government. (名词转动词) 
(2)Too much exposure to TV programs will do great harm to the eyesight of  
children. 
孩子们看电视过多会大大地损坏视力。(名词转动词) 
(3)由于我们实行了改革开放政策,我国的综合国力有了明显的增强。 
Thanks to the introduction of our reform and opening policy, our  
comprehensive national strength has greatly improved. (动词转名词) 
(4) I'm all for you opinion. 
我完全赞成你的意见。(介词转动词) 
(5)The reform and opening policy is supported by the whole Chinese people. 
改革开放政策
受到了全中国人民的拥护。(动词转名词) 
(6)In his article the author is critical of man's negligence toward his  
environment. 
作者在文章中,对人类疏忽自身环境作了批评。(形容词转名词) 
(7)In some of the European countries, the people are given the biggest  
social benefits such as medical insurance. 
在有些欧洲国家里,人民享受最广泛的社会福利,如医疗保险等。(被动语态转主动语态) 
(8)时间不早了,我们回去吧! 
We don't have much time left. Let's go back. (句型转换) 
(9)学生们都应该德、智、体全面发展。 
All the students should develop morally, intellectually and physically.  
(名词转副词) 
 
4.拆句法和合并法:这是两种相对应的翻译方法。拆句法是把一个长而复杂的句子拆译成若干个较短、较简单的句子,通常用于英译汉;合并法是把若干个短句合并成一个长句,一般用于汉译英。汉语强调意合,结构较松散,因此简单句较多;英语强调形合,结构较严密,因此长句较多。所以汉译英时要根据需要注意利用连词、分词、介词、不定式、定语从句、独立结构等把汉语短句连成长句;而英译汉时又常常要在原句的关系代词、关系副词、主谓连接处、并列或转折连接处、后续成分与主体的连接处,以及意群结束处将长句切断,译成汉语分句。这样就可以基本保留英语语序,顺译全句,顺应现代汉语长短句相替、单复句相间的句法修辞原则。如: 
(1) Increased
cooperation with China is in the interests of the United  
States. 
同中国加强合作,符合美国的利益。 (在主谓连接处拆译) 
(2)I wish to thank you for the incomparable hospitality for which the  
Chinese people are justly famous throughout the world. 
我要感谢你们无与伦比的盛情款待。中国人民正是以这种热情好客而闻明世界的
。(在定语从句前拆译) 
(3)This is particularly true of the countries of the commonwealth, who see  
Britain's membership of the Community a guarantee that the policies of the  
community will take their interests into account 
英联邦各国尤其如此,它们认为英国加入欧共体,将能保证欧共体的政策照顾到它们的利益。(在定语从句前拆译) 
(4)中国是个大国,百分之八十的人口从事农业,但耕地只占土地面积的十分之一,其余为山脉、森林、城镇和其他用地。 
China is a large country with four-fifths of the population engaged in  
agriculture, but only one tenth of the land is farmland, the rest being  
mountains, forests and places for urban and ot
her uses.(合译) 
 
5.正译法和反译法:这两种方法通常用于汉译英,偶尔也用于英译汉。所谓正译,是指把句子按照与汉语相同的语序或表达方式译成英语。所谓反译则是指把句子按照与汉语相反的语序或表达方式译成英语。正译与反译常常具有同义的效果,但反译往往更符合英语的思维方式和表达习惯。因此比较地道。如: 
(1) 在美国,人人都能买到枪。 
In the United States, everyone can buy a gun. (正译) 
In the United States, guns are avai
lable to everyone. (反译
(2) 你可以从因特网上获得这一信息。 
You can obtain this information on the Internet. (正译) 
This information is accessible/available on the Internet. (反译) 
(3) 他突然想到了一个新主意。 
Suddenly he had a new idea. (正译) 
He suddenly thought out a new idea. (正译) 
A new idea suddenly occurred to/struck him.
(反译) 
(4) 他仍然没有弄懂我的意思。 
He still could not understand me. (正译) 
Still he failed to understand me. (反译) 
(5) 无论如何,她算不上一位思维敏捷的学生。 
She can hardly be rated as a bright student. (正译) 
She is anything but a bright student. (反译)
 
6 Please withhold the document for the time being.  
请暂时扣下这份文件。(正译) 
请暂时不要发这份文件。(反译) 
 
6.  倒置法:在汉语中,定语修饰语和状语修饰语往往位于被修饰语之前;在英语中,许多修饰语常常位于被修饰语之后,因此翻译时往往要把原文的语序颠倒过来。倒置法通常用于英译汉,  
即对英语长句按照汉语的习惯表达法进行前后调换,按意群或进行全部倒置,原则是使汉语译句安排符合现代汉语论理叙事的一般逻辑顺序。有时倒置法也用于汉译英。如: 
(1)At this moment, through the wonder of telecommunications, more people  
are seeing and hearing what we say than on any other occasions in the  
whole history of the world. 
此时此刻,通过现代通信手段的奇迹,看到和听到我们讲话的人比整个世界历史上任何其他这样的场合都要多。(部分倒置) 
(2)I believe strongly that it is in the interest of my countrymen that  
Britain should remain an active and energetic member of the European  
Community. 
我坚信,英国依然应该是欧共体中的一个积极的和充满活力的成员,这是符合我国人民利益的。(部分倒置) 
(3)改革开放以来,中国发生了巨大的变化。 
Great changes have taken place in China since the introduction of the  
reform and opening policy.(全部倒置) 
 
7.包孕法:这种方法多用于英译汉。所谓包孕是指在把英语长句译成汉语时,把英语后置成分按照汉语的正常语序放在中心词之前,使修饰成分在汉语句中形成前置包孕。但修饰成分不宜过长,否则会形成拖沓或造成汉语句子成分在连接上的纠葛。如: 
(1)You are the representative of a country and of a continent to which  
China feels particularly close.
您是一位来自于使中国倍感亲切的国家和大洲的代表。 
(2)What brings us together is that we have common interests which  
transcend those differences. 使我们走到一起的,是我们有超越这些分歧的共同利益。 
 
8.插入法:指把难以处理的句子成分用破折号、括号或前后逗号插入译句中。这种方法主要用于笔译中。偶尔也用于口译中,即用同位语、插入语或定语从句来处理一些解释性成分。如: 
如果说宣布收回香港就会像夫人说的"带来灾难性的影响
",那我们要勇敢地面对这个灾难,做出决策。 
If the announcement of the recovery of Hong Kong would bring about, as  
Madam put it, "disastrous effects," we will face that disaster squarely  
and make a new policy decision. 
 
9.重组法:指在进行英译汉时,为了使译文流畅和更符合汉语叙事论理的习惯,在捋清英语长句的结构、弄懂英语原意的基础上,彻底摆脱原文语序和句子形式,对句子进行重新组合。如: 
Decision must be made very rapidly; physical endurance is tested as much  
as perception, because an enormous amount of time must be spent making  
certain that the key figures act on the basis of the same information and
 
purpose. 
必须把大量时间花在确保关键人物均根据同一情报和目的行事,而这一切对身体的耐力和思维能力都是一大考验。因此,一旦考虑成熟,决策者就应迅速做出决策。 
 
10.综合法:是指单用某种翻译技巧无法译出时,着眼篇章,以逻辑分析为基础,同时使用转换法、倒置法、增译法、省译法、拆句法等多种翻译技巧的方法。如: 
How can the European Union contribute to the development of a European  
film and television program industry which is competitive in the world  
market, forward-looking and capable of radiating the influence of European  
culture and of creating jobs in Europe? 
欧洲联盟应该怎样做才能对欧洲的电影电视工业有所贡献,使它在国际市场上具有竞争能力,使它有能力发挥欧洲文化的影响,并且能够在欧洲创造更多的就业机会呢?
 

]]>
Thu,19 Jun 2008 08:52:13 CST 0
<![CDATA[网吧特色人]]> .html   网吧里的特色人!

  在网吧里,任何时间都会有人在吃饭,有人在睡觉,有人在玩。不论是清晨,中午,还是深夜,都有一些人挺不住了,他们用疲惫无神的双眼仔细注视着屏幕,仿佛创作中的马克思。他们是铁人,施瓦辛格死了他们都死不了,马克思挺不住了他们都挺的住,埃塞俄比亚的难民觉得饿了他们都不饿,沙漠的非洲土著渴了他们也不会渴,他们是神的化身,是精神力量的体现。

  ——网吧里有不怕困的人,你玩的时候他们在玩,你睡觉了他们在玩,等你醒了他仍在玩,等你睡了他依旧在玩。

  ——网吧里有不怕冷的人,你穿着羽绒服还是觉得冷气袭人,他只穿了一件薄毛衣,还把袖子挽起来。最难得是他们满面红光。

  ——网吧里有不怕饿的人。整整24小时了,这期间你吃了两份炒饼,一瓶啤酒,5个茶叶蛋,一份炒饭和好几瓶可乐。但是他什么都没吃,却比你还精神。

  ——网吧里有不怕脏的人。他屏幕旁边的桌子上有一个装方便面的碗,里面有两厘米厚的剩下的汤,已经同烟灰、烟头和成泥了,你看一眼都会把隔夜饭吐出来,而他却还心安理得的往里吐痰。

  ——网吧里有不怕黏的人。他的头发和脸上的油比你家抽油烟机上的都多,但是他还是露出了天真灿烂的笑容。

  ——网吧里有不用新陈代谢的人。已经整整48小时了,这期间别说是拉屎撒尿,他连个屁都没放过。

  ——网吧里有诚实的人。一个满脸麻子、有白头发、戴着眼镜还有龅牙的女胖子在OICQ里对他的男网友说:“其实我不是很漂亮的。”

  ——网吧里有虚伪的人。那个男网友给她回信息:“没关系,我这个人不是很注重外表的。”

  ——网吧里有贱人。他同时下载了5首MP3、同时下着一盘四国军棋、一盘围棋、一盘五子棋、还打着一桌麻将、玩着5张ShowHand,后台打开着四五个明星新

]]>
Mon,16 Jun 2008 09:22:54 CST 0
<![CDATA[ResultSet 已定义的方法集]]> .html ResultSet 已定义的方法集:

 

一、  滚动结果集:  
   
  rs.previous(); 向前滚动  
   
  rs.next();向后滚动  
   
  rs.getRow();  得到当前行号  
   
  rs.absolute(n);   光标定位到n行  
   
  rs.relative(int   n);  相对移动n行  
   
  rs.first();   将光标定位到结果集中第一行。  
   
  rs.last();   将光标定位到结果集中最后一行。  
   
  rs.beforeFirst()  将光标定位到结果集中第一行之前。  
   
  rs.afterLast();    将光标定位到结果集中最后一行之后。  
   
  rs.moveToInsertRow()    光标移到插入行  
   
  rs.moveToCurrentRow();    光标移回到调用rs.moveToInsertRow()方法前光标所在行   
    
  二、测试光标位置 

 

    
  rs.isFirst()  
   
  rs.isLast()  
   
  rs.isBeforeFirst()  
   
  rs.isAfterLast()   
   
三、更新结果集:  
   
  rs.insertRow();         把插入行加入数据库和结果集  
   
  rs.deleteRow();           从数据库和结果集中删除当前行  
   
  rs.update类型(int   column,类型  data);      
    
  rs.update类型(String   columnName,String   Data);   
  最后要  更新数据库
  rs.updateRow();             更新内容发送到更新数据库  

]]>
Thu,12 Jun 2008 14:56:59 CST 0
<![CDATA[informix领域的空缺查询动态表]]> .html informix领域的空缺查询动态表

 

 

 

       真的没办法了.已经过去4天了,在JAVA中可以动态生成SQL语句。由于生成的SQL语句过于繁杂反锁庞大,查询速度非常的慢。所以,要在存储过程里完成这项查询并把结果返回。可是,informix不支持from 变量 、where 变量 =变量 。

 

      想了很久,试了多次,查了很多,一句话:必须完成。突破中。。。。。。。

]]>
Thu,05 Jun 2008 12:17:36 CST 0
<![CDATA[电动车电池(原理级讲解)]]> .html 电动车电池(原理级讲解)

 

一、令人头痛的电动车电池问题

对于电动自行车来说,发展势头异常迅猛。近几年每年的实际产量都超过社会保有量,这是一个惊人的数据,这表明着电动车的产销上正经历着最辉煌的历史。身在这个红红火火的市场,赚钱并不是太困难的事。但是,每个优势行业都有“软肋”,如果要问在这个行业中搏击的老板级人物,什么是经销电动车最头痛的问题,唯一的答案就是电池寿命短。
现在大部分厂家都承诺电池质保一年,商家当然就这么宣传,可是半年后问题出来了,大量的用户回来,他们不是来二次消费的,也不是介绍朋友来购车的,而是来更换电池。就算电池厂家履行保修承诺,用户们也不会满意,他们会认为这是电动车的质量问题,经销商花费了大量的精力,还是不能避免被投诉。也许这个问题出在电池制造商那里,可是电池制造商也有苦衷,电池的设计及循环放电试验都表明,电池的循环寿命的确是一年半甚至两年,生产时也严格按照工艺流程控制质量,可半年后很多电池就会老化。有的厂家开始尝试用寿命更长的固体电池、镍电池甚至锂电池代替铅电池,但高昂的成本在以上班族为主消费群的市场面前失去了竞争优势,很多富有开拓和进取精神的厂商被无情地打败。我们都知道,诸如电视、计算机等很多电子产品的寿命可长达十年,但厂家也只提供一年的质保,而电动车电池最多就两年的寿命,电池制造商们却要硬撑着质保一年,这是为掩饰电动车电池寿命不理想这个无可奈何的现实,同时为稳定用户的消费信心。这个“硬着头皮”质保的方法短期内还能抵挡片刻,时间长了,问题总会凸现出来。所以,这个行业里出现了很多游击队式的厂商,他们以半年为周期,不建立固定客户群,以损害整个行业利益为代价而谋取着他们个人的利益。

那么如何提高电池的寿命,如何改进电池的的使用环境等等问题都是大家非常失望但又关心的问题。为了弄清楚延长电池寿命的途径,首先就要弄清楚电池的失效机理,以便对症下药。
二、电动车铅蓄电池寿命短的原因
从1859年,法国人加斯东普兰特发现了铅酸充放电的现象后,铅酸蓄电池一直是电池领域应用最广泛的产品,如汽车、机车、轮船、飞机、后备供电设备上都有铅酸蓄电池,但我们并有听到很多来自这些领域对铅酸蓄电池的不满,然而,为什么同样的产品到了电动自行车上却是名符其实的“怨声载道”。下面我们从几个方面阐述产生这一问题的原因。
铅酸蓄电池充放电的过程是电化学反应的过程,充电时,硫酸铅形成氧化铅,放电时氧化铅又还原为硫酸铅。而硫酸铅是一种非常容易结晶的物质,当电池中电解溶液的硫酸铅浓度过高或静态闲置时间过长时,就会“抱成”团,结成小晶体,这些小晶体再吸引周围的硫酸铅,就象滚雪球一样形成大的惰性结晶,结晶后的硫酸铅充电时不但不能再还原成氧化铅,还会沉淀附着在电极板上,造成了电极板工作面积下降,这一现象叫硫化,也就是常说的老化。这时电池容量会逐渐下降,直至无法使用。当硫酸铅大量堆集时还会吸引铅微粒形成铅枝,正负极板间的铅枝搭桥就造成电池短路。如果极板表面或密封塑壳有缝隙,硫酸铅结晶就会在这些缝隙内堆积,并产生膨胀张力,最终使极板断裂脱落或外壳破裂,造成电池不可修复性物理损坏。所以,导致铅酸蓄电池失效和损坏的主要机理就是电池本身无法避免的硫化。
2、电动自行车特殊工作环境的原因
只要是铅蓄电池,在使用的过程中都会硫化,但其它领域的铅酸电池却比电动自行车上使用的铅酸电池有着更长的寿命,这是因为电动自行车的铅酸电池有着一个更容易硫化的工作环境。

①深度放电

用在汽车上的铅蓄电池只是在点火时单向放电,点火后发电机会对电池自动充电,不造成电池深度放电。而电动自行车在骑行时不可能充电,经常会超过60%的深度放电,深放电时,硫酸铅浓度增加,硫化就会相当严重。

②大电流放电
电动车20公里巡航电流一般是4A,这个值已经高于其它领域的电池工作电流,而超速超载的电动车的工作电流就更大。电池制造商都进行过1C充电70%,2C放电60%的循环寿命试验。经过这样的寿命试验,可达到充放电循环350次寿命的电池很多,但是实际在用的效果就相差甚远了。这是因为大电流工作增加了50%的放电深度,电池会加速硫化。所以,电动三轮摩托车的电池寿命更短,因为三轮摩托车的车身太重,工作电流达6A以上。
③充放电频率高
 
用在后备供电领域的电池,只有在停电时才会放电,如果一年停8次电,要达到10年的寿命,只用做到80次循环充电寿命,而电动车一年充放电循环300次以上很常见。

④短时充电
由于电动自行车是交通工具,可充电的时间不多,要在8小时内完成36伏或48伏的20安时充电,这就必须提高充电电压(一般为单节2.7~2.9伏),当充电电压超过单节电池的析氧电压(2.35伏)或析氢电压(2.42伏)时,电池就会因过度析氧而开阀排气,造成失水,使电解液浓度增加,电池的硫化现象加重。

⑤放电后不能及时充电
作为交通工具,电动自行车的充电及放电被完全分离开来,放电后很难有条件及时充电,而放电后形成的大量硫酸铅如果超过半小时不充电还原为氧化铅,就会硫化结成晶体。

3、铅蓄电池生产方面的原因
针对电动自行车用铅酸蓄电池的特殊性,各个电池制造商采取了多种方法。最典型的方法如下:

①增加极板数量。

把原设计的单格5片6片制改为6片7片制,7片8片制,甚至8片9片制。靠减薄极板厚度和隔板,增加极板数量来提高电池容量。
②提高电池的硫酸比重。
 
原来浮充电池的硫酸比重一般都在1.21~1.28之间,而电动自行车的电池的硫酸比重一般都在1.36~1.38左右,这样可以提供较大的电流,提升电池的初期容量。
 
③增加正极板活性物质氧化铅的用量和比例。
 
增加氧化铅就增加了参与放电的电化学反应物质,也就增加了放电时间,增加了电池容量。
 
通过这些措施,电池的初期容量满足了电动自行车的容量要求,特别是改善了电池的大电流放电的特性。但是,极板增加了,硫酸的容量就减少了,电池发热导致大量失水,同时,电池的微短路和铅枝搭桥的概率增加了。提高硫酸比重增加了电池的初期容量,但是,硫化现象就更严重。密封电池的最基本原理之一就是正极板析氧以后,氧气直接到负极板,被负极板吸收而还原为水,考核电池这个技术指标的参数叫做“密封反应效率”,这种现象叫做“氧循环”。这样,电池的失水很少,实现了“免维护”,就是免加水。为此,都要求负极板容量做的比正极板容量大一些,又称为负极过渡。增加正极板活性物质必然使得,负极过渡减少了,氧循环变差了,失水增加了,又会造成硫化。这些措施虽然提升了电池的初期容量,但是却会造成失水和硫化,而失水和硫化又会相互促成,最终结果却是牺牲电池的寿命。

还有就是极群组装虚焊问题。容易产生虚焊的地方是极板。而每个电池的单格有15片极板,就是15个焊点,一个电池有6个单格,就有90个焊点,一组电池由3个12V电池组成,就有270个焊点。如果一个焊点存在虚焊,该单格容量就下降,进而该单格形成电池落后,造成整个电池都落后,电池就会形成严重的不均衡,使这组电池提前失效。就算虚焊控制在万分之一,平均每37组电池就会有一组电池存在虚焊,这是绝对不能够允许的。而铅钙合金板栅的电池,在焊接的时候会析出钙而掩盖虚焊问题,这样,很多电池制造商宁愿采用低锑合金的板栅而没有采用铅钙合金。而低锑合金的板栅析氧析氢电压更低,电池出气量大,失水相对严重,电池更容易硫化。

4、电动自行车生产方面的原因

大多数车的控制器都留了一个线损插头,很多经销商以去掉限速来招揽顾客。一些车厂干脆就去掉限速器出厂,既可以吸引看重车速的客户,也能降低成本,这样的车在高速行驶时电流非常大,会严重缩短电池寿命。
12V铅酸电池的最低保护电压为10.5V,如果是36V电池组,最低保留电压就是31.5V,目前大多数车厂采用的控制器欠压保护电压也都是31.5V。表面上看这是正确的,但是,实际当36V电池组只剩下31.5V电压时,由于电池存在容量差,肯定就会有一个电池电压低于10.5V,该电池就处于过放电状态。这时候,过放电的电池容量急剧下降,这时对电池的损伤影响不仅仅是该单只电池,而是影响整组电池的寿命。其实,在电池电压低于32V以后一直到27V,所增加的续行能力不到2公里,而对电池的损伤却非常大。只要出现这样的情况10次,电池的容量就会低于标称容量的70%。另外,一些用户发现电池在欠压以后,过10分钟,电池又不欠压了,就又采取给电行驶,这对电池破坏更大,而大多数车的说明书没有给用户以警示。目前多数控制器内部都有可调的电位器,而这个可调的电位器的振动漂移是比较严重的。在价格竞争中,面对更注重车外表的用户群,很少有产品采用抗振动的精密多圈电位器,这样的控制器发生振动后漂移也不奇怪。
 
5、充电设备的原因
 
业界广为流传的一句话就是:电池不是用坏的,是充坏的。为了满足电动自行车电池的短时高容量充电,在三段式恒压限流充电中,不得不通过提高恒压值到2.47V~2.49V。这样,大大超过电池正极板析氧电压和负极板析氢电压。一些充电器制造商的产品为了降低充电时间的指示,提高了恒压转浮充的电流,而使得充电指示充满电以后,还没有充满电,就靠提高浮充电压来弥补。这样,很多充电器的浮充电压超过单格电压2.35V,这样在浮充阶段还在大量析氧。而电池的氧循环又不好,这样在浮充阶段也在不断的排气。恒压值高了,保证了充电时间,但是牺牲的是失水和硫化。恒压值低了,充电时间和充入电量又难以保证。在改善电池的电池板栅合金、提高析气电位、改善氧循环性能,提高密封反应效率的基础上,控制充电最高充电电压在2.42V以下,也就是在析氢电位以下。这样做必然会导致充电时间的延长,这就必须在大电流充电(限流充电)的状态下,加入去极化的负脉冲,改善电池的充电接受能力,在大电流充电的时候多充入一些电量,缩短充电时间。70%的2C电流充电,是电池在充电接受能力比较大的时候,对电池采用大电流充电,对电池的损伤比较小。电池基本上没有高于严重析氢电压。一旦高于析氢电压,电池也会快速的失水。使用这类充电器,必须采用连续充放电,如果中途停止几天充电,电池就会产生比较严重的硫化而提前失效。而用户使用电池,是无法保证每次使用以后,都能够及时充电的,一年以内发生数次没有及时充电的情况,电池的硫化就会积累。多数充电器制造商都说车厂因为价格因素不接受可以保证电池寿命的充电器。应该承认,这是大多数小企业是如此,但是,有发展的、规模性大企业确实出高价也买不到好的充电器。一些充电器制造商把某些功能夸大,成品的功效没有其宣传的那样好。还有不少功能是属于卖概念的功能,实效有限。

6、其它原因
不少电池在单体测试中,可以获得比较好的结果,但是,对于串连电池组来说,由于容量、开路电压、荷电状态、硫化程度各不相同,这个差异会在串连电池组被扩大,状态差的单体会影响整组电池,其寿命明显下降。

从电池在生产线上充电,到用户购车后配车使用这段时间要经过很多环节,间隔时间甚至会长达数月,在这期间,由于没对电池进行补充电,自放电产生的硫酸铅大量堆积结晶,用户刚买到的新电池可能是已经老化甚至报费的电池。

电池厂家在执行质保时,对回收电池并不是完全的淘汰。电池返退以后,电池制造商重新进行充放电检验,在检验中往往会发现有60%以上的单体电池是不符合返退条件的电池。其原因也就是在串连电池组中,个别的电池落后形成整组电池功能下降而引起整组返退。不少电池制造商对返退电池采取配组、补水、除硫、包装后,又重新提供给用户,以提高电池的有效使用寿命,降低报废率,减少电池制造商的部分理索赔的损失,所以,很多经销商已经感觉到厂家提供的电池明显“一代不如一代”。
三、如何解决电池的硫化
要减小电池的硫化,延长电池的使用寿命,首先就要改善电动自行车的工作环境。减小车身自重,去掉不必要的装饰件,适当限速,不搭载重物,长时间不使用电动自行车时要做补充充电,最好每次放电后都能及时充电,做好欠压保护,严防电池过放电,对于标称24V的欠压保护应该设在21.5V~22V,对于标称36V的欠压保护应该选32.5V±0.5V,对于标称48V的应该设在44V~45V。这样的电压对续行能力仅仅减少不到2公里,但是可以有效延长电池的使用寿命。每三个月定期到专业维修点检修电池,及时补水。这些方法简单易行,经济成本很低,但要严格遵守却有一定难度。所以,可以使用专门的设备进行除硫维护,这些方法有:

1.使用台式快速除硫设备
台式快速除硫设备的工作原理是高电压大电流脉冲充电,通过负阻击穿消除硫化。这种方法速度快,见效快,可以获得暂时的消除硫化的效果,但是,高电压大电流能击除硫也能除活性物质,在消除硫化中带来严重失水和正极板软化的问题,对电池产生致命的损伤,经过这类设备除硫两次后的电池基本都会报废。另外,目前的专业维修点进行一次除硫收费基本在60~80元之间,最多能延长电池寿命半年,并没有为用户来显著的经济利益。目前,市场上的专业电池维护店主都已经明白了这种方法的危害.于是,又出现了脉冲放电除硫的设备,其实,根本原理并没有变,只是从恒高压恒大电流变成了瞬时峰值高压,还是会损伤极板活性物质,用过这类产品的朋友应该很清楚这点.

2.选择可除硫充电器
目前可除硫充电器有三种工作原理,一种是类同于台式快速除硫设备的工作原理,采用高电压大电流脉冲充电,通过负阻击穿除硫,上面已经说明了这种方法对电池寿命会构成致命伤害,已被市场否定。第二种是采用快速的脉冲前沿的充放电脉冲,利用瞬间峰值,在充电过程中干扰电池的硫化。另一种是周期性的采用10%~20%的过充电的方法,还原电池的硫酸铅结晶。这两种充电器都可以在充电时除硫,但会造成欠充或过充,也忽略了电池放电过程才是最主要的硫化过程这一事实,所以,效果并不理想,大部分用户在具备电动车配备的充电器后会放弃这种重复投资的除硫方式。

]]>
Tue,03 Jun 2008 12:31:10 CST 0
<![CDATA[电动车的使用和保养详细说明]]> .html 电动车的使用和保养详细说明

 


1、电动自行车使用前应调整好鞍座和车把的高度,以保证骑行的舒适性,减轻疲劳。鞍座和车把高度应因人而异,一般鞍座的高度以骑行者能够单脚可靠着地为适宜(整车应基本保持直立),车把的高度以骑行者小臂平放、肩部和手臂放松为适宜。但鞍座和车把的调整应首先保证过管及把立管的插入深度必须高于安全标志线。
2、电动自行车使用前应检查并调整好前后刹车。前刹车由右闸把控制,后刹车由左闸把控制。前后刹车的调整以左右闸把手柄达到一半行程时即能可靠刹车为适宜;闸皮过度磨损,要及时更换。
3、电动自行车作用前应检查链条的松紧度。链条过紧脚蹬骑行时费力,过松则容易颤动、擦碰其他零部件。链条的垂度为1-2mm较适宜,一般不用脚蹬骑行时可以适当调紧。链条调整时,先松开后轮螺母,通过均匀旋进旋出左右调链螺钉,调整好链条松紧度,重新紧固好后轮螺母即可。
4、电动自行车使用前应检查链条的润滑情况。手感和观察链条的链轴转动是否灵活,链节锈蚀是否严重。如果锈蚀或转动不灵活,应加注适量润滑油,严重的应更换链条。
5、电动自行车骑行前,应检查轮胎气压、车把转向灵活性、前后轮转动灵活性、电路、蓄电池电量、电机工作状况以及灯光、喇叭、紧固件等是否满足使用要求。
(1)轮胎气压不足,将增加轮胎和路面的摩擦力,从而缩短续行里程;还会使车把转动灵活性降低,影响骑行的舒适性和安全性。气压不足时应及时补充气压,轮胎气压应按照《电动自行车使用说明书》中的推荐气压或轮胎表面上的规定气压。
(2)车把转动不灵活,有卡滞、僵点或紧点时,应及时润滑或调整。润滑一般使用黄油、钙基或锂基润滑脂;调整时,先松开前叉锁母,旋转前叉上挡,当车把转动灵活性达到要求后,锁紧前叉锁母即可。
(3)前后轮转动灵活性不好,将增加转动摩擦力,增加电量消耗,从而降低续行里程。因此,一旦出现故障应及时润滑和保养维修,润滑一般使用黄油、钙基或锂基润滑脂;如果是轴皮故障,可以更换钢珠或轴皮,如果是电机故障应到专业维修单位维修。
(4)电路检查时,打开电源开关,检查电路是否畅通,插接件是否插接牢固可靠、保险管工作是否正常,尤其是电池输出端子与电缆的连接是否牢固可靠。发现故障应及时排除。
(5)出行前,应检查蓄电池的电量,根据出行的里程判断蓄电池的电量是否充足。如果电量不充足,则应适当辅以人力骑行,避免蓄电池欠压工作。 (6)出行前还应当检查电机的工作状况。起动电机并调整其转速观察和听电机的运转,如有异常现象,应及时维修。
(7)电动自行车使用前应检查灯光、喇叭等,尤其是夜间出行。大灯应明亮,光束一般应落在车头前方5-10米的范围;喇叭声音应响亮,不嘶哑;转向灯应闪烁正常、转向指示正常,灯光的闪烁频率为75-80次/分钟;仪表显示应正常。
(8)出行前应检查各主要紧固件是否紧固,如把横管、把立管、鞍座、鞍管、前轮、后轮、中轴、锁母、脚蹬等的紧固件不应松动,如果出现紧固件松动或脱落,应及时紧固或更换。各紧固件的推荐力距一般为:把横管、把立管、鞍座、鞍管、前轮、脚蹬为18N.m,中轴锁母和后轮为30N.m。
6、电动自行车尽量不要使用零起动(即原地起动),尤其是在负重和上坡处更应禁止。起动时,应先用人力骑行,当达到一定的速度时再转为电动行驶,或直接使用电助动行驶。这是因为起动时,电机必须首先克服静摩擦力,此时电流较大,接近甚至达到阻转电流,使蓄电池大电流工作,加速蓄电池的损坏。
7、电动自行车骑行时尽量使用人力助动或电助动方式,尤其是上坡、负重、迎风行驶或路面坎坷不平时一定要人力骑行相助。这样,可以避免蓄电池较长时间大电流放电,损坏蓄电池,有利于提高一次充电的续行里程,延长蓄电池的使用寿命。
8、电动自行车不适应坎坷不平或坡度过陡(一般应≤8°)的道路。如遇此种道路,应缓慢驾驶或下车推行。在该种路面下行驶,电机、控制器、蓄电池等的工作环境差,将降低使用寿命并容易损坏。
9、电动自行车行驶时应避免频繁刹车和起动,刹车前或同时应将调速转把回位,在道路拥护的区域尽量使用人力骑行。这样,可以避免起动时大电流对蓄电池的损坏。
10、电动自行车的标准载重量为75公斤,应尽量避免超载。如果超载行驶,应使用人力骑行、人力助动方式。
11、寒冷天气使用电动自行车,应尽量人力助动或电助动行驶;并且还应当注意蓄电池的电量及电压指示,一般天气寒冷时,应适当降低蓄电池的放电深度,切不可欠压状态行驶。这是因为,天气寒冷时蓄电池的荷电能力、放电能力均有所降低。
12、电动自行车不怕雨雪天气。但是,涉积水时水位高度不能超过电动轮毂轴承座的下沿,以防止电机进水造成损坏。雨雪天骑行后,应尽快擦拭干净;如果电器件浸水,还应该用吹风机将其干燥。以免造成铁件腐蚀和电路漏电、短路等故障。
13、雨雪天骑行,行驶速度应适当降低,刹车注意增加制动距离,防止侧滑和掉头等,以免危及人身安全。
14、电动自行车应避免长时间日光曝晒,存放时应置于阴凉处。日光曝晒会加速油漆、塑料件、橡胶件和电子元件的老化,降低其使用寿命和可靠性。 15、蓄电池充电时应使用配套或厂家指定型号的充电器,不可混用;充电时,蓄电池和充电器应位于通风阴凉处,放置稳妥,应远离易燃易爆品,避免高温、潮湿和水淋,禁止用物品覆盖,禁止婴幼儿童接触。充电时应首先确认电网电压和频率符合充电器的要求,然后将电池与充电器输出端连接,充电器输入端与电网相连接;充电完成后,先断开电网连接再断开充电器与电池的连接。铅酸蓄电池充电一般需6-8小时。
16、蓄电池达到欠压状态应停止使用,并及早充电,禁止使用蓄电池的回升电压,禁止蓄电池深放电和过放电,最好随用随充,使其始终处于丰电状态。建议至少每天充电一次。
17、蓄电池存放时应放置在阴冷、空气湿度适中的地方,蓄电池应保持直立;长时间存放应先充足电并且应定期补充电量,一般每月充电一次。铅酸蓄电池长时间存放,可以加注几滴蒸馏水,以抵消水分蒸发,减轻极板的硫化。
18、初次使用电动自行车应仔细阅读《使用说明书》,了解电动自行车的性能。不要借给不会操纵电动自行车的人骑行。
19、精神病患者、酗酒者和其他不适宜骑行的残疾人禁止使用电动自行车;心脏病、癫痫患者以及色盲者等骑行时应谨慎。
20、电动自行车属非机动车,骑行时应遵守交通规则,在非机动车道或当地规定车道上行驶。
21、电动自行车应存放在阴凉、通风、干燥、远离腐蚀性液体和气体的地方;存放时要将整车直立,轮胎气压充足;车体上不可加载重物;并且蓄电池应分开存放。

]]>
Mon,02 Jun 2008 17:10:40 CST 0
<![CDATA[T-SQL存储过程 原理]]> .html T-SQL存储过程 原理

 

 

 

T-SQL存储过程
 1 存储过程的概念
 ● 存储过程是存放在服务器上的预先定义与编译好的SQL语句的命名集合,是一个独立的数据库对象。
 ● 存储过程在第一次执行时进行语法检查和编译。编译好的版本存储在过程高速缓存中用于后续调用,执行速度快。
 ● 存储过程由应用程序激活,而不是由系统自动执行。
 ● 存储过程可以由应用程序多次激活,提高重复任务的执行性能。
 ● 存储过程可以接受输入参数和返回值。
  存储过程的创建和处理过程如图4-27。
  创建后先进行语法分析,语法正确的存储过程存入到系统表sysobjects和syscomments中。第一次执行时先进行优化和编译,编译后的执行计划放在过程高速缓存中,以备后续过程调用。所以,存储过程在第一次执行以后,通常不再需要进行语法分析、优化和编译,以后的过程调用只须把查询计划从高速缓存中调出执行即可。

  图4-27 存储过程的处理流程


  综合存储过程特点如下:(1) 存储过程作为一个程序逻辑处理单元,使多个应用程序可以共享应用程序的处理逻辑单元,所有的客户机程序可以使用同一个存储过程进行各种操作,从而确保数据访问和操作的一致性,也提高了应用程序的可维护性。
 (2) 由于存储过程在第一次执行之后,就驻存在高速缓存存储器中,因此可以提高系统的执行效率。
 (3) 存储过程提供了一种安全机制。如果用户被授予执行存储过程的权限,那么既使该用户没有执行访问在该存储过程中所参考的表或者视图的权限,该用户也可以完全执行该存储过程。
 (4) 减少了网络的流量负载。由于存储过程是存放在服务器端的,因此客户端要执行存储过程时,只需要传送一条命令即可,如果不使用存储过程,则需要传送许多条SQL语句。
 (5) 因为存储过程提供该前端应用程序共享的处理逻辑,若要改变业务规则或策略,只需改变存储过程和参数,不用修改应用程序。

 

       在大型数据库系统中,存储过程和触发器具有很重要的作用。无论是存储过程还是触发器,都是SQL 语句和流程控制语句的集合。就本质而言,触发器也是一种存储过程。存储过程在运算时生成执行方式,所以,以后对其再运行时其执行速度很快。SQL Server 2000 不仅提供了用户自定义存储过程的功能,而且也提供了许多可作为工具使用的系统存储过程。

        存储过程的概念
存储过程(Stored Procedure)是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

        在SQL Server 的系列版本中存储过程分为两类:系统提供的存储过程和用户自定义存储过程。系统过程主要存储在master 数据库中并以sp_为前缀,并且系统存储过程主要是从系统表中获取信息,从而为系统管理员管理SQL Server 提供支持。通过系统存储过程,MS SQL Server 中的许多管理性或信息性的活动(如了解数据库对象、数据库信息)都可以被顺利有效地完成。尽管这些系统存储过程被放在master 数据库中,但是仍可以在其它数据库中对其进行调用,在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时,一些系统存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建并能完成某一特定功能(如查询用户所需数据信息)的存储过程。在本章中所涉及到的存储过程主要是指用户自定义存储过程。

         存储过程的优点
    当利用MS SQL Server 创建一个应用程序时,Transaction-SQL 是一种主要的编程语言。若运用Transaction-SQL 来进行编程,有两种方法。其一是,在本地存储Transaction- SQL 程序,并创建应用程序向SQL Server 发送命令来对结果进行处理。其二是,可以把部分用Transaction-SQL 编写的程序作为存储过程存储在SQL Server 中,并创建应用程序来调用存储过程,对数据结果进行处理存储过程能够通过接收参数向调用者返回结果集,结果集的格式由调用者确定;返回状态值给调用者,指明调用是成功或是失败;包括针对数据库的操作语句,并且可以在一个存储过程中调用另一存储过程。

    我们通常更偏爱于使用第二种方法,即在SQL Server 中使用存储过程而不是在客户计算机上调用Transaction-SQL 编写的一段程序,原因在于存储过程具有以下优点:

(1)   存储过程允许标准组件式编程
存储过程在被创建以后可以在程序中被多次调用,而不必重新编写该存储过程的SQL 语句。而且数据库专业人员可随时对存储过程进行修改,但对应用程序源代码毫无影响(因为应用程序源代码只包含存储过程的调用语句),从而极大地提高了程序的可移植性。

(2) 存储过程能够实现较快的执行速度
如果某一操作包含大量的Transaction-SQL 代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的执行计划。而批处理的Transaction- SQL 语句在每次运行时都要进行编译和优化,因此速度相对要慢一些。

(3) 存储过程能够减少网络流量
对于同一个针对数据数据库对象的操作(如查询、修改),如果这一操作所涉及到的 Transaction-SQL 语句被组织成一存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,否则将是多条SQL 语句,从而大大增加了网络流量,降低网络负载。

(4) 存储过程可被作为一种安全机制来充分利用
系统管理员通过对执行某一存储过程的权限进行限制,从而能够实现对相应的数据访问权限的限制,避免非授权用户对数据的访问,保证数据的安全。(我们将在14 章“SQLServer 的用户和安全性管理”中对存储过程的这一应用作更为清晰的介绍)

注意:存储过程虽然既有参数又有返回值,但是它与函数不同。存储过程的返回值只是指明执行是否成功,并且它不能像函数那样被直接调用,也就是在调用存储过程时,在存储过程名字前一定要有EXEC保留字

]]>
Wed,28 May 2008 17:34:03 CST 0
<![CDATA[中国软件行业最应强大的方向,国产操作系统]]> .html 中国软件行业最应强大的方向,国产操作系统

 

       中国程序员心中的刺,国产操作系统。“我们什么时候才能有自己的操作系统和CPU?”这是每一个计算机人心中的疑问和希望。其实我们早就已经有一个基于LINUX的国产操作系统红旗了。真希望自己也可以去为中国的操作系统出一份力.

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

http://www.csdn.net/subject/ChinaOS/ok/index.htm

 

无芯无魂,已经成了制约我国IT产业发展的瓶颈。于是,汉芯、麒鳞一度成为了人们的希望。然而,当我们确切地看到其中的技术创新成分时,却又忍不住一次又一次地失望。但越是如此,具备技术创新的国产操作系统,就越可能成为国人心中的渴望。

 


   
 

事变缘起

        麒麟操作系统是由国防科技大学、中软公司、联想公司、浪潮公司和民族恒星公司五家单位合作研制的服务器操作系统。按照麒麟官方的说法:“Kylin服务器操作系统是国家863计划的重大研究成果,拥有完全自主版权的内核,与Linux在应用上二进制兼容,并支持64位,是中国独立研发成功的、具有完全自主知识产权的服务器操作系统。”然而,DanceFire的一篇文章却在提醒我们:麒麟操作系统内核与FreeBSD5.3内核的相似性达到了99.45%。

       麒麟操作系统内核与FreeBSD5.3内核的相似性达到了99.45%         银河麒麟操作系统官方公告

        麒麟操作系统涉嫌抄袭 自主研发说法遭质疑

       近年来,中国在国际经济政治舞台上的迅速崛起引起了西方国家的高度重视,一股由天然担忧、意识形态偏见及“中国威胁论”交织而成的,在知识技术上压制中国的做法,已经成为一堵阻碍中国国力再上台阶的厚墙。不止一家西方媒体提出,西方只有在创新方面继续领先才能有效应对中国的崛起。中国专家同样认为,突破西方技术压制的唯一方法就是自主创新,能否创新将决定中国的未来。

         西方禁运清单接踵而至 我多项技术被指"剽窃"            我们离创新型国家有多远?           

         中国的LAMP普及程度处于世界最低水平               政府采购:国产软件发展的第一推动力

         一台PC装两套操作系统 国产软件遭变相束之高阁

        


   
 

众议国产操作系统

 

       我认为不应该过分的强调国产,相反,为了促进中国软件人才力量的积蓄,更应该强调在开源社区中,中国程序员所占的比重。其实很多核心软件,我们国家还没有那么多技术力量,过分的强调国产,反而是一种闭门造车的行为。浪费了时间和人力去重复别人几十年前的工作。         DanceFire:要融入全球社区开发的大环境中

        目前的国内企业使用开源软件还是比较多的,但是仅限于使用,对功能进行一些简单的扩展,或者仅改头换面就包装上市了。这样的“拿来主义”短期内可以促进国内企业产品的繁荣,但并不能代表创新力的提高,这样的行为长期来说和吸食鸦片没有什么区别。     Zhlqcn:开源与创新

        FreeBSD源代码,可以随意使用,只要注明其版权信息即可。这就是说,代码随你用,权力我保留。在麒麟操作系统的源代码里面,有部分FreeBSD的源代码,有什么不好?这说明麒麟的出身更加“出自名门”、更加“无比高贵”。

                袁盟:麒麟与红旗

        中国人需不需要搞自己的操作系统?在我看来,这个问题根本就不成为一个问题。在“中国人有没有这个技术能力”“搞出来的东西有没有市场”这些方面当然有很多可以讨论的地方,但在“需不需要有自己的操作系统”这个问题上,毫无争论的余地。有无数无可辩驳的理由,需要我们拥有自己的操作系统。      左轻侯:国产操作系统的可行性分析

 


   
 

相关资料汇总

 

       可能相当一部分人知道Linux,甚至知道Linux和Windows的纷争。但是提到国内制作的操作系统时恐怕就知之甚少了。能提起名字的,恐怕只有中科院的红旗、国防科技大学的银河麒麟。但是,国人制作的操作系统就只有这么几个商业化的或者科研计划的操作系统么? 其实远不是这样。在民间,已经有大量的操作系统人才在积蓄着自己的力量,已经有优秀的作品发布了出来。

        国产操作系统从头数

        开源运动同样有自己的游戏规则和道德准则。不遵行这些规则不但损害开源运动的健康发展,也会对违规者造成名誉和市场上的损失,更可能陷入法律纠纷和赔偿。 经常用的一些开源协议的详细解析

        自己动手写操作系统

 

 

 

 

]]>
Wed,28 May 2008 17:22:19 CST 0
<![CDATA[Informix 7.31 For SCO 5安装脚本]]> .html INFORMIXDIR=/usr/informix
export INFORMIXDIR

echo "INPUT YOUR FREE DIVISIONS: (exp: d10???)"
read MYDEVICE
cd /dev
ls $MYDEVICE > $INFORMIXDIR/mydb.txt

cd $INFORMIXDIR
dbline=`wc -l mydb.txt|awk '{print $1}'`
if [ $dbline -lt 3 ]
then 
echo "DEVICE NOT ENOUGH!!! AT LEAST 3 * 2G"
exit
fi 

cd $INFORMIXDIR
ROOTDEVICE1=`cat mydb.txt|awk 'NR==1 {print $0}'`
ROOTDEVICE2=`cat mydb.txt|awk 'NR==2 {print $0}'`
ROOTDEVICE3=`cat mydb.txt|awk 'NR==3 {print $0}'`
echo $ROOTDEVICE1
echo $ROOTDEVICE2
echo $ROOTDEVICE3


MYHOST=`hostname`
MYSERVER=$MYHOST
MYCONFIG=onconfig.$MYHOST
MYPORT=8888


SOURCE=/tmp               #°&sup2;&#1520;&#1332;&#319;&frac14;


cd $INFORMIXDIR

tar xvf $SOURCE/SQL.TAR
./installsql <<!

AAC#J704041
YRRCJU

!

cpio -icvdBum < $SOURCE/ESQL.CPI
./installesql <<!

AAC#J334485
RVJAJS

!

tar xvf $SOURCE/4GL.TAR
./install4gl <<!

AAC#J704038
BBNUJB

!


cpio -icvdBum < $SOURCE/IDS.CPI
./installserver <<!

AAC#J704034
KOREJH

!

cd /usr/informix 
echo "INFORMIXDIR=/usr/informix" > .profile
echo "INFORMIXSERVER=${MYSERVER}_shm" >> .profile
echo "ONCONFIG=$MYCONFIG" >> .profile
echo "PATH=$PATH:$INFORMIXDIR/bin:.                  # set command search path" >> .profile
echo "MAIL=/usr/spool/mail/`logname`          # mailbox location" >> .profile
echo "export PATH MAIL INFORMIXDIR INFORMIXSERVER ONCONFIG" >> .profile


echo "${MYSERVER}_shm      onipcshm        `hostname`  ${MYSERVER}_shm" >$INFORMIXDIR/etc/sqlhosts
echo "${MYSERVER}_tcp      ontlitcp        `hostname`  ${MYSERVER}_tcp" >>$INFORMIXDIR/etc/sqlhosts

cp /etc/services /etc/services.bak
grep -v ${MYSERVER}_tcp /etc/services.bak > /etc/services
echo "${MYSERVER}_tcp ${MYPORT}/tcp" >> /etc/services

########write ONCONFIG FILES#########

cp $INFORMIXDIR/etc/onconfig.std $INFORMIXDIR/etc/${MYCONFIG}

chown informix:informix $INFORMIXDIR/etc/$MYCONFIG

cd $INFORMIXDIR/etc/


cat ${MYCONFIG}|awk -v dev1="/dev/"${ROOTDEVICE1} '$1=="ROOTPATH" {$2=dev1} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="ROOTSIZE" {$2="50000"}  {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LOGFILES" {$2="3"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="TAPEDEV" {$2="/dev/null"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LOGSMAX" {$2="20"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LTAPEDEV" {$2="/dev/null"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LOCKS" {$2="500000"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="BUFFERS" {$2="400000"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="TAPEBLK" {$2="128"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk  -v server=${MYSERVER}"_shm" '$1=="DBSERVERNAME" {print $1 " " server} !($1=="DBSERVERNAME"){print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk  -v server=${MYSERVER}"_tcp" '$1=="DBSERVERALIASES" {print $1 " " server} !($1=="DBSERVERALIASES"){print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk  '$1=="DBSPACETEMP" {print $1 " rootdbs"} !($1=="DBSPACETEMP"){print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LRU_MAX_DIRTY" {$2="20"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="LRU_MIN_DIRTY" {$2="15"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}
cat ${MYCONFIG}|awk '$1=="CKPTINTVL" {$2="5000"} {print $0}' > /tmp/onconfig.tmp
cp /tmp/onconfig.tmp $INFORMIXDIR/etc/${MYCONFIG}


####END ONCONFIG#########


#######ONINIT#########
cd $INFORMIXDIR
. ./.profile
oninit -iy
sleep 10
#######ONINIT#########

onspaces -c -d tmpdbs -t -p /dev/$ROOTDEVICE1 -o 50002 -s 945000
onspaces -c -d phydbs -p /dev/$ROOTDEVICE1 -o 1000000 -s 1000000
onspaces -c -d logdbs -p /dev/$ROOTDEVICE2 -o 0 -s 2000000
onspaces -c -d workdbs -p /dev/$ROOTDEVICE3 -o 0 -s 2000000


onmode -s -y
sleep 3
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000
onparams -a -d logdbs -s 100000

]]>
Tue,27 May 2008 16:46:22 CST 0
<![CDATA[Informix存储过程 详解]]> .html Informix存储过程 详解


一、存储过程概述
 

存储过程是一个用户定义的函数,由存储过程语句(SPL) 和一组SQL语句组成,以可以执行代码形式存储在数据库中,和表、视图、索引等一样

,是数据库的一种对象。

存储过程语言SPL(Stored Procedure Language),只能用在存储过程中,可以分成下面几类:
 
1、变量定义和赋值:define,let
 
2、流程控制:
分支控制:
if  then
elif
else
end if;

循环控制:
FOR,FOREACH,WHILE,EXIT, CONTINUE
 
3、函数调用与返回
CALL, SYSTEM ,RETURN
 
4、错误处理和调试
TRACE, ON EXCEPTION, RAISE EXCEPTION
 

例子:
drop procedure count_add;--删除存储过程
create procedure count_add(user_name_var varchar(50) default 'administrator')
--user_name_var传递参数变量在此定义
returning varchar(50);
--返回一个字符型的值
define error_count_var integer;
----定义输入的次数变量
select error_count into error_count_var from users where user_name=user_name_var;
----error_count默认是0,从0开始记数
let error_count_var=error_count_var 1;
----输入一次记数加1
update users set error_count= error_count_var where user_name =user_name_var
return user_name_var;
--返回变量值,与returning对应。
return user_name_var WITH  RESUME;
----将保证存储过程继续执行,所有的变量均保持原有的值
end procedure
document ‘this is a error count procedure’
with listing in ’/export/home/xie/errorcount.txt‘;
 

将该脚本保存为count_add.sql,在unix系统下,执行如下命令建立存储过程:
$dbaccess db1 count_add.sql
 
存储过程建立在数据库db1中,执行存储过程可以通过dbaccess工具
$dbaccess db1
 
然后进入执行状态
execute procedure count_add('administrator');
execute procedure db@servername:count_add('administrator');
 
 
 
与存储过程相关系统表
SYSPROCEDURES:记录数据库的所有存储过程
SYSPROCBODY:记录存储过程文本
SYSPROCPLAN:记录存储过程执行的查询规划
SYSPROCAUTH:记录授予存储过程的权限
 

查看存储过程代码、导出存储过程
$dbschema -d dbname -f procedurename -ss
 
例如:
xxxdb% dbschema -d xxdb -f pro1231
DBSCHEMA Schema Utility       INFORMIX-SQL Version 9.40.FC7   
Copyright IBM Corporation 1996, 2004 All rights reserved
Software Serial Number AAA#B000000
 

create procedure "xxxuser".pro1231()
returning int;
return 2007;
end procedure
document "this is a test"
;

 
 
$dbschema -d dbname -f procedurename proc.sql
 
从系统表中查看
select data
from sysprocedures, sysprocbody
where datakey ="T"
and sysprocedures.procname = "pro1231"
and sysprocedures.procid =
sysprocbody.procid;
 

结果显示
data
create procedure pro1231()
returning int;
return 2007;
end procedure
document "this is a test"

 

 

二、创建存储过程
 
语法:

CREATE [DBA] PROCEDURE 过程名(参数[, 参数 [ ,...]]  )
                   RETURNING 子句
                        语句块
                  END   PROCEDURE
                  document  子句
                  WITH   LISTING   IN 文件名

过程名说明创建的存储过程的名字
参数说明调用该存储过程所需的参数个数和类型
一个存储过程可以不返回任何值,或返回一个或多个值,也可返回多组值。
返回多组值的存储过程称之为游标式存储过程,对该类存储过程,相应调用函数需作一些特殊处理。
 

例子:
假设建立一个脚本名为proc1231.sql的文件,内容如下:
 
create procedure proc1231()
returning int;
return 2007;
end procedure
--end procedure后面不能加分号(;),否则会报语法错误
document
'this is a new procedure'
--这里也不能加分号(;),ducoment子句需加双引号或单引号。
with listing in '/export/home/user/pro.log';
--最后可以加分号(;),也可以不加
 
 
存储过程中的语句块由SPL语句和SQL语句组成,但不包含下面的SQL语句

CREATE DATABASE
DATEBASE
CLOSE DATEBASE
CHECK TABLE
REPAIR   INFO   OUTPUT   LOAD   UNLOAD
CREATE PROCEDURE
CREATE PROCEDURE FROM
 
document子句对存储过程做一些说明,可省略。
WITH LISTING IN 选项说明接受编译器输出信息的文件名,如省略, 则编译器不产生输出。
 

向存储过程中传递变量
create procedure procname(var_num integer default null)
delete from proctable where colno=var_num;
end procedure;

execute procedure procname(11);
 
 

return语句
从存储过程中返回0个或多个值
RETURN 语句说明的返回值的个数和类型必须与创建存储过程时说明的返回值的个数和类型一致,或者不返回任何值,在后一情形下,所有的返

回值为空值。
WITH  RESUME子句将保证存储过程继续执行,所有的变量均保持原有的值。该子句用于返回多组值,比如循环语句中。
 
create procedure proc_new()
returning int,int;
define num1;
define num2;
.....
....
return num1,num2;
end procedure;
 
 

从SQL中调用存储过程
select * from users
where number=proc_new(23);
 
 

call语句
 
从一个存储过程中调用另一个存储过程
 
两种格式:
CALL 过程名(参数, ...) RETURNING 变量,...;
CALL 过程名(参数名=参数, ...) RETURNING 变量,...;
 
 
说明:
参数可以是SPL表达式或是SELECT语句,只要该语句返回单值,并且具有适当的类型和长度。
如果参数个数多于被调用的存储过程的参数,则返回错误。
如果参数个数少于被调用的存储过程的参数,则未说明的参数被初始化为其缺省值(该值在创建存储过程时说明)若无缺省值, 则返回错误。
RETURNING 子句说明的变量用于接收被调用存储过程的返回值,如无返回值, 则可省略。
 
 
例如:
define var_no1 int;


三、存储过程语言
 
变量

局部变量
仅在本存储过程中有效的变量。 局部变量不允许有缺省值
全局变量
在同一用户活动期间, 存储过程中的可被同一数据库的其它存储过程访问的的变量。全局变量必须在所有使用的存储过程中定义,并且必须给

出缺省值,实际的缺省值是第一次被访问时定义的缺省值。
 

变量(局部变量)的范围
变量在语句块内有效, 如语句块嵌套,则同名的内层定义覆盖其外层定义, 内层语句执行完后,外层定义重新有效。

存储过程表达式
存储过程表达式可以是除聚集函数表达式外的任何SQL算术表达式
例子: var_value1; var_value1 var_value2;

变量定义
用DEFINE 语句定义变量,其类型可以是除SERIAL数据类型外 的所有SQL 数据类型
定义TEXT 或BYTE 类型变量时, 需在其变量前加关键字REFERENCES, 以表明该变量并不含有真正的数据, 而只是指向数据的指针。
可以使用LIKE定义与字段类型一致的数据类型
传入参数变量的定义在create procedure procname(var_value int)定义
 

例子:
DEFINE i,j INT;
DEFINE name VARCHAR(12);
DEFINE time_stamp DATETIME YEAR TO SECOND DEFAULT CURRENT YEAR TO SCECOND;
DEFINE date_value DATE;
DEFINE txt REFERENCES TEXT;
DEFINE by REFERENCES BYTE;
DEFINE p_customer like users.customer_num;
 
 

定义全局变量
define global global_var int default 0;
 
 
局部BLOB数据类型
只使用描述符:
LET
DEFINE
CALL
SELECT
存取BLOB数据:
INSERT
UPDATE
RETURN(到前端应用程序)
 
 
 
 
变量赋值 四种方式
1、利用LET 语句
LET i, j=1, 0;
LET var_name, var_num=(SELECT username, usernum FROM users WHERE usernum=100);

2、利用SELECT 或SELECT ... INTO 语句
SELECT username INTO var_name FROM users WHERE usernum=100;

3、利用CALL 语句
call proc_new(22)  returning var_no1;

4、利用EXECUTE PROCEDURE ...INTO 语句
execute procedure proc_name(username,address into p_name,p_addr);
 
 

语句块
create procedure pro_test()
returning int;
    begin
   
    define i int;
    let i=1;
    end
--begin,end 语句块(显示)
retrun i;
--returning,return语句块(隐含)
end procedure;
 
 
 

foreach循环
 
create procedure pro_foreach()
define id int;
select userid into id from users where age>30;
--select语句返回大于1的行,可以理解为将select到的值放在id这个列表中一个一个执行。
update others set uservalue=345 where userid=id;
end foreach;
end procedure;
 
 

使用update游标
条件分支
if then
elif then
else
end if
 
 

--------------------------------------------------
drop procedure pro_dele;
create procedure pro_dele()
define p_time date;
begin work;
foreach curl for
--update游标必须命名
select time_stamp into p_time from pro_dele_tbl
where num > 100
if p_time is not null then
delete from pro_del_tbl where current of curl;
--删除当前记录
end if;
end foreach;
commit work;
--所有修改记录的锁被释放。
end procedure;
--------------------------------------------------
 
 
 
 
if语句中的表达式

If exists(select username from users
   where usernum = 13) then
 …
end if
if var_num > all(select usernum from users
    where usernum = 23) then
 …
end if
if var_name matches “A*” then
 …
end if
 
 
 
 
 
循环语句while
 
格式: WHILE 条件语句    语句块   END WHILE

执行过程
先测试条件,若为真,则执行语句块,否则退出循环。
重复上述步骤,开始下一次循环,直到条件为假而退出循环

 

 

WHERE 与FOREACH 的区别

 


WHILE 循环的条件是不定的,循环次数不定,因而可能出现无穷循环
FOR和FOREACH 循环的条件是确定的,循环次数也是明确的,不可能出现无穷循环

例子
create procedure prowhile()
define i int;
define sum int;
let i=1;
let sum=0;
while i<100
let sum=sum i;
let i=i 1;
end while;
end procedure;
 
 
 

循环语句for
 
三种格式
FOR 变量 IN (expr1 to expr2 STEP expr3)  语句块   END FOR
--expr1,expr2表示范围,expr3表示步长,默认为1
for i=1 to 10 step 2
...
end for;

FOR 变量 = (expr1 to expr2 STEP expr3)  语句块   END FOR
--expr1,expr2表示范围,expr3表示步长,默认为1

FOR 变量 IN (expr1, expr2,...)  语句块   END FOR
for i in (1,2,3,4,5,7,8)
...
end for;
 
循环的转移
for i = 1 to 10
 if i = 5 then
  continue for;
----------------contiune将执行下一次循环
 elif i = 8 then
  exit for;
----------------exit for将退出循环,执行for循环的下一条语句
 end if;
end for;
 
 
 
 
 
循环语句foreach
 
 

用 FOREACH 语句可以查询或操作一组记录
FOREACH 隐式定义并打开一个游标
 

三种格式
FOREACH [WITH HOLD] SELECT ... INTO 语句
        语句块
END FOREACH;
-FOREACH 游标名[WITH HOLD] FOR SELECT ... INTO 语句
        语句块
END FOREACH;
FOREACH EXECUTE PROCEDURE 存储过程名(参数...参数)
     INTO 变量[, 变量[, ...]]    语句块
END FOREACH;
FOREACH 定义的游标在以下情况下关闭:

无行返回
事务提交或回滚导致非保护游标关闭
循环非正常退出(使用EXIT 或 ON EXCEPTION)
 
 
 
 
操作系统命令

system "echo" "Delete Operation Completed" "|mail judy";

数据库系统一直等到上述命令执行完毕
不能使用返回值判断执行是否成功
如执行不成功,将设置适当的ISAM错误代码和SQL错误代码
 
 
 
检查NOTFOUND条件
create procedure protest()
define num integer;
returning integer;
foreach select usernum into num from users
where usernum=20
--select执行失败将不执行foreach中的语句。
return num;
end foreach;
return;
--return没有返回值将在前端应用中引发NOTFOUND
end procedure;
 
 
 
 

递归调用

create procedure digui(i int defualt 1)
 returning int;
 if i <6 then
  return 1;
 end if;
 return n * digui(n-2);
--调用自己
end procedure;
 
 
 

获取serial值

create procedure seri_inst()
 define seri int;
 insert into users
  (user_num,user_date)
  values (1,"2006-01-03");
 let seri = dbinfo("sqlca.sqlerrd1");
--获取上一条insert语句中的serial值
 insert into other(num,name)
  values(seri,"new");
end procedure;
 
 
 
 
 
获取处理的记录数
 
create procedure num_rows()
 returning int;
 define num_rows int;
 delete from orders where customer_num = 104;
 let num_rows = dbinfo("sqlca.sqlerrd2");
--select、update或update的记录数
 return num_rows;
end procedure;
 
 
 
 

跟踪调试语句trace

存储过程被正确创建后,说明无语法错误,但有可能有逻辑错误
TRACE语句用于调试存储过程, 它可以跟踪以下存储过程实体的值:
变量(Variables)
过程参数(Procedure arguments)
返回值(Return values)
SQL 错误代码(SQL error codes)
ISAM 错误代码(ISAM error codes)
TRACE 语句把跟踪结果写到一个文件中, 该文件由SQL语句SET DEBUG FILE指定
 
 
 
 

TRACE 语句的三种形式:
TRACE ON :打开跟踪调试, 跟踪所有语句
TRACE OFF :关闭跟踪调试
TRACE PROCEDURE: 对于过程调用, 不跟踪过程体,仅跟踪过程的输入和返回值。
 
 
 
 
create procedure tracepro(var_user_num int)
 define var_user_date date;
 set debug file to "/export/home/user/trace";
--设置输出文件
 trace on;
--跟踪所有执行的语句
 select user_date into var_user_date
  from users
  where user_num = var_user_num;
 if var_user_date is null then
  trace "user date is null";
--执行到这里输出user date is null
  execute procedure other((var_user_num );
 end if;
 trace off;
--关闭跟踪
end procedure;


四 存储过程中的异常处理
 

没有异常处理
 
create procedure yichang ()
 returning int;
 define var_num integer;
 let  var_num = "jack";
--------存储过程到这将会出错
        return var_num;
end procedure;
 
 
 
 
异常处理
 
create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
 end exception;
end procedure;
 
 
 

异常捕获:ON EXCEPTION
 
 
用ON EXCEPTION语句捕获一个或一组特定的异常(即错误),用错误号标识。
ON EXCEPTION 语句与RAISE EXCEPTION 语句一起提供存储过程语言(SPL)的错误 捕获和恢复机制。
在一个语句块内可以定义多个 ON EXCEPTION 语句。
被捕获的异常可以是系统异常或用户定义的异常。
一旦异常被捕获,错误状态即被清除。
 
 

ON EXCEPTION 语句的位置:
ON EXCEPTION 语句是一声明性而非执行性语句, 故应位于任何执行语句之前,  而位于DEFINE 语句之后。
 
 
 
 
格式

           ON EXCEPTION IN (错误号,...)
           SET SQL 错误变量 ISAM 错误文本变量   语句块
           END EXCEPTION [WITH RESUME]
 

IN 子句说明欲捕获的错误号, 缺省时捕获所有的错误号。
SET 子句接收错误号和错误文本的变量,该语句可省略。
SQL 错误变量:  说明接收SQL 错误号的变量
ISAM错误变量: 说明接收ISAM错误号的变量
错误文本变量:   说明接收与SQL错误号对应的错误文本的变量
WITH RESUME 关键字用于把控制转向到捕获的错误被处理后的紧接发生异常语句后的语句,其效果相当于异常被处理后程序继续执行下去。 
WITH RESUME 可以省略。
 
 
 

捕捉特定的错误
 
create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
 end exception;
-----其他错误的捕捉
        on exception (-206)
  call new_tab();
 end exception;
-----表不在数据库中的错误在这里捕捉
end procedure;
 
 
 

异常处理后继续执行
 
        on exception (-206)
  call new_tab();
 end exception with resume;
        select new froom tab;
--出错将继续执行
        let nex=9;
 
 

WITH RESUME将继续
执行出错行后面的语句

如果没有WITH  RESUME将继续执行下一次循环或下一个语句块,如果有的话。如果没有语句块,则过程将结束。
 
 
 

异常捕获:RAISE EXCEPTION

用RAISE EXECPTION 语句模拟异常的产生,该异常可被ON EXECTPION语句捕获。
格式:
      RAISE EXCEPTION SQL 错误号, ISAM 错误号, 错误文本变量
SQL错误号和ISAM错误号均可是SPL表达式,且其计算结果是一个常数(错误号)
例子:
RAISE EXCEPTION -99999, 0, --Broke the Rule
 
 
 

create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
                raise exception sql_err, isam_err, error_info;
----------------RAISE EXCEPTION引发一个人工的错误信息
 end exception;
end procedure;
 
 
 
 

存储过程的权限    两类存储过程
DBA 权限的存储过程
所有者权限的存储过程
 
下列用户可以创建存储过程
具有RESOURCE 权限的用户可以创建存储过程

 

 

下列用户可以执行存储过程
DBA 用户
存储过程的创建者
具有EXECUTE 权限的用户

 

 

 

 

 

 

 

 

 

]]>
Tue,27 May 2008 16:43:47 CST 0
<![CDATA[Informix存储过程 详解]]> .html Informix存储过程 详解


一、存储过程概述
 

存储过程是一个用户定义的函数,由存储过程语句(SPL) 和一组SQL语句组成,以可以执行代码形式存储在数据库中,和表、视图、索引等一样

,是数据库的一种对象。

存储过程语言SPL(Stored Procedure Language),只能用在存储过程中,可以分成下面几类:
 
1、变量定义和赋值:define,let
 
2、流程控制:
分支控制:
if  then
elif
else
end if;

循环控制:
FOR,FOREACH,WHILE,EXIT, CONTINUE
 
3、函数调用与返回
CALL, SYSTEM ,RETURN
 
4、错误处理和调试
TRACE, ON EXCEPTION, RAISE EXCEPTION
 

例子:
drop procedure count_add;--删除存储过程
create procedure count_add(user_name_var varchar(50) default 'administrator')
--user_name_var传递参数变量在此定义
returning varchar(50);
--返回一个字符型的值
define error_count_var integer;
----定义输入的次数变量
select error_count into error_count_var from users where user_name=user_name_var;
----error_count默认是0,从0开始记数
let error_count_var=error_count_var 1;
----输入一次记数加1
update users set error_count= error_count_var where user_name =user_name_var
return user_name_var;
--返回变量值,与returning对应。
return user_name_var WITH  RESUME;
----将保证存储过程继续执行,所有的变量均保持原有的值
end procedure
document ‘this is a error count procedure’
with listing in ’/export/home/xie/errorcount.txt‘;
 

将该脚本保存为count_add.sql,在unix系统下,执行如下命令建立存储过程:
$dbaccess db1 count_add.sql
 
存储过程建立在数据库db1中,执行存储过程可以通过dbaccess工具
$dbaccess db1
 
然后进入执行状态
execute procedure count_add('administrator');
execute procedure db@servername:count_add('administrator');
 
 
 
与存储过程相关系统表
SYSPROCEDURES:记录数据库的所有存储过程
SYSPROCBODY:记录存储过程文本
SYSPROCPLAN:记录存储过程执行的查询规划
SYSPROCAUTH:记录授予存储过程的权限
 

查看存储过程代码、导出存储过程
$dbschema -d dbname -f procedurename -ss
 
例如:
xxxdb% dbschema -d xxdb -f pro1231
DBSCHEMA Schema Utility       INFORMIX-SQL Version 9.40.FC7   
Copyright IBM Corporation 1996, 2004 All rights reserved
Software Serial Number AAA#B000000
 

create procedure "xxxuser".pro1231()
returning int;
return 2007;
end procedure
document "this is a test"
;

 
 
$dbschema -d dbname -f procedurename proc.sql
 
从系统表中查看
select data
from sysprocedures, sysprocbody
where datakey ="T"
and sysprocedures.procname = "pro1231"
and sysprocedures.procid =
sysprocbody.procid;
 

结果显示
data
create procedure pro1231()
returning int;
return 2007;
end procedure
document "this is a test"

 

 

二、创建存储过程
 
语法:

CREATE [DBA] PROCEDURE 过程名(参数[, 参数 [ ,...]]  )
                   RETURNING 子句
                        语句块
                  END   PROCEDURE
                  document  子句
                  WITH   LISTING   IN 文件名

过程名说明创建的存储过程的名字
参数说明调用该存储过程所需的参数个数和类型
一个存储过程可以不返回任何值,或返回一个或多个值,也可返回多组值。
返回多组值的存储过程称之为游标式存储过程,对该类存储过程,相应调用函数需作一些特殊处理。
 

例子:
假设建立一个脚本名为proc1231.sql的文件,内容如下:
 
create procedure proc1231()
returning int;
return 2007;
end procedure
--end procedure后面不能加分号(;),否则会报语法错误
document
'this is a new procedure'
--这里也不能加分号(;),ducoment子句需加双引号或单引号。
with listing in '/export/home/user/pro.log';
--最后可以加分号(;),也可以不加
 
 
存储过程中的语句块由SPL语句和SQL语句组成,但不包含下面的SQL语句

CREATE DATABASE
DATEBASE
CLOSE DATEBASE
CHECK TABLE
REPAIR   INFO   OUTPUT   LOAD   UNLOAD
CREATE PROCEDURE
CREATE PROCEDURE FROM
 
document子句对存储过程做一些说明,可省略。
WITH LISTING IN 选项说明接受编译器输出信息的文件名,如省略, 则编译器不产生输出。
 

向存储过程中传递变量
create procedure procname(var_num integer default null)
delete from proctable where colno=var_num;
end procedure;

execute procedure procname(11);
 
 

return语句
从存储过程中返回0个或多个值
RETURN 语句说明的返回值的个数和类型必须与创建存储过程时说明的返回值的个数和类型一致,或者不返回任何值,在后一情形下,所有的返

回值为空值。
WITH  RESUME子句将保证存储过程继续执行,所有的变量均保持原有的值。该子句用于返回多组值,比如循环语句中。
 
create procedure proc_new()
returning int,int;
define num1;
define num2;
.....
....
return num1,num2;
end procedure;
 
 

从SQL中调用存储过程
select * from users
where number=proc_new(23);
 
 

call语句
 
从一个存储过程中调用另一个存储过程
 
两种格式:
CALL 过程名(参数, ...) RETURNING 变量,...;
CALL 过程名(参数名=参数, ...) RETURNING 变量,...;
 
 
说明:
参数可以是SPL表达式或是SELECT语句,只要该语句返回单值,并且具有适当的类型和长度。
如果参数个数多于被调用的存储过程的参数,则返回错误。
如果参数个数少于被调用的存储过程的参数,则未说明的参数被初始化为其缺省值(该值在创建存储过程时说明)若无缺省值, 则返回错误。
RETURNING 子句说明的变量用于接收被调用存储过程的返回值,如无返回值, 则可省略。
 
 
例如:
define var_no1 int;


三、存储过程语言
 
变量

局部变量
仅在本存储过程中有效的变量。 局部变量不允许有缺省值
全局变量
在同一用户活动期间, 存储过程中的可被同一数据库的其它存储过程访问的的变量。全局变量必须在所有使用的存储过程中定义,并且必须给

出缺省值,实际的缺省值是第一次被访问时定义的缺省值。
 

变量(局部变量)的范围
变量在语句块内有效, 如语句块嵌套,则同名的内层定义覆盖其外层定义, 内层语句执行完后,外层定义重新有效。

存储过程表达式
存储过程表达式可以是除聚集函数表达式外的任何SQL算术表达式
例子: var_value1; var_value1 var_value2;

变量定义
用DEFINE 语句定义变量,其类型可以是除SERIAL数据类型外 的所有SQL 数据类型
定义TEXT 或BYTE 类型变量时, 需在其变量前加关键字REFERENCES, 以表明该变量并不含有真正的数据, 而只是指向数据的指针。
可以使用LIKE定义与字段类型一致的数据类型
传入参数变量的定义在create procedure procname(var_value int)定义
 

例子:
DEFINE i,j INT;
DEFINE name VARCHAR(12);
DEFINE time_stamp DATETIME YEAR TO SECOND DEFAULT CURRENT YEAR TO SCECOND;
DEFINE date_value DATE;
DEFINE txt REFERENCES TEXT;
DEFINE by REFERENCES BYTE;
DEFINE p_customer like users.customer_num;
 
 

定义全局变量
define global global_var int default 0;
 
 
局部BLOB数据类型
只使用描述符:
LET
DEFINE
CALL
SELECT
存取BLOB数据:
INSERT
UPDATE
RETURN(到前端应用程序)
 
 
 
 
变量赋值 四种方式
1、利用LET 语句
LET i, j=1, 0;
LET var_name, var_num=(SELECT username, usernum FROM users WHERE usernum=100);

2、利用SELECT 或SELECT ... INTO 语句
SELECT username INTO var_name FROM users WHERE usernum=100;

3、利用CALL 语句
call proc_new(22)  returning var_no1;

4、利用EXECUTE PROCEDURE ...INTO 语句
execute procedure proc_name(username,address into p_name,p_addr);
 
 

语句块
create procedure pro_test()
returning int;
    begin
   
    define i int;
    let i=1;
    end
--begin,end 语句块(显示)
retrun i;
--returning,return语句块(隐含)
end procedure;
 
 
 

foreach循环
 
create procedure pro_foreach()
define id int;
select userid into id from users where age>30;
--select语句返回大于1的行,可以理解为将select到的值放在id这个列表中一个一个执行。
update others set uservalue=345 where userid=id;
end foreach;
end procedure;
 
 

使用update游标
条件分支
if then
elif then
else
end if
 
 

--------------------------------------------------
drop procedure pro_dele;
create procedure pro_dele()
define p_time date;
begin work;
foreach curl for
--update游标必须命名
select time_stamp into p_time from pro_dele_tbl
where num > 100
if p_time is not null then
delete from pro_del_tbl where current of curl;
--删除当前记录
end if;
end foreach;
commit work;
--所有修改记录的锁被释放。
end procedure;
--------------------------------------------------
 
 
 
 
if语句中的表达式

If exists(select username from users
   where usernum = 13) then
 …
end if
if var_num > all(select usernum from users
    where usernum = 23) then
 …
end if
if var_name matches “A*” then
 …
end if
 
 
 
 
 
循环语句while
 
格式: WHILE 条件语句    语句块   END WHILE

执行过程
先测试条件,若为真,则执行语句块,否则退出循环。
重复上述步骤,开始下一次循环,直到条件为假而退出循环

 

 

WHERE 与FOREACH 的区别

 


WHILE 循环的条件是不定的,循环次数不定,因而可能出现无穷循环
FOR和FOREACH 循环的条件是确定的,循环次数也是明确的,不可能出现无穷循环

例子
create procedure prowhile()
define i int;
define sum int;
let i=1;
let sum=0;
while i<100
let sum=sum i;
let i=i 1;
end while;
end procedure;
 
 
 

循环语句for
 
三种格式
FOR 变量 IN (expr1 to expr2 STEP expr3)  语句块   END FOR
--expr1,expr2表示范围,expr3表示步长,默认为1
for i=1 to 10 step 2
...
end for;

FOR 变量 = (expr1 to expr2 STEP expr3)  语句块   END FOR
--expr1,expr2表示范围,expr3表示步长,默认为1

FOR 变量 IN (expr1, expr2,...)  语句块   END FOR
for i in (1,2,3,4,5,7,8)
...
end for;
 
循环的转移
for i = 1 to 10
 if i = 5 then
  continue for;
----------------contiune将执行下一次循环
 elif i = 8 then
  exit for;
----------------exit for将退出循环,执行for循环的下一条语句
 end if;
end for;
 
 
 
 
 
循环语句foreach
 
 

用 FOREACH 语句可以查询或操作一组记录
FOREACH 隐式定义并打开一个游标
 

三种格式
FOREACH [WITH HOLD] SELECT ... INTO 语句
        语句块
END FOREACH;
-FOREACH 游标名[WITH HOLD] FOR SELECT ... INTO 语句
        语句块
END FOREACH;
FOREACH EXECUTE PROCEDURE 存储过程名(参数...参数)
     INTO 变量[, 变量[, ...]]    语句块
END FOREACH;
FOREACH 定义的游标在以下情况下关闭:

无行返回
事务提交或回滚导致非保护游标关闭
循环非正常退出(使用EXIT 或 ON EXCEPTION)
 
 
 
 
操作系统命令

system "echo" "Delete Operation Completed" "|mail judy";

数据库系统一直等到上述命令执行完毕
不能使用返回值判断执行是否成功
如执行不成功,将设置适当的ISAM错误代码和SQL错误代码
 
 
 
检查NOTFOUND条件
create procedure protest()
define num integer;
returning integer;
foreach select usernum into num from users
where usernum=20
--select执行失败将不执行foreach中的语句。
return num;
end foreach;
return;
--return没有返回值将在前端应用中引发NOTFOUND
end procedure;
 
 
 
 

递归调用

create procedure digui(i int defualt 1)
 returning int;
 if i <6 then
  return 1;
 end if;
 return n * digui(n-2);
--调用自己
end procedure;
 
 
 

获取serial值

create procedure seri_inst()
 define seri int;
 insert into users
  (user_num,user_date)
  values (1,"2006-01-03");
 let seri = dbinfo("sqlca.sqlerrd1");
--获取上一条insert语句中的serial值
 insert into other(num,name)
  values(seri,"new");
end procedure;
 
 
 
 
 
获取处理的记录数
 
create procedure num_rows()
 returning int;
 define num_rows int;
 delete from orders where customer_num = 104;
 let num_rows = dbinfo("sqlca.sqlerrd2");
--select、update或update的记录数
 return num_rows;
end procedure;
 
 
 
 

跟踪调试语句trace

存储过程被正确创建后,说明无语法错误,但有可能有逻辑错误
TRACE语句用于调试存储过程, 它可以跟踪以下存储过程实体的值:
变量(Variables)
过程参数(Procedure arguments)
返回值(Return values)
SQL 错误代码(SQL error codes)
ISAM 错误代码(ISAM error codes)
TRACE 语句把跟踪结果写到一个文件中, 该文件由SQL语句SET DEBUG FILE指定
 
 
 
 

TRACE 语句的三种形式:
TRACE ON :打开跟踪调试, 跟踪所有语句
TRACE OFF :关闭跟踪调试
TRACE PROCEDURE: 对于过程调用, 不跟踪过程体,仅跟踪过程的输入和返回值。
 
 
 
 
create procedure tracepro(var_user_num int)
 define var_user_date date;
 set debug file to "/export/home/user/trace";
--设置输出文件
 trace on;
--跟踪所有执行的语句
 select user_date into var_user_date
  from users
  where user_num = var_user_num;
 if var_user_date is null then
  trace "user date is null";
--执行到这里输出user date is null
  execute procedure other((var_user_num );
 end if;
 trace off;
--关闭跟踪
end procedure;


四 存储过程中的异常处理
 

没有异常处理
 
create procedure yichang ()
 returning int;
 define var_num integer;
 let  var_num = "jack";
--------存储过程到这将会出错
        return var_num;
end procedure;
 
 
 
 
异常处理
 
create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
 end exception;
end procedure;
 
 
 

异常捕获:ON EXCEPTION
 
 
用ON EXCEPTION语句捕获一个或一组特定的异常(即错误),用错误号标识。
ON EXCEPTION 语句与RAISE EXCEPTION 语句一起提供存储过程语言(SPL)的错误 捕获和恢复机制。
在一个语句块内可以定义多个 ON EXCEPTION 语句。
被捕获的异常可以是系统异常或用户定义的异常。
一旦异常被捕获,错误状态即被清除。
 
 

ON EXCEPTION 语句的位置:
ON EXCEPTION 语句是一声明性而非执行性语句, 故应位于任何执行语句之前,  而位于DEFINE 语句之后。
 
 
 
 
格式

           ON EXCEPTION IN (错误号,...)
           SET SQL 错误变量 ISAM 错误文本变量   语句块
           END EXCEPTION [WITH RESUME]
 

IN 子句说明欲捕获的错误号, 缺省时捕获所有的错误号。
SET 子句接收错误号和错误文本的变量,该语句可省略。
SQL 错误变量:  说明接收SQL 错误号的变量
ISAM错误变量: 说明接收ISAM错误号的变量
错误文本变量:   说明接收与SQL错误号对应的错误文本的变量
WITH RESUME 关键字用于把控制转向到捕获的错误被处理后的紧接发生异常语句后的语句,其效果相当于异常被处理后程序继续执行下去。 
WITH RESUME 可以省略。
 
 
 

捕捉特定的错误
 
create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
 end exception;
-----其他错误的捕捉
        on exception (-206)
  call new_tab();
 end exception;
-----表不在数据库中的错误在这里捕捉
end procedure;
 
 
 

异常处理后继续执行
 
        on exception (-206)
  call new_tab();
 end exception with resume;
        select new froom tab;
--出错将继续执行
        let nex=9;
 
 

WITH RESUME将继续
执行出错行后面的语句

如果没有WITH  RESUME将继续执行下一次循环或下一个语句块,如果有的话。如果没有语句块,则过程将结束。
 
 
 

异常捕获:RAISE EXCEPTION

用RAISE EXECPTION 语句模拟异常的产生,该异常可被ON EXECTPION语句捕获。
格式:
      RAISE EXCEPTION SQL 错误号, ISAM 错误号, 错误文本变量
SQL错误号和ISAM错误号均可是SPL表达式,且其计算结果是一个常数(错误号)
例子:
RAISE EXCEPTION -99999, 0, --Broke the Rule
 
 
 

create procedure err_deal()
 define sql_err int;
 define isam_err int;
 define error_info char(100);
 on exception set sql_err, isam_err, error_info
  call error_rout(sql_err,isam_err,error_info);
                raise exception sql_err, isam_err, error_info;
----------------RAISE EXCEPTION引发一个人工的错误信息
 end exception;
end procedure;
 
 
 
 

存储过程的权限    两类存储过程
DBA 权限的存储过程
所有者权限的存储过程
 
下列用户可以创建存储过程
具有RESOURCE 权限的用户可以创建存储过程

 

 

下列用户可以执行存储过程
DBA 用户
存储过程的创建者
具有EXECUTE 权限的用户

 

 

 

 

 

 

 

 

 

]]>
Tue,27 May 2008 16:43:10 CST 0
<![CDATA[dbschema 详解]]> .html dbschema 详解

在网上找了许久,还真没发现关于 dbschema 工具有更全的说明资料。我也是多方收集过来的,大有慢慢看吧,疑问就在这里问吧,不过,留言是当天就可以看到的,而评论就不一定,可能半年能好使一回。呵呵。

 

 

dbschema 实用程序打印复制指定表、视图或数据库所需的 SQL 语句。它还显示 UPDATE STATISTICS 语句创建的分发。

可以将 dbschema 实用程序用于以下用途:

显示 SQL 语句(模式),这是复制数据库或特定表、视图、同义词、序列或过程所必需的。
显示 Information Schema 视图的模式
显示为数据库中的一个或多个表存储的分布信息
显示有关用户定义的数据类型和行类型的信息

 

警告:
使用 dbschema 实用程序可以增加数据库中的序列对象,而在生成的数字中创建间隔则可能不是那些需要序列化整数的应用程序所期望的。


使用 dbschema 且只指定了数据库名称时,等价于使用带所有选项(除了 -hd 和 -ss 选项)的 dbschema。另外,如果为数据库创建了“信息模式”视图,则将显示此模式。例如:以下两个命令是等价的:

dbschema -d stores_demo
dbschema -s all -p all -t all -f all -d stores_demo

经常使用的导出数据库所有信息的语句。
dbschema -s all -p all -t all -f all -d stores_demo -ss stores.sql

 

 

命令格式

dbschema [-q] [-t tabname] [-s user] [-p user] [-r rolename] [-f procname]
[-hd tabname] -d dbname [-w passwd] [-seq sequence] [-l [num]]
[-u [ia] udtname [all]] [-it [Type]] [-ss [-si]] [filename]

 

参数:
-q Suppress the db version from header

-t table name or "all" for all tables

-s synonyms created by user name
or "all" for all users

-p permissions granted to user name
or "all" for all users

-r create and grant of the role
or "all" for all roles :Not a valid option for SE

-f SPL routine name
or "all" for all SPL routines


-hd Histograms of the distribution for columns of
of a specified table, a specific table column,
or "all" for all tables.

-d database name

-w database password

-seq generate sequence specific syntax

-u Prints the definitions of user-defined data types

-ui Prints the definitions of user-defined data types,
including type inheritance

-ua Prints the definitions of user-defined data types,
including all functions and casts defined over a type

-u all Directs dbschema to include all the tables
in the display of distributions

-it Type of isolation can be DR, CR, CS or RR

-l set lock mode to wait [number] optional

-ss generate server specific syntax

-si excludes the generation of index storage clauses for
non-fragmented tables

filename is the name
of file that the SQL
script goes in.

 

 

常见事例:

1)导出数据库中所有的表结构到文件db.sql
  $>dbschema -d your_database -t all  db.sql  

2)导出数据库中所有的存储过程到文件db.sql
  $>dbschema -d your_database -f all  db.sql

3)导出数据库中的所有对象(包含表,存储过程,触发器。。。)到文件db.sql
  $>dbschema -d your_database db.sql

4)导出数据库中一个表的结构到文件db.sql
  $>dbschema -d your_database_name -t your_table_name db.sql

5)导出一个存储过程定义到文件db.sql
  $>dbschema -d your_database_name -f your_procedure_name  db.sql

6)如果导出更多的表的信息(EXTENT...)
  $>dbschema -d your_database_name -ss db.sql

7)导出数据库中对用户或角色的授权信息
  $>dbschema -d your_database_name -p all
  $>dbschema -d your_database_name -r all

8)导出数据库中的同义词
  $>dbschema -d your_database_name -s all

 

]]>
Tue,27 May 2008 15:15:49 CST 0
<![CDATA[“存储过程”的定义及优点]]> .html 存储过程

sql语句执行的时候要先编译,然后执行。存储过程就是编译好了的一些sql语句。应用程序需要用的时候直接调用就可以了,所以效率会高。

 

存储过程介绍

 

存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在ORACLE中,若干个有联系的过程可以组合在一起构成程序包。

 

使用存储过程有以下的优点:

 

* 存储过程的能力大大增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的 运算。

 

* 可保证数据的安全性和完整性。

 

# 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。

 

# 通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。

 

* 再运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。 由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。

 

* 可以降低网络的通信量。

 

* 使体现企业规则的运算程序放入数据库服务器中,以便:

 

# 集中控制。

 

# 当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的 运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可以了,应用程序无须任何变化。

 

数据库存储过程的实质就是部署在数据库端的一组定义代码以及SQL。

 

利用SQL的语言可以编写对于数据库访问的存储过程,其语法如下:

 

CREATE PROC[EDURE] procedure_name [;number] 
[ 
{@parameter data_type} ][VARYING] [= default] [OUTPUT] 
] 
[,...n] 
[WITH 
{ 
RECOMPILE 
| ENCRYPTION 
| RECOMPILE, ENCRYPTION 
} 
] 
[FOR REPLICATION] 
AS 
sql_statement [...n]

 

 

[ ]内的内容是可选项,而()内的内容是必选项,

例: 若用户想建立一个删除表tmp中的记录的存储过程Select_delete可写为:

 

Create Proc select_del As 
Delete tmp 

 

 

例:用户想查询tmp表中某年的数据的存储过程

 

create proc select_query @year int as 
select * from tmp where year=@year

 

 

在这里@year是存储过程的参数

例:该存储过程是从某结点n开始找到最上层的父亲结点,这种经常用到的过程可以由存储过程来担当,在网页中重复使用达到共享。

空:表示该结点为顶层结点

fjdid(父结点编号) 

结点n 非空:表示该结点的父亲结点号

dwmc(单位名称)

]]>
Tue,27 May 2008 11:20:18 CST 0
<![CDATA[Informix存储过程示例]]> .html Informix存储过程示例

 

create procedure "npmuser".chk_grade(s_time datetime year to second)

        define v_ne_id integer;
        define v_ne_type integer;
        define v_time datetime year to second;
        define v42 float;
        define v66 float;
        define v45 float;
        define v43 float;
        define v65 float;
        define v411 float;
        define v67 float;
        define f42 float;
        define f66 float;
        define f45 float;
        define f43 float;
        define f65 float;
        define f411 float;
        define f67 float;
        SET DEBUG FILE TO '/tmp/chk_grade.log';
        TRACE 'BEGIN 24h traff';
        TRACE ON;
        delete from chk_grade where first_result=s_time;
        insert into chk_grade(ne_id,ne_type,first_result,g42,
        g66,g45,g43,g65,g411,g67)
        select
        TPA_UNIC_MSC_SUM.ne_id,TPA_UNIC_MSC_SUM.ne_type,TPA_UNIC_MSC_SUM.first
_result,
        (SFB_DIVFLOAT_1((NVL(TPA_UNIC_MSC_SUM.SEND_IAI_MSG_NHO,0) NVL(TPA_UNIC_MSC_SUM.VOICE_PAGING_
REQ,0)),(TPA_UNIC_BTS_SUM.TCH_SEIZE_NHO*SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,(NVL
(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,0) NVL(TPA_UNIC_MSC_SUM.RECE_CALLCONFIRM_MSG,0)),0,0) NVL(
TPA_UNIC_MSC_SUM.RECE_IAI_MSG_NHO,0)),0,0)*(SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,
(NVL(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,0) NVL(TPA_UNIC_MSC_SUM.RECE_CALLCONFIRM_MSG,0)),0,0)*
SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.RAND_ACC_SUC,TPA_UNIC_BTS_SUM.RAND_ACC_ATT,0,0)*SFB_DIVFLOAT_1(TPA_U
NIC_BTS_SUM.TCH_SEIZE_NHO,TPA_UNIC_BTS_SUM.TCH_CALL_REQ_NHO,0,0) (1-SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.
SEND_CALLPROCEEDING_MSG,(NVL(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,0) NVL(TPA_UNIC_MSC_SUM.RECE_C
ALLCONFIRM_MSG,0)),0,0))*SFB_DIVFLOAT_1(NVL(TPA_UNIC_MSC_SUM.PAGING_RESP,0),NVL(TPA_UNIC_MSC_SUM.PAG
ING_REQ, 0),0,0)*SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.TCH_SEIZE_NHO,TPA_UNIC_BTS_SUM.TCH_CALL_REQ_NHO,0,0
)))*100,
        NVL(SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.TCH_TRAFFIC*60,TPA_UNIC_BTS_SUM.DROP_CALL_TCH,0,0),0),
        (SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,(NVL(TPA_UNIC_MSC_SUM.SEND_CALLPROC
EEDING_MSG,0) NVL(TPA_UNIC_MSC_SUM.RECE_CALLCONFIRM_MSG,0)),0,0)*SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.RAN
D_ACC_SUC,TPA_UNIC_BTS_SUM.RAND_ACC_ATT,0,0)*SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.TCH_SEIZE_NHO,TPA_UNIC_
BTS_SUM.TCH_CALL_REQ_NHO,0,0) (1-SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,(NVL(TPA_UN
IC_MSC_SUM.SEND_CALLPROCEEDING_MSG,0) NVL(TPA_UNIC_MSC_SUM.RECE_CALLCONFIRM_MSG,0)),0,0))*SFB_DIVFLO
AT_1(NVL (TPA_UNIC_MSC_SUM.PAGING_RESP,0),NVL(TPA_UNIC_MSC_SUM.PAGING_REQ,0),0,0)*SFB_DIVFLOAT_1(TPA
_UNIC_BTS_SUM.TCH_SEIZE_NHO,TPA_UNIC_BTS_SUM.TCH_CALL_REQ_NHO,0,0))*100,
        (SFB_DIVFLOAT_1((NVL(TPA_UNIC_MSC_SUM.SEND_IAI_MSG_NHO,0) NVL(TPA_UNIC_MSC_SUM.VOICE_PAGING_
REQ,0) NVL(TPA_UNIC_MSC_SUM.LOSE_NUM_USER_BUSY_CALLED,0)),(TPA_UNIC_BTS_SUM.TCH_SEIZE_NHO*(SFB_DIVFL
OAT_1(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,(NVL(TPA_UNIC_MSC_SUM.SEND_CALLPROCEEDING_MSG,0) NVL(
TPA_UNIC_MSC_SUM.RECE_CALLCONFIRM_MSG,0)),0,0)) NVL(TPA_UNIC_MSC_SUM.RECE_IAI_MSG_NHO,0)-(NVL(TPA_UN
IC_MSC_SUM.ROUTING_QUERY_REQ,0)-NVL(TPA_UNIC_MSC_SUM.ROUTING_QUERY_SUC,0))),0,0))*100 ,
        NVL(SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.DROP_CALL_TCH,TPA_UNIC_BTS_SUM.TCH_SEIZE_NHO,0,0)*100,0)
,
        NVL(SFB_DIVFLOAT_1(TPA_UNIC_MSC_SUM.PAGING_RESP,TPA_UNIC_MSC_SUM.PAGING_REQ,0,0)*100,0),
        NVL(SFB_DIVFLOAT_1(TPA_UNIC_BTS_SUM.WORST_CELL,TPA_GSMA_UNIC_SUM.TOTAL_CELL,0,0)*100,0)
        from tpa_unic_msc_sum tpa_unic_msc_sum,tpa_unic_bts_sum tpa_unic_bts_sum,tpa_gsma_unic_sum t
pa_gsma_unic_sum
        where tpa_unic_msc_sum.first_result=tpa_unic_bts_sum.first_result
        and tpa_gsma_unic_sum.first_result=tpa_unic_bts_sum.first_result
        and tpa_unic_msc_sum.ne_id=tpa_unic_bts_sum.ne_id
        and tpa_gsma_unic_sum.ne_id=tpa_unic_bts_sum.ne_id
        and tpa_unic_bts_sum.ne_type in (10000,10003)
        and tpa_unic_msc_sum.first_result=s_time
        and tpa_unic_msc_sum.sv_id=-1;
        foreach
        select ne_id,ne_type,first_result,g42,g66,g45,g43,g65,g411,g67
          into v_ne_id,v_ne_type,v_time,v42,v66,v45,v43,v65,v411,v67
        from chk_grade
        where first_result=s_time
        ------------------g42-------------------
        if v42 - 88 >= 0 then
        if v42 - 88 >= 5 then
        let f42 = 5;
        else
        let f42 = 3 (v42 - 88)*0.4;
        end if;
        end if;
        if v42 - 88 < 0 then
        if 88 - v42 >= 10 then
        let f42 = 0;
        else
        let f42 = 3 (v42 - 88)*0.3;
        end if;
        end if;
        update chk_grade set g42_fact = f42 where ne_id = v_ne_id and ne_type = v_ne_type and first_
result = v_time;
        -------------------------------------
        ------------------g66-------------------
        if v66 - 100 >= 0 then
        if v66 - 100 >= 30 then
        let f66 = 5;
        else
        let f66 = 3 (v66 - 100)*0.4/6;
        end if;
        end if;
        if v66 - 100 < 0 then
        if 100 - v66 >= 60 then
        let f66 = 0;
        else
        let f66 = 3 (v66 - 100)*0.3/6;
        end if;
        end if;
        update chk_grade set g66_fact = f66 where ne_id = v_ne_id and ne_type = v_ne_type and first_
result = v_time;
        -------------------------------------
        ------------------g45-------------------
        if v45 - 92 >= 0 then
        if v45 - 92 >= 4 then
        let f45 = 3;
        else
        let f45 = 1.8 (v45 - 92)*0.3;
        end if;
        end if;
        if v45 - 92 < 0 then
        if 92 - v45 >= 6 then
        let f45 = 0;
        else
        let f45 = 1.8 (v45 - 92)*0.3;
        end if;
        end if;
        update chk_grade set g45_fact = f45 where ne_id = v_ne_id and ne_type = v_ne_type and first_
result = v_time;
        --------------------------------------
        ------------------g43-------------------
        if v43 >= 95  then
        if v43 >= 99  then
        let f43 = 3;
        else
        let f43 = 1.8 (v43 - 95)*0.3;
        end if;
        end if;
        if v43 < 95  then
        if v43 <