星期日, 十二月 03, 2006

食 品 相 克 列 表

食 品 相 克 列 表

1.猪肉菱角若共食,肚子疼痛不好受. 2.牛肉栗子一起吃,食后就会发呕吐.
3.羊肉滋补大有用,若遇西瓜定相侵. 4.狗肉滋补需注意,若遇绿豆定伤身.
5.兔肉芹菜本不合,同食之后头发脱. 6.鸡肉芹菜也相忌,同食就会伤元气.
7.鹅肉鸡蛋不同窝,一同入胃伤身体. 8.鲤鱼甘草性相反,兼食而之定伤身.
9.黄鳝皮蛋皆佳肴,不可同桌结伴行. 10.鸡蛋若遇消炎片,同室操戈两相争.
11.鸡蛋糖精更相克,同食中毒更伤身. 12.柿子红薯若同吃,体内结石易形成.
13.柿子螃蟹也相背,同食之后会腹泻. 14.柿子白酒更不合,食后使你心发闷.
15.豆腐蜂蜜伴着吃,味道虽好耳要聋. 16.洋葱蜂蜜也不合,同食就会伤眼睛.
17.香蕉芋头本不合,同时入胃腹胀痛. 18.香蕉相克马铃薯,同食面部要起斑.
19.黄瓜生熟都可以,进食之际忌花生. 20.萝卜木耳不同食,食了容易生皮炎.
21.萝卜水果更相背,甲状腺肿会诱发.
 * 以下食物两小时内不能同时食用,否则会发生中毒,甚至有生命危险,千万不可大意,提供中毒解救小窍门,供参考:

脚鱼与苋菜:食则死亡。解救:吃空心菜汁
鲤鱼与甘草:食则死亡。解救:吃麻油二两;
狗肉和绿豆:食则胀腹。解救:甘草一两煎水服;
桃子下烧酒:食则昏倒,多吃死亡。解救:服牛黄解毒丸三粒;
黄瓜与花生:食则泻肚。解救:吃藿香正气丸二粒;
蜂糖与生葱:食则死亡。解救:米炒枯研末,再用甘草二两煎水冲枯米吃;
茶煮青蛙:食则死亡,无法解救;
蚕豆与田螺:食则绞畅痛。解救:吃儿童小便二两;
香蕉与芋头:食则中毒。解救:吃桐油五钱;
冰棒与西红柿:食则中毒。解救:吃穿心莲二两煎水服;
羊肉和西瓜:食则中毒。解救:甘草二两煎水服;
猪肉和芝麻花:食则死亡。解救:吃空心菜汁二两;
芥菜与兔肉:食则死亡。解救:吃杨梅水二两;
不可单用生姜下酒:食则胃脘痛,多吃则烂肝脏;
冬笋和龟肉:食则中毒。解救:甘草二两煎水服;
鲫鱼与冬瓜:食则脱水。解救:吃空心菜汁二两;
黄疸病忌马肉:食则死亡。无法解救
甜酒与味精:食则中毒。解救:甘草煎水服;
牛肉与香附子:食则生九子疡;
油煎鸡蛋与糖精:食则中毒。解救:牛黄五分,开水服;
鹿肉与南瓜:食则死亡。无法解救;
抬头黄鳝不能吃:食则死亡。无法解救;
洋葱与癞蛤蟆:食则死亡。解救:车钱子一两水煎服;
红薯与柿子:食则胃结石,多吃死亡;
螃蟹与柑桔:食则中毒。解救:吃大蒜汁;
螃蟹与柿子:食则中毒。解救:吃藕节(煮水)
螃蟹与泥鳅:食则中毒。解救:吃黄泥水
螃蟹与茄子:食则中毒。解救:吃藕节(煮水)
螃蟹与香瓜:食则中毒。解救:吃柑桔皮
螃蟹与生花生:食则中毒。解救:吃黄泥水
螃蟹与冰水:食则中毒。解救:吃藕节(煮水)
田螺与玉米:食则中毒。解救:吃黄泥水。
田螺与香瓜:食则中毒。解救:吃黄泥水。
鲫鱼与蜂糖;食则中毒。解救:吃黑豆甘汤草
牛奶与酸醋物:食则腹结石。解救:吃绿豆汤
牛肉与韭菜:食则中毒。解救:吃人奶或豉汁
蟮鱼与红枣:吃则脱发。解救:吃蟹
牛奶与菠菜:食则拉痢。解救:吃绿豆汤
鳝鱼与南瓜:食则中毒。解救:吃蟹
竹笋与麦芽糖;食则中毒。解救:吃绿豆汤
番茄与石榴:食则中毒。解救:吃韭菜汁
鸡肉与李子:食则拉痢,解救:吃鸡屎白
鸭蛋与李子:食则中毒。解救:吃黄泥水
竹笋与羊肝:食则中毒。解救:吃黄泥水
雀肉与李子:食则中毒。解救:吃鸡屎白
黑枣与柿子:食则解释。解救:无方
以上仅供参考,若发生中毒症状,应及时送医院为妥。
1、萝卜: 严禁与桔子同食,同食患甲状腺肿;忌何首乌、地黄;服人参时忌食;忌与胡萝卜同食。
2、胡萝卜:不宜和西红柿、萝卜、辣椒、石榴、莴苣、木瓜等水果同吃。最好单独吃肉类烹调。
3、黄瓜: 不宜和维生素c含量高的蔬菜如西红柿、辣椒等同烹调。
4、甘薯: (红薯、白薯、地瓜、山芋);不能与柿子同食,二者相聚会形成胃柿石,引起胃胀、腹痛、
呕吐,严重时可导致胃出血等,危及生命;也不宜与香蕉同吃。
5、韭菜: 不可与菠菜同食,二者同食有滑肠作用,易引起腹泻;不可与蜂蜜同食,同食则令人心痛;
不可与牛肉同食,同食令人发热动火。
6、茄子: 忌与黑鱼、蟹同食,同食有损肠胃;过老熟的茄子不宜食,易中毒。
7、菠菜: 忌韭菜;不宜与豆腐同食,同食使人缺钙。
8、小白菜:忌兔肉。
9、南瓜: 不可与羊肉同食,否则易发生黄疸和脚气;不可与富含维生素c 的蔬菜、水果同食。
10、竹笋: 不宜与豆腐同食,同食易生结石;不可与鹧鸪肉同食,同食令人腹胀;不可与糖同食;不宜与羊肝同食。
11、辣椒: 忌与羊肝、南瓜同食。
12、香菜: 不可与一切补药同食;忌白术、牡丹皮。
13、莼菜: 忌与醋同食。
14、茭白: 不宜与豆腐同食,否则易形成结石。
15、芹菜: 忌同醋食,否则易损齿;不宜与黄瓜同食。
16、芥菜: 忌与鲫鱼同食,否则易引发水肿。
17、蕨菜: 忌与黄豆、花生、毛豆等同吃。
18、菜瓜: 忌与牛奶、奶酪、鱼类同食,否则易生疾病。
19、山药: 忌鲫鱼、甘遂。
20、豆腐(豆浆):不要与牛奶同食;不要与菠菜同烹调;忌用豆浆冲鸡蛋;忌与四环素同用。
21、木耳: 忌与田螺、雉鸡、野鸭、鹌鹑肉同食;忌与四环素同服
22、苋菜: 不宜与菠菜、蕨粉同食
23、苦菜: 不可与蜂蜜同食
24、花生: 忌蕨菜、毛蟹、黄瓜。
25、马齿苋:不宜与鳖甲同食。
26、香瓜: 忌与蟹、田螺、油饼同吃
27、猪肉: 忌与鹌鹑同食,同食令人面黑;忌与鸽肉、鲫鱼、虾同食,同食令人滞气;忌与荞麦同食,同食令人落毛发;忌与菱角、黄豆、蕨菜、桔梗、乌梅、百合、巴豆、大黄、黄连、苍术同食;忌与牛肉、驴肉、羊肝同食。
28、猪脑髓:不可与酒、盐同食,影响男子性功能;
29、羊肉: 忌与豆酱、荞麦面、乳酪、南瓜、醋、赤豆、梅干菜同食;忌铜、丹砂。
30、鸡肉: 老鸡鸡头不能吃,因毒素滞留在脑细胞内,民间有"十年鸡头生砒霜"的说法;忌与糯米、李子、大蒜、鲤鱼、鳖鱼、虾、兔肉同食;忌芥末、菊花。
31、猪油: 不宜与梅子同食。
32、牛肉: 不可与鱼肉同烹调;不可与栗子、黍米、蜂蜜同食;不宜与韭菜、白酒、生姜同食。
33、猪肝: 忌与荞麦、黄豆、豆腐同食,同食发痼疾;忌与鱼肉同食,否则令人伤神;忌与雀肉、山鸡、鹌鹑肉同食。
34、牛肝: 忌鲍鱼、鲇鱼;不宜与富含维生素c的食物同食。
35、鸭肉: 反木耳、胡桃;不宜与鳖肉同食,同食令人阴盛阳虚,水肿泄泻。
36、狗肉: 忌与绿豆、杏仁、菱角、鲤鱼、泥鳅同食;忌用茶;不宜与大蒜同食。
37、猪血: 忌黄豆,同食令人气滞;忌地黄、何首乌。
38、羊心、 羊肝:忌与生椒、梅、赤豆、苦笋、猪肉同食;不宜与富含维生素c的蔬菜同食。
39、驴肉: 忌荆芥;不宜与猪肉同食,否则易致腹泻。
40、马肉: 不宜与大米(粳米)、猪肉同食;忌生姜、苍耳。
41、鹅肉: 不宜与鸭梨同吃。
42、鹿肉: 不宜与雉鸡、鱼虾、蒲白同食
43、雀肉: 春夏不宜食,冬三月为食雀季节。不宜与猪肝、牛肉、羊肉同食;忌李子、白术。
44、鸡蛋: 忌与柿子同食,同食可引起腹痛、腹泻,易形成"柿结石";不宜与兔肉、鲤鱼、豆浆同食;民间有吃"毛蛋"之习,其实"毛蛋"中含有大量病菌,易中毒。
45、鸭蛋: 不宜与李子、桑椹子同食。
46、野鸭: 忌与木耳、核桃、荞麦同食
47、鹧鸪肉:忌与竹笋同食
48、水獭肉:忌与兔肉、柿子同吃
49、獐肉: 不宜与虾、生菜、梅子、李子同食
50、鹌鹑肉:不宜与猪肉、猪肝、蘑菇、木耳同食。
51、雉鸡(野鸡)不宜与猪肝、鲇鱼、鲫鱼、木耳、胡桃、荞麦同食
52、猫肉: 忌藜芦;猫肉有伤胎之弊,孕妇忌服。
53、虾: 严禁同时服用大量维生素c。否则,可生成三价砷,能致死,不宜与猪肉同食损精;忌与狗、鸡肉同食;忌糖。
54、鲤鱼: 忌朱砂、狗肉。葵菜、赤小豆、咸菜不宜与狗肉同食。
55、泥鳅: 不宜与狗肉同食。
56、海带: 不宜与甘草同食。
57、鲫鱼: 不宜与芥菜、猪肝、猪肉、蒜、鸡肉、鹿肉等同食;忌山药、厚朴、麦冬、甘草。
58、鳖肉: 忌猪肉、兔肉、鸭蛋、苋菜;忌与薄荷同煮;忌与鸭肉同食,久食令人阴盛阳虚,水肿泄泻。
59、带鱼、 平鱼、银鱼、黄花鱼:忌用牛、羊油煎炸;凡海味均禁甘草;反荆芥。
60、龟肉: 不宜与酒、果、瓜、猪肉、苋菜同食。
61、蜗牛: 忌蝎子。
62、田螺: 忌与香瓜、木耳、蛤蚧、冰糖同食;忌与四环素同用。
63、鲶鱼: 不宜与牛肝同食;忌用牛、羊油煎炸;不可与荆芥同用。
64、鳝鱼: 忌狗血、狗肉,同食助热动风;忌荆芥,同食令人吐,青色鳝鱼有毒,黄色无毒。有毒鳝鱼一次吃250克,可致死。
65、海鳗鱼:不宜与白果、甘草同食。
66、青鱼: 忌用牛、羊油煎炸;不可与荆芥、白术、苍术同食。
67、牡蛎肉:不宜与糖同食。
68、枣: 不可与海鲜同食,否则令人腰腹疼痛;不可与葱同食,否则令人脏腑不合,头胀。
69、苹果: 不宜与海味同食(海味与含有鞣酸的水果同吃,则易引起腹痛、恶心、呕吐等)。
70、鸭梨: 忌鹅肉、蟹;忌多吃;忌与油腻、冷热之物杂食。
71、桔子: 忌与萝卜同食,同食诱发甲状腺肿;忌与牛奶、蟹、蛤同食。
72、山楂、 石榴、木瓜、葡萄:不宜与海鲜类、鱼类同食;服人参者忌用;忌铁器;忌和四环素同吃。
73、桃子: 不宜与鳖肉、龟肉同食。
74、香蕉: 不宜与白薯同食。
75、柿子: 忌与蟹、水獭肉同食,同食腹痛、大泻;忌与红薯、酒同食。
76、杨梅: 忌生葱;不宜与羊肛,鳗鱼同食。
77、杏: 忌与小米同食,否则令人呕泻。
78、芒果:忌与大蒜等辛物同食。
79、银杏(白果):严禁多吃,婴儿吃10颗左右可致命,三、五岁小儿吃30~40颗可致命;不可与鱼同吃,同食则产生不利于人体的生化反应,小儿尤忌。
80、柑子:忌与蟹同食。
81、大米(粳米):不可与马肉同食,不可与苍耳同食,同食心痛;
82、黄豆:不宜与猪血、蕨菜同食;服四环素时忌用。
83、绿豆:不宜与狗肉、榧子同食
84、小米(粟米)不可与杏同食,同食易使人呕吐泄泻;气滞者忌用。
85、黑豆:忌与厚朴、蓖麻籽、四环素同用。
86、红豆:忌与米同煮,食之发口疮;不宜与羊肉同食;蛇咬伤,忌食百日;多尿者忌用。
87、葱: 不宜与杨梅、蜜糖同食,同食易气壅胸闷;忌枣、常山、地黄。
88、醋: 忌丹参、茯苓;不宜与海参、羊肉、奶粉同食;忌壁虎,可致死。
89、糖: 忌虾;不可与竹笋同煮;不宜与牛奶、含铜食物同食。
90、酒: 忌与汽水、啤酒、咖啡、奶、茶、糖同饮,不然对胃肠、肝、肾脏器官有严重的损害;不宜与牛肉、柿同食。
91、茶: 贫血病人服用铁剂时,忌饮茶。不宜与狗肉同食;服人参等滋补药品时忌用。
92、蒜: 一般不与补药同服。忌蜜、地黄、何首乌、牡丹皮;
93、花椒:忌防风、附子、款冬。
94、牛奶:忌牛奶中放钙粉;勿用牛奶冲鸡蛋;不宜与巧克力、桔子, 四环素同食。
95、蜜: 不宜与葱、蒜、韭菜、莴苣、豆腐同食,不然易引起腹泄

星期五, 十一月 24, 2006

Delphi之面向对象程序开发

Delphi之面向对象程序开发
作者:熊建峰 网址:http://www.passtwo.com 邮箱:passtwo@gmail.com
  使用Delphi编程也有一段时间了,Delphi开发程序效率很高,但是一直感觉和VB开发程序没有什么两样,除了语法的区别之外就是在控件、窗体等基础上进行程序开发了,Delphi面向对象开发的特点没有一点体现出来。
  最近在开发一个应用程序的时候对系统代码进行查看,才恍然大悟,其实,基于Delphi的VCL组件下的开发实际上就已经遵循了面向对象的规则。举例说明如下:
例1:一个普通的Delphi窗体
我们利用Delphi进行程序开发的时候,首先就是一个窗体,设置好窗体的属性,好了,我们来看看窗体的代码。如下:
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
首先看看这段代码,定义了一个类型TForm1,它集成自TForm类,同时有两个属性:Edit1和Button1。同时还有可以添加private和public的地方。从面向对象的角度来讲,这属于面向对象的一个典型应用(使用了集成来生成新的类型)。那么,有人会说,在delphi下本来就是这样,跟我的程序有什么关系?我又怎样才能把面向对象的方法应用到我的程序中来呢?下面我来举一个例子说明。
例2:一个简单的继承
  图1列出了一个大家比较熟悉的继承关系,图中包含三各类:水果,苹果,桔子。水果作为基类,它有两个属性:颜色和重量,另外水果都可以被食用,但是不同的水果有不同的方法,所以在水果类中有一个public abstract void 食用(),所有水果的子类必须实现该方法。苹果和桔子为水果的子类,它们集成了水果的基本特性:颜色和重量,另外它们分别实现了水果的食用()方法。它们的代码看起来如下:
unit Ufruit;

interface

uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs;

type
TFruit = class(TObject)
private
mColor: Integer;
weight: Integer;
public
procedure eat; virtual; abstract;
end;

TApple = class(TFruit)
public
procedure eat;
end;

TOrange = class(TFruit)
public
procedure eat;
end;


implementation

{
************************************ TApple ************************************
}
procedure TApple.eat;
begin
end;

{
*********************************** TOrange ************************************
}
procedure TOrange.eat;
begin
end;


end.
  以上的代码是继承关系在Delphi下的编写,那么这些东西怎样才能和VCL组件结合起来,形成我们所熟悉的Form展现给用户呢?下面我们举例说明这个问题


图1
例三:使用Form实现水果的集成
有了我们水果的类图,我们使用Delphi的窗体来对水果集成关系做一个界面出来,首先是基类:TFruit,窗体界面如图2:

图2
它的代码如下:
unit UFruit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TfrmFruit = class(TForm)
mColor: TEdit;
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure eat; virtual; abstract;
end;

var
frmFruit: TfrmFruit;

implementation

{$R *.dfm}

procedure TfrmFruit.Button1Click(Sender: TObject);
begin
eat;
end;

end.
接下来我们实现苹果类:选择File->New->Other->project1,如图3所示

图3
点击ok后,将出现苹果类的窗体(有没有感觉和水果类很像呀^_^),更改窗体的caption和name属性,然后实现fruit的eat方法,好了,我们的苹果类就做好了,如图4:

图4
它的代码如下:
unit UApple;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, UFruit, StdCtrls;

type
TfrmApple = class(TfrmFruit)
private
{ Private declarations }
public
{ Public declarations }
procedure eat;override;
end;

var
frmApple: TfrmApple;

implementation

{$R *.dfm}

{ TfrmApple }

procedure TfrmApple.eat;
begin
Application.MessageBox ('我是苹果,吃起来是甜的!','',32);
end;

end.
同样的方法,实现桔子类,程序界面如图:

图5
代码如下:
unit UOrange;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, UFruit, StdCtrls;

type
TfrmOrange = class(TfrmFruit)
private
{ Private declarations }
public
{ Public declarations }
procedure eat;override;
end;

var
frmOrange: TfrmOrange;

implementation

{$R *.dfm}

{ TfrmOrange }

procedure TfrmOrange.eat;
begin
Application.MessageBox('我是桔子,吃起来是酸的!','',32);
end;

end.
小结
以上我们使用Delphi的窗体实现了水果类、苹果类和桔子类,这样,就将实际的业务类和VCL组件类结合起来了。使用同样的方法,我们在进行数据库编程的时候可以首先考虑进行业务建模,然后画出类图,最后使用Delphi的窗体来完成整个程序的开发。我写这篇文章旨在抛砖引玉,欢迎大家一起讨论。

星期一, 十一月 06, 2006

针对URL的SEO方法-随想飞翔

针对URL的SEO方法-随想飞翔: "以下仅是个人经验,未经任何试验验证,请自行判断以下方法是否可行,使用如下方法进行SEO,任何后果自负。

作者:Cloudream http://www.5iya.com/blog/
转载请注明以上信息

匹配指匹配用户搜索关键字。

1. 主域名匹配优于目录名或网页名匹配。
2. 英文关键字之间应使用 - 或 _ 链接。
3. 针对中文关键字,中文目录名和网页名优于英文目录名和网页名。Google、百度可识别中文目录名和网页名,但其它搜索引擎未知。中文目录名和网页名可能导致部分浏览器无法识别该URL。
"

Google Adsense 提示100条-随想飞翔

Google Adsense 提示100条-随想飞翔: "译注:少数条目有重复,不重新编排以遵从原文。

1. AdSense 收入 = 广告展示次数 x 点击率 x 点击单价 x 智能定价因素(Smart Price)
2. 广告展示次数基于你的网站流量,该项代表Adsense广告展示次数。(译注:废话-。-!)
3. 点击率为广告被点击次数÷广告展示次数,基本范围为0.1%-30%,大多数为1%-10%(译注:中文广告偏低,大陆地区平均点击率约0.2%)。
4. 点击单击为每次点击的收入,一般根据广告商付出的点击单价决定。
5. 智能定价机制为Google衡量你的网站刊登广�"

星期四, 十一月 02, 2006

计算机二级上机考试评分方法 - QQread.com 教育频道

计算机二级上机考试评分方法 - QQread.com 教育频道: "计算机二级上机考试评分方法
http://edu.qqread.com  作者:玲珑草草 来源:

  上机必读
二级上机考试部分评分方法

  自动评分系统有客观、公正的优点,但也有死板的缺点,要想得到比较好的分数,应当考虑到机器的这一特点。实际考试还有人工复查一项,由省级考试部门负责进行.但是人工复查如何进行,我们完全不得而知。因此我们下面的所有内容均不含人工复查内容,仅从考试系统本身来进行分析和说明。
  我们从多次使用中摸索�"

星期二, 十月 24, 2006

给控件做数字签名之三:进行数字签名 - 阿泰的软件实用主义 - 博客园

给控件做数字签名之三:进行数字签名 - 阿泰的软件实用主义 - 博客园: "双击工具包里的signcode.exe
文中提到的数字签名工具包,请在此处下载
http://www.cnblogs.com/Files/babyt/SignTool.rar
































至此,数字签名完成
在DOS窗口下,输入
chktrust.exe E:\myTest\08\Package\WebRTF.CAB


对我们的成果进行检验





此时成功,对了,这个“恭喜”的红字是我做上去的,可别到时候这俩字出不来还觉得奇怪

最后就是发布了

将这两个文件拷贝到WEB目录下进行测试,出现证书安装提示后按是安装即可




"

星期二, 十月 17, 2006

请教如何获得所有当前用户可以访问的,不是系统表的表名和列名? - ITPUB论坛

请教如何获得所有当前用户可以访问的,不是系统表的表名和列名? - ITPUB论坛: "SELECT OWNER ,TABLE_NAME,COLUMN_NAME
FROM all_col_comments
WHERE OWNER NOT IN('SYS','SYSTEM');"

如何有效地利用oracle的数据字典

ORACLE的数据字典是数据库的重要组成部分之一,它随着数据库的产生而产生, 随着数据库的变化而变化, 体现为sys用户下的一些表和视图。数据字典名称是大写的英文字符。

数据字典里存有用户信息、用户的权限信息、所有数据对象信息、表的约束条件、统计分析数据库的视图等。我们不能手工修改数据字典里的信息。很多时候,一般的ORACLE用户不知道如何有效地利用它。

  dictionary   全部数据字典表的名称和解释,它有一个同义词dict
dict_column   全部数据字典表里字段名称和解释

如果我们想查询跟索引有关的数据字典时,可以用下面这条SQL语句:

SQL>select * from dictionary where instr(comments,'index')>0;

如果我们想知道user_indexes表各字段名称的详细含义,可以用下面这条SQL语句:

SQL>select column_name,comments from dict_columns where table_name='USER_INDEXES';

依此类推,就可以轻松知道数据字典的详细名称和解释,不用查看ORACLE的其它文档资料了。

下面按类别列出一些ORACLE用户常用数据字典的查询使用方法。

一、用户

查看当前用户的缺省表空间
SQL>select username,default_tablespace from user_users;

查看当前用户的角色
SQL>select * from user_role_privs;

查看当前用户的系统权限和表级权限
SQL>select * from user_sys_privs;
SQL>select * from user_tab_privs;

二、表

查看用户下所有的表
SQL>select * from user_tables;

查看名称包含log字符的表
SQL>select object_name,object_id from user_objects where instr(object_name,'LOG')>0;

查看某表的创建时间
SQL>select object_name,created from user_objects where object_name=upper('&table_name');

查看某表的大小
SQL>select sum(bytes)/(1024*1024) as size(M) from user_segments where segment_name=upper('&table_name');

查看放在ORACLE的内存区里的表
SQL>select table_name,cache from user_tables where instr(cache,'Y')>0;

三、索引

查看索引个数和类别
SQL>select index_name,index_type,table_name from user_indexes order by table_name;
查看索引被索引的字段
SQL>select * from user_ind_columns where index_name=upper('&index_name');

查看索引的大小
SQL>select sum(bytes)/(1024*1024) as size(M) from user_segments where segment_name=upper('&index_name');

四、序列号

查看序列号,last_number是当前值
SQL>select * from user_sequences;

五、视图

查看视图的名称
SQL>select view_name from user_views;

查看创建视图的select语句
SQL>select view_name,text_length from user_views;
SQL>set long 2000;说明:可以根据视图的text_length值设定set long 的大小
SQL>select text from user_views where view_name=upper('&view_name');

六、同义词

查看同义词的名称
SQL>select * from user_synonyms;

七、约束条件

查看某表的约束条件
SQL>select constraint_name, constraint_type,search_condition, r_constraint_name from user_constraints where table_name = upper('&table_name');

SQL>select c.constraint_name,c.constraint_type,cc.column_name
from user_constraints c,user_cons_columns cc
where c.owner = upper('&table_owner') and c.table_name = upper('&table_name')
and c.owner = cc.owner and c.constraint_name = cc.constraint_name
order by cc.position;

八、存储函数和过程

查看函数和过程的状态
SQL>select object_name,status from user_objects where object_type='FUNCTION';
SQL>select object_name,status from user_objects where object_type='PROCEDURE';

查看函数和过程的源代码
SQL>select text from all_source where owner=user and name=upper('&plsql_name');

九、触发器

查看触发器

set long 50000;
set heading off;
set pagesize 2000;

select
'create or replace trigger ' ||
trigger_name || '' || chr(10)||
decode( substr( trigger_type, 1, 1 ),
'A', 'AFTER', 'B', 'BEFORE', 'I', 'INSTEAD OF' ) ||
chr(10) ||
triggering_event || chr(10) ||
'ON ' || table_owner || '.' ||
table_name || '' || chr(10) ||
decode( instr( trigger_type, 'EACH ROW' ), 0, null,
'FOR EACH ROW' ) || chr(10) ,
trigger_body
from user_triggers;

trixbox官方网站

http://www.trixbox.org/modules/smartsection/item.php?itemid=2/
构建中小企业语音电话平台

birt使用经验

http://blogger.org.cn/blog/more.asp?name=lhwork&id=16583
该工具主要是使用图形化的界面来处理itext报表问题

星期四, 十月 12, 2006

上机必读 二级上机考试部分评分方法

作者: 玲珑草草  来源:新浪  http://www.csai.cn  2005年11月22日
自动评分系统有客观、公正的优点,但也有死板的缺点,要想得到比较好的分数,应当考虑到机器 的这一特点。实际考试还有人工复查一项,由省级考试部门负责进行.但是人工复查如何进行,我们完全不得而知。因此我们下面的所有内容均不含人工复查内容, 仅从考试系统本身来进行分析和说明。

   我们从多次使用中摸索到的考生可能感兴趣的几点介绍如下:

   1. DOS操作题的评分比较复杂,评分系统在几次考试中标准似乎有一些变化。

   按系统的操作说明,只要命令正确即可得分,但实际情况并非如此。机器评分只根据结果,结果正确即得分,命令正确而结果不正确,不能得分。

   要注意使用规定的命令。比如考试系统不允许使用 deltree 命令,您如果习惯于用该命令来删除子目录,考试时将无法使用。

   本人曾做过试验,将结果做得完全符合要求,而不让考试系统看到我所作的事(比如使用另外的工具来做),结果照样得分;而使用正确的命令(即使与答案完全相同),而结果不正确(自然使用了"不正当"的方法),评分结果是不能得分。

   2. 程序修改题的评分大约有下面一些特点:

   有结果输出到文件中的,先检查结果文件。如果结果文件内容完全正确,给满分,并不再检查修改内容。

   结果没有输出到文件,或结果文件不正确的,逐个错误语句进行检查。分数平均分配(如果共有两个错误,每修正一个得15分;共有三个错误,则每修正一个得10分……)。

   检查标志为"***found***"。即机器死板地检查第X个"***found***"下面第N行(第X个错误语句应在的行)是否修改得和标准答案中的一个相同,相同则给分,否则不给分。

   例如:您的修改是完全正确的,与标准答案也完全一致。但是您插入了一个空行在"***found***"和修改了的行之间,这显然不影响程序的正确性,但自动评分系统却会认定您"修改错误"。

   更有甚者:如果您在程序的前面增加一个含有"***found***"的注释行,则不论您的程序修改得有多正确,评分系统会毫不留情地给您一个零分。

   程序修改题中还应注意考虑原程序作者的思路,所作改动应尽量小。

   这里有一个极端的例子:(1999年上半年二级BASIC)

'* 给定程序MODI1.BAS其功能是: 从键盘上每次输入两个100以下
'* 的正数分别赋给Y和Z(如不符合此条件的, 则重新输入),累加到累
'* 加器X中,直到X的值超过500为止。请找出程序中的错误,将程序调
'* 试出所需结果。
'* 注意: 不得增行或删行, 也不得更改程序的结构!

X = 0
DO
  DO
   t = 0
   INPUT "Y,Z="; Y, Z
   IF 0 < Y AND Y < 100 AND 0 < Z AND Z < 100 THEN
   t = 2
   ELSE
   PRINT "Out of Range! Input again"
   END IF
'**********found**********
  LOOP WHILE t <> 1
  X = X + Y + Z
'**********found**********
'WHILE X <> 500
PRINT "X="; X
END

   这里共有两个错误:第一个为条件错,第二个语句和条件均有错。因此第一个错误可只改动条件为 t<>2 或 t=0,整个语句为
    loop while t<>2 或者 loop while t=0
   第二个错误可改为
    LOOP WHILE X <= 500
   总之,这里的思路就是用 DO ... LOOP WHILE <条件> 语句。
   如果使用 do ... loop until <条件>,程序可以同样成立。如第一个错误改为
   loop until t=2
   运行结果完全相同。
   但是自动评分系统会认为您"修改错误!"扣掉您应得的15分!!!

   过去 C 语言的考试题目一般都出的较为严谨,很少有错误发生(但2002上半年的题虽然没发现什么严重错误,其质量实在不敢恭维)。但在2001年下半年中,仍有错判现象。举一例如下:
/*
给定程序MODI1.C中函数fun的功能是:先将在字符串s中的字符
按逆序存放到t串中,然后把s中的字符按正序连接到t串的后面。
例如:当s中的字符串为:"ABCDE"时,
则t中的字符串应为:"EDCBAABCDE"。
请改正程序中的错误,使它能得出正确的结果。
注意:不要改动main函数,不得增行或删行,也不得更改程序
的结构!
*/
#include <conio.h>
#include <stdio.h>
#include <string.h>

void fun (char *s, char *t)
{
/************found************/
  int i,sl;
// int i;
/* 由于C语言对书写格式不作要求,本错误如改为 int i, 其结果显然也是
   正确的。然而遗憾的是,自动批改系统此时会判错! */
  sl = strlen(s);
  for (i=0; i < sl; i++)
/************found************/
   t[ i ] = s[sl-i-1];
// t[i] = s[sl-i];
  for (i=0; i   t[sl+i] = s[i];
  t[2*sl] = '\0';
}

main()
{ char s[100], t[100];
  clrscr();
  printf("\nPlease enter string s:"); scanf("%s", s);
  fun(s, t);
  printf("The result is: %s\n", t);
}
  有的考生怕修改过程中忘记了原来的内容,把原来的内容用注释的方法保留在程序中(应该说,这是一个好的习惯)。比如把上面的内容写成
   t[ i ] = s[sl-i-1]; // t[ i ] = s[sl-i]; 或者
   t[ i ] = s[sl-i-1]; /* t[ i ] = s[sl-i]; */

   毫无疑问,这是正确的。但是评分系统竟然会判为"错误",不给分。考试系统会出现这种低级错误,倒是我以前未曾想到的,而且直至目前,这种错误仍未得到修正。

   因此考生必须注意把错误的内容全部删除掉。

  3. 编程题除去少部分类似填空或改错的BASIC程序外,均有结果输出到文件。自动评分时检查结果文件,如果结果文件内容正确,则给满分;如果没有结果文件 (即使程序是正确的,但没有运行),则得零分;如果应有若干个结果,则得分一般按结果数平均分配(比如应有两个结果,其中一个正确,另一个错误,则一般可 得40/2=20分)。在多数情况下,编程题往往不是满分就是零分。

   要注意的是,在FoxBASE编程题中,如果要生成新的数据库,只要库结构正确,哪怕其他都是错误的,也可得10到20分(随题目不同而有所变化)。因此做不到编程题的考生不可轻言放弃。

   部分BASIC的编程题实际上是填空题,因此是一个个空来改的,分数按空数平均分配。与程序修改题不同的是,它没有使用"***found***"标记,即使有添行等,也能正确进行评分。

   有的编程题对考生提出了一些限制,比如不许使用某个或某类函数,或不许使用某种方法等。在评分时,却很可能没有考虑如何限制这一点。我曾试过专门用"不 许"的方法去做题,在结果正确的情况下,照样得满分。看来考试系统也是"撑死胆大的,饿死胆小的"。当然,本人绝不鼓励考生不按要求做。如果你看了我的贴 子,去做一个"胆大的",得不到分可不要找我负责哟!!!

  首先,我讲一下考试评分系统的工作原理:

  考试评分系统是不看源程序。而是对你的源程序编译时所产生的.obj文件和.exe文件进行测试。测试分为两部份组成:

一、运行:完成输入、输出。
二、评分:与预期的结果对比。

运行:

  1、运行.exe文件(由你的源程序生成的),运行时,它会调用一个读函数,把in.dat文件里的测试数据读入主函数;一般二级有20组数据,三级、四是一大组数据(一篇英文、400个四位数、100个记录等)

  2、调用你所编写的函数,把这些数代入。

  3、调用写函数,把运行结果写入out.dat文件里。一般二级有20行结果(就是每组数据的运行结果),三级、四级有一大组结果(如一组字符流)或二到三个结果(如求平均值、公差、符合条件的数的个数等)

  以上这三个过程二级里是调用NONO函数完成,三级、四级是分别调用ReadDat()和WriteDat()函数来完成。

评分:

  运行test.exe文件,把out.dat文件里的内容与评分系统内的内容(预期结果)比较,在二级里,每对一行(就是这组数据的测试结果),给5分。

  三级、四级的就要看具体情况给分了,如:字符流处理的,那只要错一个小部分就0分,因为字符流是连续的。如果是数值处理的(有2-3个结果),那就是 每对一个结果结20-30分,但错了一个答案就很难及格了,因为数值处理很多数是互相关联的,如:求平均值,如果符合条件的数的个数错了,那平均值也一定 是错的。还有那个100个记录的,那它是以那一行上的内容是不是与预期的一样,每对一行给1分。(因为这个测试数据刚好一百行),这就是三级或四级里有: 0<成绩<100 分的原故。(很多人都说三级四级上机成绩不是0分就是一百分,这个观点是错的)

  以上文件名、函数名应以源程序调用时的名为准。

  由上述可知:一个题如果通过编译、能运行就一定有分,那是错的,因为一个题,如果你一点都不做(放空),那是一定能通过编译和运行的。但这时,out.dat文件为空,如果你编写了程序,而运行的结果都是错的,那和空是一样的。这样是不能得分的。

  还有是有人说我做了题,通过了编译,也出了"正确"结果,那为什么会不及格呢?是不是考试系统有问题,这个可能很小,一般是因为你的程序有问题,如以前考网上有一个题:

求一子字符串在主字符串出现的次数;
例如:子串:go
主串:good yjgocel liugo ygoygong
结果为: 5

以下是两个人的回复:

一、int fun(char *str,char *s)
{
int m=0;
char *p=s;
while(*str!='\0')
{ if(*str==*p)
{ str++;
p++;
} /*两字符相同就同时移动指针。*/
else
{p=s;
str++ ; /*不同只移动一个指针,并把另一指针指向初始位置 */
}
if(*p=='\0') /*如果是连续的同时移动到了后一个字符串尾,就计一次数 */
{ m++;
p=s ;
}
}
return m;
}

二、int fun(char *str,char *s)
{
int i,j,m=0;
for(i=0;i<strlen(str);) {
for(j=0;j<strlen(s);)
if(str[i]==s[j]) {
i++;
j++;
}
else {
i++;
break;
}
if(j==strlen(s))
m++;
}
return m;
}

  其实这两个答案,对于上面的那个主串和子串也许是可以的,但,如果主串是aaa aa,子串是aa,那上面这两个程序就不行了,因为,aa在aaa aa里出现了3次,而不是2次,字符串是可以嵌套出现的,而测试数据里的数据一般什么情况都有,而象这种嵌套的多,这就是他认为自已程序是对的,而结果是 不及格的原故。

  以上两位如果是考生的话,他们肯定会说他们的程序是绝对对的,是评分系统问题。

正确的应这样写:

fun(char *str,char *s)
{char str1[10]="";
int i,k=0;
for(;*str;str++)
{for(i=0;i<strlen(s);i++)
str1[i]=*(str+i);
if(!strcmp(str1,s)) k++;
}
return k;
}

  下面我再讲一个测试上述程序的实例:

  主串为:ababcabcacbab。子串为abc或ab。有兴趣的考生可以上机试一下看对不对

星期一, 十月 09, 2006

共享软件防破解的实用招法

1、检测主程序大小,防止破解补丁之类:


Function TForm1.GesSelfSf: integer;
var
F: file of byte;
begin
Filemode:=0;
Assignfile(F,'.\FileName.exe');
Reset(f);
Result:=Filesize(F);
Closefile(F);
end;


2、检测创建日期和时间,让破解补丁实效:

Function TForm1.FinDate:String;
var
t:TDate;
begin
ShortDateFormat:='yyyy-mm-dd';
t:=FileDateToDateTime(FileAge('FileName.exe'));
Result:=DateToStr(t);
end;

3、注册码加密函数嵌入数学函数,增加破解难度:
(略)

4、必要时自己删除自己(主程序):



procedure TForm1.Funll;
var
hModule:THandle;
buff:array[0..255]of Char;
hKernel32:THandle;
pExitProcess,pDeleteFileA,pUnmapViewOfFileointer;
begin
hModule:=GetModuleHandle(nil);
GetModuleFileName(hModule, buff, sizeof(buff));
CloseHandle(THandle(4));
hKernel32:=GetModuleHandle('KERNEL32');
pExitProcess:=GetProcAddress(hKernel32, 'ExitProcess');
pDeleteFileA:=GetProcAddress(hKernel32, 'DeleteFileA');
pUnmapViewOfFile:=GetProcAddress(hKernel32, 'UnmapViewOfFile');
asm
LEA EAX, buff
PUSH 0
PUSH 0
PUSH EAX
PUSH pExitProcess
PUSH hModule
PUSH pDeleteFileA
PUSH pUnmapViewOfFile
RET
end;
begin
Funll;
end;
end;



   具体怎么使用,那要看你自己的意愿了和需要了。反正我是这样做的,我的软件ADSL拨号计时器只在很早版本上出过注册机,后来的v3.70出过破解补丁 ——其实只是破掉了启动时提示注册的对话框,实质上根本没破解。用了上述的着法以后,到现在的v5.28版本,再没有过什么破解补丁或注册机。

  如果现在的v5.28版本谁能破解,将立即公布程序源码。


附:注册机破解法的原理以及应对方法

认识注册机破解法
  顾名思义,写注册机来破解软件注册的方法,就是模仿你的注册码生成算法或者逆向注 册码验证算法而写出来的和你一模一样的注册机。如果被写出注册机,你的软件只好免费了。或者你必须更换算法,但以前注过册的合法用户都得被迫更换注册码了。

   Cracker要写注册机必须详细研究你软件的验证模块,这必须先将你的软件脱壳,再反汇编或者用调试器跟踪。市面上许多加壳和保护软件都吹嘘不可能被 脱壳,但到目前为止没有一个软件兑现了自己的诺言。由于CPU最终执行的都是有效指令,所以等你的程序自解压完成后再从内存中Dump出来就可以实现脱 壳。因此不要在壳上面花很多功夫,因为没有这个必要。

第一招:制造假相

  反汇编和调试器跟踪都是不可能防止的,因为所有的Win32程序都必须通过API来调用Windows系统中的关键DLL的(如Kernel32.dll、GDI32.dll等),然而API是可以Hook的。我们只能从自己的代码着手来保护我们的劳动果实了。

   为了自己调试和以后维护的方便,我们一般采用有意义的名字给我们的函数命名,可这给了Cracker可乘之机。例如这样的函数是什么意思大家应该一目了 然吧?IsRegistered(),IsLicensed(),LicenseVerify(),CheckReg()……这样Cracker就可以轻 松地从数千个函数中找到他的目标——你的注册码校验函数!而且破解Delphi编写的软件还有一件TMG小组的破解利器——DeDe。它可以轻松地看到你 软件里的Form、Unit和函数名,还可以反汇编一部分代码,更可以和Win32DASM合作反汇编更多的代码,对Delphi编出的程序威胁极大。

  为了不给Cracker创造温馨舒适的破解环境,要故意混乱(Obfuscate)我们的代码,将软件中所有的函数名全部替换成随机 生成的函数名。例如Func_3dfsa_fs32zlfv这个函数是什么意思?恐怕只有天知道了。网上有现成的代码混乱器,按你使用的编程语言的种 类可以找到一些。但要注意,只有当你要发布软件时才使用它,而且一定注意备份源代码。否则,当你看不懂你自己的代码时就着急了:)

第二招:用公匙,并改名

   另外,一定要使用公开密匙算法保护你的软件。RSA、DSA和El Gamal之类的算法都可以从网上找到。但注意:将你算法单元中所有涉及到算法名称的字符串全部改名。避免被Cracker发现你用的算法而模仿写出注册 机来!你还可以张冠李戴,明明用的DSA,将名字全部替换成RSA。

  其它算法,如对称算法和Hash算法也要注意改名,否则这样:


  EncryptedCode = Blowfish(MD5(UserName),MD5(Key));


  //你的加密算法,使用了Blowfish(对称算法)和MD5(Hash算法)

  虽然那些Cracker不了解Blowfish和MD5算法的原理,也不会逆向推测它们,但他们了解你的校验算法的流程和算法名,便可马上从网上找到类似的Blowfish和MD5算法包,从而模拟你的软件仿造出注册机。

  如果你用不常见的,算法如Skipjack(NASA美国航天局标准算法)、LOKI、3-WAY、Safer之类不出名但保密程度很高的算法,并且全部改名,这样就会伤透他们脑筋了。

   当然,最好把Hash算法也全部改名,会给他们制造更多的困难。但注意,MD5和SHA之类的Hash初始值会被Cracker从内存中找到,这样他就 知道你用的Hash了。所以建议同时使用MD5的变形算法Ripe-MD(RMD)128或160或其它的Hash,如Tiger、Haval等算法。

第三招:阻止别人调试

  还有一点,调试器对我们的威胁很大,我们不会让Cracker们舒舒服服地使用SoftICE、TRW或OllyDbg来调试我们的程序。除了常用的MeItICE方法外,这里我给一个笔者写的方法:

  {检查自己的进程的父进程是否为Explorer.exe,否则是被调试器加载了}

  {不过注意,控制台程序的父进程在WinNT下是Cmd.exe!}

  {注意加载TlHelp32.pas单元}


  procedure CheckParentProc;
  var //检查自己的进程的父进程
  Pn: TProcesseNtry32;
  sHandle:THandle;
  H,ExplProc,ParentProc:Hwnd;
  Found:Boolean;
  Buffer:array[0..1023]of Char;
   Path:string;
  begin
  H:= 0;
  ExplProc:= 0;
  ParentProc:= 0;
  //得到Windows的目录
  SetString(Path,Buffer)
  GetWindowsDirectory(Buffer,Sizeof(Buffer)- 1));
  Path:= UpperCase(Path)+ '\EX PLORER.EXE';//得到Explorer的路径
  //得到所有进程的列表快照
  sHandle:= CreateToolHelp32Snap Shot(TH32CS_SNAPALL,0);
  Found:= Process32First(sHandle,Pn);//查找进程
  while Found do //遍历所有进程
  begin
  if Pn.szExeFile = ParamStr(0)then //自己的进程
  begin
  ParentProc:= Pn.th32ParentProcessID://得到父进程的进程ID
  //父进程的句柄
  H:= OpenProcess(PRO CESS_ALL_ACCESS,True,Pn.th32Parent ProcessID);
  end
  else if UpperCase(Pn.szExeFile)= Path then
  ExplProc:= Pn.th32ProcessID;//Ex plorer的PID
  Found:= Process32Next(sHandle,Pn);//查找下一个
  end;
  //父进程不是Explorer,是调试器……
  if ParentProc <> ExplProc then
  begin
  TerminateProcess(H,0);//杀之!除之而后快也! :)
  //你还可以加上其它什么死机代码来消遣消遣这位可爱的Cracker:)
   end�
  end


  你可以在Delphi或者VC中试试,这样可以把Delphi和VC杀掉了,因为你现在用的是Delphi和VC的内置调试器来运行你的程序。调试的时候你还是把它的注释删掉吧,发布时别忘记激活哟!

第四招:保护字符串

   最后一个问题,这也是一个非常重要的问题:保护你的字符串!字符串在注册模块中非常重要!当一个富有经验的Cracker破解你的软件时,首先做的就是 窃取你的字符串。比如他会输入错误的注册码,得到你关于错误注册码的提示,通常是"无效的注册码,请重新输入!"或者"Invalid key(please input again)"等等,然后用OllyDbg进行断点调试或者用WinDASM、IDA Pro等静态分析工具在被他脱壳后的程序中查找那个字符串,找到后进行分析。因此,请一定加密你的字符串! 使用时再临时解密出来,而且要尽量少使用消息提示框,避免被Cracker找到漏洞。加密字符串不需要太复杂的算法,随便找一个快速的对称算法就可以了。

  最后提醒大家一句,不要在加密上花太多的功夫!你应该把更多的时间和精力都用来完善你的软件,这样会更合算。借用一位前辈的话来忠告 大家吧:花点时间考虑你自己的软件,看看它是否值得保护?如果没人用你的软件,保护也就没有意义了,不要过高估计你的软件"对世界的重要性


星期日, 九月 10, 2006

oracle 942错误

Imp正常,但Exp却无法完成
==============================
前日晚上准备对刚刚启用的Unix环境Oracle数据库做一次Exp逻辑备份,报如下错误:
EXP-00056: ORACLE error 942 encountered
ORA-00942: table or view does not exist
EXP-00000: Export terminated unsuccessfully
感觉很奇怪,因为数据库中的数据就是通过Imp转移来的,怎么这里的Exp不能用了呢?上网搜了一下,发现这个问题还并不鲜见,找到一篇文章解 释为Oracle本身的一个bug,发生在从920升级到9206以后,因此建议在升级后用Exp命令来检验升级是否真正成功,但事已至此,我又检查了测 试环境和开发环境,发现都有这样的我问题,于是根据作者提供的方法,执行了/rdbms/admin/catpatch.sql脚本,然后手动编译了 sys schema下的所有package,再使用Exp命令导出数据就可以了,具体命令如下:
SQL>shutdown immediate;
SQL>startup migrate;
SQL>@?/rdbms/admin/catpatch.sql
SQL>shutdown immediate;
SQL>startup;

========================

XP-00056: 遇到 ORACLE 错误 942

ORA-00942: 表或视图不存在

EXP-00000: 导出终止失败

解决办法:报此错误并不是因为你的权限不够,也不是因为你的命令有误,而是ORACLE本身的问题,是由于你的客户端版本低于服务器端的版本造成的。最好的办法就是装一个与服务器端版本相同客户端。要不就到服务器端去导吧。


星期五, 九月 08, 2006

在Oracle中存取BLOB对象实现文件的上传和下载

最近做一个J2EE项目,需要在JSP页面实现对文件的上传和下载。很早以前就知道JDBC支持大对象(LOB)的存取,以为很容易,做起来才发现问题多多,读了一大堆文章,反而没有什么头绪了。正如一位网友文章所讲:“…网络上的教程99%都是行不通的,连SUN自己的文档都一直错误……”,实际情况大致如此了。

存取BLOB出现这么多问题,我认为大半是由数据库开发商、应用服务器商在JDBC驱动上的不兼容性带来的。而实际应用中,每个人的开发运行环境不同,使得某个网友的solution没有办法在别人的应用中重现,以至于骂声一片。至于为什么会不兼容、有哪些问题,我没有时间去弄清,这里只说说我们怎样解决了问题的。

基于上述原因,先列出我们的开发环境,免得有人配不出来,招人唾骂。

数据库 Oracle 9i

应用服务器 BEA Weblogic 8.11

开发工具 JBuilder X

在JSP实现文件Upload/Download可以分成这样几块 :文件提交到形成InputSteam;InputSteam以BLOB格式入库;数据从库中读出为InputSteam;InputStream输出到页面形成下载文件。先说BLOB吧。

1. BLOB入库

(1) 直接获得数据库连接的情况

这是Oracle提供的标准方式,先插入一个空BLOB对象,然后Update这个空对象。代码如下:

//得到数据库连接(驱动包是weblogic的,没有下载任何新版本)

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection con = DriverManager.getConnection(

"jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");

//处理事务

con.setAutoCommit(false);

Statement st = con.createStatement();

//插入一个空对象

st.executeUpdate("insert into BLOBIMG values(103,empty_blob())");

//用for update方式锁定数据行

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 for update");

if (rs.next()) {

//得到java.sql.Blob对象,然后Cast为oracle.sql.BLOB

oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1).;

//到数据库的输出流

OutputStream outStream = blob.getBinaryOutputStream();

//这里用一个文件模拟输入流

File file = new File("d:\\proxy.txt");

InputStream fin = new FileInputStream(file);

//将输入流写到输出流

byte[] b = new byte[blob.getBufferSize()];

int len = 0;

while ( (len = fin.read(b)) != -1) {

outStream.write(b, 0, len);

//blob.putBytes(1,b);

}







//依次关闭(注意顺序)

fin.close();

outStream.flush();

outStream.close();

con.commit();

con.close();

(2) 通过JNDI获得数据库连接

在Weblogic中配置到Oracle的JDBC Connection Pool和DataSource,绑定到Context中,假定绑定名为”orads”。

为了得到数据库连接,做一个连接工厂,主要代码如下:

Context context = new InitialContext();

ds = (DataSource) context.lookup("orads");

return ds.getConnection();

以下是BLOB写入数据库的代码:



Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

st.executeUpdate("insert into BLOBIMG values(103,empty_blob())");

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 for update");

if (rs.next()) {

//上面代码不变

//这里不能用oracle.sql.BLOB,会报ClassCast 异常

weblogic.jdbc.vendor.oracle.OracleThinBlobblob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob(1);

//以后代码也不变

OutputStream outStream = blob.getBinaryOutputStream();

File file = new File("d:\\proxy.txt");

InputStream fin = new FileInputStream(file);

byte[] b = new byte[blob.getBufferSize()];

int len = 0;

while ( (len = fin.read(b)) != -1) {

outStream.write(b, 0, len);

}

fin.close();

outStream.flush();

outStream.close();

con.commit();

con.close();



2. BLOB出库

从数据库中读出BLOB数据没有上述由于连接池的不同带来的差异,只需要J2SE的标准类java.sql.Blob就可以取得输出流(注意区别java.sql.Blob和oracle.sql.BLOB)。代码如下:

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

//这里的SQL语句不再需要”for update”

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 ");

if (rs.next()) {

java.sql.Blob blob = rs.getBlob(1);



InputStream ins = blob.getBinaryStream();



//用文件模拟输出流

File file = new File("d:\\output.txt");

OutputStream fout = new FileOutputStream(file);

//下面将BLOB数据写入文件

byte[] b = new byte[1024];

int len = 0;

while ( (len = ins.read(b)) != -1) {

fout.write(b, 0, len);

}

//依次关闭

fout.close();

ins.close();

con.commit();

con.close();



3. 从JSP页面提交文件到数据库

(1) 提交页面的代码如下:

<form action="handle.jsp" enctype="multipart/form-data" method="post" >

<input type="hidden" name="id" value="103"/>

<input type="file" name="fileToUpload">

<input type="submit" value="Upload">

</form>



(2) 由于JSP没有提供文件上传的处理能力,只有使用第三方的开发包。网络上开源的包有很多,我们这里选择Apache Jakarta的FileUpload,在http://jakarta.apache.org/commons/fileupload/index.html 可以得到下载包和完整的API文档。法奥为adajspException

处理页面(handle.jsp)的代码如下

<%

boolean isMultipart = FileUpload.isMultipartContent(request);

if (isMultipart) {

// 建立一个新的Upload对象

DiskFileUpload upload = new DiskFileUpload();

// 设置上载文件的参数

//upload.setSizeThreshold(yourMaxMemorySize);

//upload.setSizeMax(yourMaxRequestSize);

String rootPath = getServletConfig().getServletContext().getRealPath("/") ;

upload.setRepositoryPath(rootPath+\\uploads);



// 分析request中的传来的文件流,返回Item的集合,

// 轮询Items,如果不是表单域,就是一个文件对象。

List items = upload.parseRequest(request);

Iterator iter = items.iterator();

while (iter.hasNext()) {

FileItem item = (FileItem) iter.next();

//如果是文件对象

if (!item.isFormField()) {







//如果是文本文件,可以直接显示

//out.println(item.getString());







//将上载的文件写到服务器的\WEB-INF\webstart\下,文件名为test.txt

//File uploadedFile = new File(rootPath+"\\uploads\\test.txt");

//item.write(uploadedFile);







//下面的代码是将文件入库(略):

//注意输入流的获取



InputStream uploadedStream = item.getInputStream();



}

//否则是普通表单

else{

out.println("FieldName: " + item.getFieldName()+"<br>");

out.println("Value: "+item.getString()+"<br>"); }

}

}

%>







4. 从数据库读取BLOB然后保存到客户端磁盘上

这段代码有点诡异,执行后将会弹出文件保存对话窗口,将BLOB数据读出保存到本地文件。全文列出如下:

<%@ page contentType="text/html; charset=GBK" import="java.io.*" import="java.sql.*" import="test.global.ConnectionFactory"%><%

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 ");

if (rs.next()) {

Blob blob = rs.getBlob(1);

InputStream ins = blob.getBinaryStream();

response.setContentType("application/unknown");

response.addHeader("Content-Disposition", "attachment; filename="+"output.txt");

OutputStream outStream = response.getOutputStream();

byte[] bytes = new byte[1024];

int len = 0;

while ((len=ins.read(bytes))!=-1) {

outStream.write(bytes,0,len);

}

ins.close();

outStream.close();

outStream = null;

con.commit();

con.close();

}

%>

注意,在<% … … %>之外,绝对不能有任何字符,空格或回车都不行,不然会导致outputStream出错,对非ASCII输出文件来说就是格式错误不可读。

在Oracle中存取BLOB对象实现文件的上传和下载_站长技术站 -

最近做一个J2EE项目,需要在JSP页面实现对文件的上传和下载。很早以前就知道JDBC支持大对象(LOB)的存取,以为很容易,做起来才发现问题多多,读了一大堆文章,反而没有什么头绪了。正如一位网友文章所讲:“…网络上的教程99%都是行不通的,连SUN自己的文档都一直错误……”,实际情况大致如此了。

存取BLOB出现这么多问题,我认为大半是由数据库开发商、应用服务器商在JDBC驱动上的不兼容性带来的。而实际应用中,每个人的开发运行环境不同,使得某个网友的solution没有办法在别人的应用中重现,以至于骂声一片。至于为什么会不兼容、有哪些问题,我没有时间去弄清,这里只说说我们怎样解决了问题的。

基于上述原因,先列出我们的开发环境,免得有人配不出来,招人唾骂。

数据库 Oracle 9i

应用服务器 BEA Weblogic 8.11

开发工具 JBuilder X

JSP实现文件Upload/Download可以分成这样几块 :文件提交到形成InputSteamInputSteamBLOB格式入库;数据从库中读出为InputSteamInputStream输出到页面形成下载文件。先说BLOB吧。

1. BLOB入库

(1) 直接获得数据库连接的情况

这是Oracle提供的标准方式,先插入一个空BLOB对象,然后Update这个空对象。代码如下:

//得到数据库连接(驱动包是weblogic的,没有下载任何新版本)

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection con = DriverManager.getConnection(

"jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");

//处理事务

con.setAutoCommit(false);

Statement st = con.createStatement();

//插入一个空对象

st.executeUpdate("insert into BLOBIMG values(103,empty_blob())");

//for update方式锁定数据行

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 for update");

if (rs.next()) {

//得到java.sql.Blob对象,然后Castoracle.sql.BLOB

oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1).;

//到数据库的输出流

OutputStream outStream = blob.getBinaryOutputStream();

//这里用一个文件模拟输入流

File file = new File("d:\\proxy.txt");

InputStream fin = new FileInputStream(file);

//将输入流写到输出流

byte[] b = new byte[blob.getBufferSize()];

int len = 0;

while ( (len = fin.read(b)) != -1) {

outStream.write(b, 0, len);

//blob.putBytes(1,b);

}

//依次关闭(注意顺序)

fin.close();

outStream.flush();

outStream.close();

con.commit();

con.close();

(2) 通过JNDI获得数据库连接

Weblogic中配置到OracleJDBC Connection PoolDataSource,绑定到Context中,假定绑定名为”orads”

为了得到数据库连接,做一个连接工厂,主要代码如下:

Context context = new InitialContext();

ds = (DataSource) context.lookup("orads");

return ds.getConnection();

以下是BLOB写入数据库的代码:

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

st.executeUpdate("insert into BLOBIMG values(103,empty_blob())");

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 for update");

if (rs.next()) {

//上面代码不变

//这里不能用oracle.sql.BLOB,会报ClassCast 异常

weblogic.jdbc.vendor.oracle.OracleThinBlobblob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob(1);

//以后代码也不变

OutputStream outStream = blob.getBinaryOutputStream();

File file = new File("d:\\proxy.txt");

InputStream fin = new FileInputStream(file);

byte[] b = new byte[blob.getBufferSize()];

int len = 0;

while ( (len = fin.read(b)) != -1) {

outStream.write(b, 0, len);

}

fin.close();

outStream.flush();

outStream.close();

con.commit();

con.close();

2. BLOB出库

从数据库中读出BLOB数据没有上述由于连接池的不同带来的差异,只需要J2SE的标准类java.sql.Blob就可以取得输出流(注意区别java.sql.Bloboracle.sql.BLOB)。代码如下:

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

//这里的SQL语句不再需要”for update”

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 ");

if (rs.next()) {

java.sql.Blob blob = rs.getBlob(1);

InputStream ins = blob.getBinaryStream();

//用文件模拟输出流

File file = new File("d:\\output.txt");

OutputStream fout = new FileOutputStream(file);

//下面将BLOB数据写入文件

byte[] b = new byte[1024];

int len = 0;

while ( (len = ins.read(b)) != -1) {

fout.write(b, 0, len);

}

//依次关闭

fout.close();

ins.close();

con.commit();

con.close();

3. JSP页面提交文件到数据库

(1) 提交页面的代码如下:

name="fileToUpload">

value="Upload">

(2) 由于JSP没有提供文件上传的处理能力,只有使用第三方的开发包。网络上开源的包有很多,我们这里选择Apache JakartaFileUpload,在http://jakarta.apache.org/commons/fileupload/index.html 可以得到下载包和完整的API文档。法奥为adajspException

处理页面(handle.jsp)的代码如下

<%

boolean isMultipart = FileUpload.isMultipartContent(request);

if (isMultipart) {

// 建立一个新的Upload对象

DiskFileUpload upload = new DiskFileUpload();

// 设置上载文件的参数

//upload.setSizeThreshold(yourMaxMemorySize);

//upload.setSizeMax(yourMaxRequestSize);

String rootPath = getServletConfig().getServletContext().getRealPath("/") ;

upload.setRepositoryPath(rootPath+\\uploads);

// 分析request中的传来的文件流,返回Item的集合,

// 轮询Items,如果不是表单域,就是一个文件对象。

List items = upload.parseRequest(request);

Iterator iter = items.iterator();

while (iter.hasNext()) {

FileItem item = (FileItem) iter.next();

//如果是文件对象

if (!item.isFormField()) {

//如果是文本文件,可以直接显示

//out.println(item.getString());

//将上载的文件写到服务器的\WEB-INF\webstart\下,文件名为test.txt

//File uploadedFile = new File(rootPath+"\\uploads\\test.txt");

//item.write(uploadedFile);

//下面的代码是将文件入库(略):

//注意输入流的获取

InputStream uploadedStream = item.getInputStream();

}

//否则是普通表单

else{

out.println("FieldName: " + item.getFieldName()+"
");

out.println("Value: "+item.getString()+"
");
}

}

}

%>

4. 从数据库读取BLOB然后保存到客户端磁盘上

这段代码有点诡异,执行后将会弹出文件保存对话窗口,将BLOB数据读出保存到本地文件。全文列出如下:

<%@ page contentType="text/html; charset=GBK" import="java.io.*" import="java.sql.*" import="test.global.ConnectionFactory"%><%

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

ResultSet rs = st.executeQuery(

"select contents from BLOBIMG where id=103 ");

if (rs.next()) {

Blob blob = rs.getBlob(1);

InputStream ins = blob.getBinaryStream();

response.setContentType("application/unknown");

response.addHeader("Content-Disposition", "attachment; filename="+"output.txt");

OutputStream outStream = response.getOutputStream();

byte[] bytes = new byte[1024];

int len = 0;

while ((len=ins.read(bytes))!=-1) {

outStream.write(bytes,0,len);

}

ins.close();

outStream.close();

outStream = null;

con.commit();

con.close();

}

%>

注意,在<% … … %>之外,绝对不能有任何字符,空格或回车都不行,不然会导致outputStream出错,对非ASCII输出文件来说就是格式错误不可读。



">
<$BlogItemTitle$>

动态SQL和PL/SQL的EXECUTE IMMEDIATE选项--ORACLE

EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当容易编码.尽管DBMS_SQL仍然可用,但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。
  
  使用技巧
  
  1. EXECUTE IMMEDIATE将不会提交一个DML事务执行,应该显式提交
  如果通过EXECUTE IMMEDIATE处理DML命令,那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分. 如果通过EXECUTE IMMEDIATE处理DDL命令,它提交所有以前改变的数据
  
  2. 不支持返回多行的查询,这种交互将用临时表来存储记录(参照例子如下)或者用REF cursors.
  
  3. 当执行SQL语句时,不要用分号,当执行PL/SQL块时,在其尾部用分号.
  
  4. 在Oracle手册中,未详细覆盖这些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能给你带来方便.
  
  5. 对于Forms开发者,当在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
  
  EXECUTE IMMEDIATE用法例子
  
  1. 在PL/SQL运行DDL语句
  
   begin
   execute immediate 'set role all';
   end;
  
  2. 给动态语句传值(USING 子句)
  
   declare
   l_depnam varchar2(20) := 'testing';
   l_loc  varchar2(10) := 'Dubai';
   begin
   execute immediate 'insert into dept values (:1, :2, :3)'
    using 50, l_depnam, l_loc;
   commit;
   end;
  
  3. 从动态语句检索值(INTO子句)
  
   declare
   l_cnt  varchar2(20);
   begin
   execute immediate 'select count(1) from emp'
    into l_cnt;
   dbms_output.put_line(l_cnt);
   end;
  
  4. 动态调用例程.例程中用到的绑定变量参数必须指定参数类型.黓认为IN类型,其它类型必须显式指定
  
   declare
   l_routin  varchar2(100) := 'gen2161.get_rowcnt';
   l_tblnam  varchar2(20) := 'emp';
   l_cnt   number;
   l_status  varchar2(200);
   begin
   execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
    using in l_tblnam, out l_cnt, in out l_status;
  
   if l_status != 'OK' then
     dbms_output.put_line('error');
   end if;
   end;
  
  5. 将返回值传递到PL/SQL记录类型;同样也可用%rowtype变量
  
   declare
   type empdtlrec is record (empno number(4),
                ename varchar2(20),
                deptno number(2));
   empdtl empdtlrec;
   begin
   execute immediate 'select empno, ename, deptno ' ||
            'from emp where empno = 7934'
    into empdtl;
   end;
  
  6. 传递并检索值.INTO子句用在USING子句前
  
   declare
   l_dept  pls_integer := 20;
   l_nam   varchar2(20);
   l_loc   varchar2(20);
   begin
   execute immediate 'select dname, loc from dept where deptno = :1'
    into l_nam, l_loc
    using l_dept ;
   end;
  
  7. 多行查询选项.对此选项用insert语句填充临时表,用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.
  
   declare
   l_sal  pls_integer := 2000;
   begin
   execute immediate 'insert into temp(empno, ename) ' ||
            '     select empno, ename from emp ' ||
            '     where sal > :1'
    using l_sal;
   commit;
   end;
  
  对于处理动态语句,EXECUTE IMMEDIATE比以前可能用到的更容易并且更高效.当意图执行动态语句时,适当地处理异常更加重要.应该关注于捕获所有可能的异常.

">
<$BlogItemTitle$>

Oracle自定义函数——f_henry_GetStringLength_

Oracle下的Length()函数不能区分中英文,只能得到字符数而不能得到字节数,很多时候插入string到字段中时总要先进行一次检查,防止 string长度超过了字段定义的长度,一般大家都是把这个检测放到应用程序中执行,用我写的这个小函数就可以实现在数据库服务器端对要插入的字段进行检 测。

create or replace function f_henry_GetStringLength(pv_String in varchar2) return integer is
Result integer;
i number;
begin
Result:=0;
if length(pv_String)=0 then
return(Result);
end if;
for i in 1 .. length(pv_String) loop
if ascii(substr(pv_String,i,1))<256 then
Result:=Result+1;
else
Result:=Result+2;
end if;
end loop;
return(Result);
end f_henry_GetStringLength;

/*************************以下是测试***************************/

SQL> select length('啊$@oii发大幅') from dual;

LENGTH('啊$@OII发大幅')
-----------------------
9

SQL> select f_henry_GetStringLength('啊$@oii发大幅') from dual;

F_HENRY_GETSTRINGLENGTH('啊$@O
------------------------------
13



">
<$BlogItemTitle$>

求在9i的存储过程中二维数组的完整例子及说明table ,varrry ,recor都行.

---------------------- 单维数组 ------------------------

DECLARE
TYPE emp_ssn_array IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;

best_employees emp_ssn_array;
worst_employees emp_ssn_array;

BEGIN
best_employees(1) := '123456';
best_employees(2) := '888888';

worst_employees(1) := '222222';
worst_employees(2) := '666666';

FOR i IN 1..best_employees.count LOOP
DBMS_OUTPUT.PUT_LINE('i=' ¦ ¦ i ¦ ¦ ', best_employees= ' ¦ ¦best_employees(i)
¦ ¦ ', worst_employees= ' ¦ ¦worst_employees(i));
END LOOP;

END;

---------------------- 多维数组 ------------------------
DECLARE

TYPE emp_type IS RECORD
( emp_id number,
emp_name string(80),
emp_gender string(80));

TYPE emp_type_array IS TABLE OF
emp_type INDEX BY BINARY_INTEGER;

emp_rec_array emp_type_array;
emp_rec emp_type;

BEGIN
emp_rec.emp_id := 300000000;
emp_rec.emp_name := 'Barbara';
emp_rec.emp_gender := 'Female';

emp_rec_array(1) := emp_rec;

emp_rec.emp_id := 300000008;
emp_rec.emp_name := 'Rick';
emp_rec.emp_gender := 'Male';

emp_rec_array(2) := emp_rec;

FOR i IN 1..emp_rec_array.count LOOP
DBMS_OUTPUT.PUT_LINE('i=' ¦ ¦i
¦ ¦', emp_id =' ¦ ¦emp_rec_array(i).emp_id
¦ ¦', emp_name =' ¦ ¦emp_rec_array(i).emp_name
¦ ¦', emp_gender = ' ¦ ¦emp_rec_array(i).emp_gender);
END LOOP;

END;
-------------- Result --------------
i=1, emp_id =300000000, emp_name =Barbara, emp_gender = Female
i=2, emp_id =300000008, emp_name =Rick, emp_gender = Male

">
<$BlogItemTitle$>

oracle错误信息大全

ORACLE的这类错误在ORALCE的文档中有详细说明,但原因及措施说明不详细,本文当着重说明如何解决这类错误。

  1、ORA-12571、ORA-03113、ORA-03114、ORA-01041

  特征:客户端(代理或应用服务器)有时报这类断连错误

  原因:如果偶尔出现一次,则可能为网络原因或用户异常中止,如果经常出现则为客户端与服务端的字符集不一致。

  措施:如果偶尔出现,可在服务端的协议配置文件PROTOCOL.ORA中增加一行

  TCP.NODELAY=YES;

  如果经常出现,则为客户端与服务端字符集不一致或网络原因。

  客户端的字符集在注册表里定义:    HKEY__LOCAL__MACHINE/SOFTWARE/ORACLE/NLS__LANG

  在客户端注册表中的TCP参数项中设置   TCPMAXDATARETRANSMITIONS=20。

  2、ORA-01000

  特征:达到会话允许的最大游标

  原因:达到会话允许的最大游标数

  措施:有两种解决方法:

  (1)在初始化文件INIT.ORA文件中增加OPEN_CURSORS的数量,一般要求大于200。

  (2)在应用级,与开发工具有关,例如设置MAXOPEN_CURSORS等。

  3、ORA-01545

  特征:某个回滚段不可用

  原因:(1)当使回滚段ONLINE时,但回滚段不可用,例如回滚段所在表空间OFFLINE;

  (2) 当使回滚段ONLINE时,但回滚段已ONLINE,例如回滚段被使用两次,典型的案例如OPS方式时,回滚段不能公有;

  (3)删除回滚段时,回滚段中有活动的事务;

  措施:(1)确保回滚段可

  (2)从初始化文件INIT.ORA的参数ROLLBACK)SEGMENTS中删除指定的回滚段。

  (3)可以将回滚段所在表空间删除,取消UNDO事务

  4、ORA-0165x

  特征:表空间没有足够的空间供分配

  原因:表空间已满;存储参数不合理,NEXT太小;没有连续的区间

  措施:如果表空间已满,则需为表空间增加文件;如果存储参数不合理,则需增加INITIAL和NEXT;如果没有连续的区间,需要合并空闲的表空间。

  查看空间碎片用DBA_FREE_SPACE

  5、ORA-01555

  特征:当前会话无法读到以前版本的数据

  原因:原因很多,主要原因有下列:回滚段太小、太少;回滚段冲突;交叉提交(FETCH_ACROSS)

  措施:增加回滚段数量;

  6、ORA-04031

  特征:共享池内存区内存不够,或产生内存碎片

  原因:当试图装载一个大包时或执行一个较大的存储过程时,而共享池没有连续的内存空间。

  措施:如果是内存不够,则增加SHARE)POOL_SIZE;

  如果是内存碎片,执行alter system flush share_pool

  7、ORA-04091

  特征:触发器工作不正常

  原因:一个行触发读取或修改变化的表(正在修改、插入)时,产生这种错误。

  措施:检查触发器脚本,保证引用完整性

  8、ORA-01242、ORA-01113

  特征:介质故障导致数据库宕机

  原因:介质故障。

  措施:检查硬件故障;修改dbshut脚本,将其中的STARTUP命令修改为:

  Startup open recover

  Alter database open



">
<$BlogItemTitle$>

ORACLE函数大全

SQL中的单记录函数
1.ASCII
返回与指定的字符对应的十进制数;
SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual;

A A ZERO SPACE
--------- --------- --------- ---------
65 97 48 32


2.CHR
给出整数,返回对应的字符;
SQL> select chr(54740) zhao,chr(65) chr65 from dual;

ZH C
-- -
赵 A

3.CONCAT
连接两个字符串;
SQL> select concat('010-','88888888')||'转23' 高乾竞电话 from dual;

高乾竞电话
----------------
010-88888888转23

4.INITCAP
返回字符串并将字符串的第一个字母变为大写;
SQL> select initcap('smith') upp from dual;

UPP
-----
Smith


5.INSTR(C1,C2,I,J)
在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
C1 被搜索的字符串
C2 希望搜索的字符串
I 搜索的开始位置,默认为1
J 出现的位置,默认为1
SQL> select instr('oracle traning','ra',1,2) instring from dual;

INSTRING
---------
9


6.LENGTH
返回字符串的长度;
SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal)) from gao.nchar_tst;

NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL))
------ ------------ ---------------- ------------ --------- --------------------
高乾竞 3 北京市海锭区 6 9999.99 7



7.LOWER
返回字符串,并将所有的字符小写
SQL> select lower('AaBbCcDd')AaBbCcDd from dual;

AABBCCDD
--------
aabbccdd


8.UPPER
返回字符串,并将所有的字符大写
SQL> select upper('AaBbCcDd') upper from dual;

UPPER
--------
AABBCCDD



9.RPAD和LPAD(粘贴字符)
RPAD 在列的右边粘贴字符
LPAD 在列的左边粘贴字符
SQL> select lpad(rpad('gao',10,'*'),17,'*')from dual;

LPAD(RPAD('GAO',1
-----------------
*******gao*******
不够字符则用*来填满


10.LTRIM和RTRIM
LTRIM 删除左边出现的字符串
RTRIM 删除右边出现的字符串
SQL> select ltrim(rtrim(' gao qian jing ',' '),' ') from dual;

LTRIM(RTRIM('
-------------
gao qian jing


11.SUBSTR(string,start,count)
取子字符串,从start开始,取count个
SQL> select substr('13088888888',3,8) from dual;

SUBSTR('
--------
08888888


12.REPLACE('string','s1','s2')
string 希望被替换的字符或变��
s1 被替换的字符串
s2 要替换的字符串
SQL> select replace('he love you','he','i') from dual;

REPLACE('H
----------
i love you


13.SOUNDEX
返回一个与给定的字符串读音相同的字符串
SQL> create table table1(xm varchar(8));
SQL> insert into table1 values('weather');
SQL> insert into table1 values('wether');
SQL> insert into table1 values('gao');

SQL> select xm from table1 where soundex(xm)=soundex('weather');

XM
--------
weather
wether


14.TRIM('s' from 'string')
LEADING 剪掉前面的字符
TRAILING 剪掉后面的字符
如果不指定,默认为空格符

15.ABS
返回指定值的绝对值
SQL> select abs(100),abs(-100) from dual;

ABS(100) ABS(-100)
--------- ---------
100 100


16.ACOS
给出反余弦的值
SQL> select acos(-1) from dual;

ACOS(-1)
---------
3.1415927


17.ASIN
给出反正弦的值
SQL> select asin(0.5) from dual;

ASIN(0.5)
---------
.52359878


18.ATAN
返回一个数字的反正切值
SQL> select atan(1) from dual;

ATAN(1)
---------
.78539816


19.CEIL
返回大于或等于给出数字的最小整数
SQL> select ceil(3.1415927) from dual;

CEIL(3.1415927)
---------------
4


20.COS
返回一个给定数字的余弦
SQL> select cos(-3.1415927) from dual;

COS(-3.1415927)
---------------
-1


21.COSH
返回一个数字反余弦值
SQL> select cosh(20) from dual;

COSH(20)
---------
242582598


22.EXP
返回一个数字e的n次方根
SQL> select exp(2),exp(1) from dual;

EXP(2) EXP(1)
--------- ---------
7.3890561 2.7182818


23.FLOOR
对给定的数字取整数
SQL> select floor(2345.67) from dual;

FLOOR(2345.67)
--------------
2345


24.LN
返回一个数字的对数值
SQL> select ln(1),ln(2),ln(2.7182818) from dual;

LN(1) LN(2) LN(2.7182818)
--------- --------- -------------
0 .69314718 .99999999


25.LOG(n1,n2)
返回一个以n1为底n2的对数
SQL> select log(2,1),log(2,4) from dual;

LOG(2,1) LOG(2,4)
--------- ---------
0 2


26.MOD(n1,n2)
返回一个n1除以n2的余数
SQL> select mod(10,3),mod(3,3),mod(2,3) from dual;

MOD(10,3) MOD(3,3) MOD(2,3)
--------- --------- ---------
1 0 2


27.POWER
返回n1的n2次方根
SQL> select power(2,10),power(3,3) from dual;

POWER(2,10) POWER(3,3)
----------- ----------
1024 27


28.ROUND和TRUNC
按照指定的精度进行舍入
SQL> select round(55.5),round(-55.4),trunc(55.5),trunc(-55.5) from dual;

ROUND(55.5) ROUND(-55.4) TRUNC(55.5) TRUNC(-55.5)
----------- ------------ ----------- ------------
56 -55 55 -55


29.SIGN
取数字n的符号,大于0返回1,小于0返回-1,等于0返回0
SQL> select sign(123),sign(-100),sign(0) from dual;

SIGN(123) SIGN(-100) SIGN(0)
--------- ---------- ---------
1 -1 0


30.SIN
返回一个数字的正弦值
SQL> select sin(1.57079) from dual;

SIN(1.57079)
------------
1


31.SIGH
返回双曲正弦的值
SQL> select sin(20),sinh(20) from dual;

SIN(20) SINH(20)
--------- ---------
.91294525 242582598


32.SQRT
返回数字n的根
SQL> select sqrt(64),sqrt(10) from dual;

SQRT(64) SQRT(10)
--------- ---------
8 3.1622777


33.TAN
返回数字的正���值
SQL> select tan(20),tan(10) from dual;

TAN(20) TAN(10)
--------- ---------
2.2371609 .64836083


34.TANH
返回数字n的双曲正切值
SQL> select tanh(20),tan(20) from dual;

TANH(20) TAN(20)
--------- ---------
1 2.2371609



35.TRUNC
按照指定的精度截取一个数
SQL> select trunc(124.1666,-2) trunc1,trunc(124.16666,2) from dual;

TRUNC1 TRUNC(124.16666,2)
--------- ------------------
100 124.16



36.ADD_MONTHS
增加或减去月份
SQL> select to_char(add_months(to_date('199912','yyyymm'),2),'yyyymm') from dual;

TO_CHA
------
200002
SQL> select to_char(add_months(to_date('199912','yyyymm'),-2),'yyyymm') from dual;

TO_CHA
------
199910


37.LAST_DAY
返回日期的最后一天
SQL> select to_char(sysdate,'yyyy.mm.dd'),to_char((sysdate)+1,'yyyy.mm.dd') from dual;

TO_CHAR(SY TO_CHAR((S
---------- ----------
2004.05.09 2004.05.10
SQL> select last_day(sysdate) from dual;

LAST_DAY(S
----------
31-5月 -04


38.MONTHS_BETWEEN(date2,date1)
给出date2-date1的月份
SQL> select months_between('19-12月-1999','19-3月-1999') mon_between from dual;

MON_BETWEEN
-----------
9
SQL>selectmonths_between(to_date('2000.05.20','yyyy.mm.dd'),to_date('2005.05.20','yyyy.mm.dd')) mon_betw from dual;

MON_BETW
---------
-60


39.NEW_TIME(date,'this','that')
给出在this时区=other时区的日期和时间
SQL> select to_char(sysdate,'yyyy.mm.dd hh24:mi:ss') bj_time,to_char(new_time
2 (sysdate,'PDT','GMT'),'yyyy.mm.dd hh24:mi:ss') los_angles from dual;

BJ_TIME LOS_ANGLES
------------------- -------------------
2004.05.09 11:05:32 2004.05.09 18:05:32


40.NEXT_DAY(date,'day')
给出日期date和星期x之后计算下一个星期的日期
SQL> select next_day('18-5月-2001','星期五') next_day from dual;

NEXT_DAY
----------
25-5月 -01



41.SYSDATE
用来得到系统的当前日期
SQL> select to_char(sysdate,'dd-mm-yyyy day') from dual;

TO_CHAR(SYSDATE,'
-----------------
09-05-2004 星期日
trunc(date,fmt)按照给出的要求将日期截断,如果fmt='mi'表示保留分,截断秒
SQL> select to_char(trunc(sysdate,'hh'),'yyyy.mm.dd hh24:mi:ss') hh,
2 to_char(trunc(sysdate,'mi'),'yyyy.mm.dd hh24:mi:ss') hhmm from dual;

HH HHMM
------------------- -------------------
2004.05.09 11:00:00 2004.05.09 11:17:00



42.CHARTOROWID
将字符数据类型转换为ROWID类型
SQL> select rowid,rowidtochar(rowid),ename from scott.emp;

ROWID ROWIDTOCHAR(ROWID) ENAME
------------------ ------------------ ----------
AAAAfKAACAAAAEqAAA AAAAfKAACAAAAEqAAA SMITH
AAAAfKAACAAAAEqAAB AAAAfKAACAAAAEqAAB ALLEN
AAAAfKAACAAAAEqAAC AAAAfKAACAAAAEqAAC WARD
AAAAfKAACAAAAEqAAD AAAAfKAACAAAAEqAAD JONES


43.CONVERT(c,dset,sset)
将源字符串 sset从一个语言字符集转换到另一个目的dset字符集
SQL> select convert('strutz','we8hp','f7dec') "conversion" from dual;

conver
------
strutz


44.HEXTORAW
将一个十六进制构成的字符串转换为二进制


45.RAWTOHEXT
将一个二进制构成的字符串转换为十六进制



46.ROWIDTOCHAR
将ROWID数据类型转换为字符类型



47.TO_CHAR(date,'format')
SQL> select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YY
-------------------
2004/05/09 21:14:41



48.TO_DATE(string,'format')
将字符串转化为ORACLE中的一个日期


49.TO_MULTI_BYTE
将字符串中的单字节字符转化为多字节字符
SQL> select to_multi_byte('高') from dual;

TO
--



50.TO_NUMBER
将给出的字符转换为数字
SQL> select to_number('1999') year from dual;

YEAR
---------
1999


51.BFILENAME(dir,file)
指定一个外部二进制文件
SQL>insert into file_tb1 values(bfilename('lob_dir1','image1.gif'));


52.CONVERT('x','desc','source')
将x字段或变量的源source转换为desc
SQL> select sid,serial#,username,decode(command,
2 0,'none',
3 2,'insert',
4 3,
5 'select',
6 6,'update',
7 7,'delete',
8 8,'drop',
9 'other') cmd from v$session where type!='background';

SID SERIAL# USERNAME CMD
--------- --------- ------------------------------ ------
1 1 none
2 1 none
3 1 none
4 1 none
5 1 none
6 1 none
7 1275 none
8 1275 none
9 20 GAO select
10 40 GAO none


53.DUMP(s,fmt,start,length)
DUMP函数以fmt指定的内部数字格式返回一个VARCHAR2类型的值
SQL> col global_name for a30
SQL> col dump_string for a50
SQL> set lin 200
SQL> select global_name,dump(global_name,1017,8,5) dump_string from global_name;

GLOBAL_NAME DUMP_STRING
------------------------------ --------------------------------------------------
ORACLE.WORLD Typ=1 Len=12 CharacterSet=ZHS16GBK: W,O,R,L,D


54.EMPTY_BLOB()和EMPTY_CLOB()
这两个函数都是用来对大数据类型字段进行初始化操作的函数


55.GREATEST
返回一组表达式中的最大值,即比较字符的编码大小.
SQL> select greatest('AA','AB','AC') from dual;

GR
--
AC
SQL> select greatest('啊','安','天') from dual;

GR
--



56.LEAST
返回一组表达式中的最小��
SQL> select least('啊','安','天') from dual;

LE
--



57.UID
返回标识当前用户的唯一整数
SQL> show user
USER 为"GAO"
SQL> select username,user_id from dba_users where user_id=uid;

USERNAME USER_ID
------------------------------ ---------
GAO 25



58.USER
返回当前用户的名字
SQL> select user from dual;

USER
------------------------------
GAO


59.USEREVN
返回当前用户环境的信息,opt可以是:
ENTRYID,SESSIONID,TERMINAL,ISDBA,LABLE,LANGUAGE,CLIENT_INFO,LANG,VSIZE
ISDBA 查看当前用户是否是DBA如果是则返回true
SQL> select userenv('isdba') from dual;

USEREN
------
FALSE
SQL> select userenv('isdba') from dual;

USEREN
------
TRUE
SESSION
返回会话标志
SQL> select userenv('sessionid') from dual;

USERENV('SESSIONID')
--------------------
152
ENTRYID
返回会话人口标志
SQL> select userenv('entryid') from dual;

USERENV('ENTRYID')
------------------
0
INSTANCE
返回当前INSTANCE的标志
SQL> select userenv('instance') from dual;

USERENV('INSTANCE')
-------------------
1
LANGUAGE
返回当前环境变量
SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
LANG
返回当前环境的语言的缩写
SQL> select userenv('lang') from dual;

USERENV('LANG')
----------------------------------------------------
ZHS
TERMINAL
返回用户的终端或机器的标志
SQL> select userenv('terminal') from dual;

USERENV('TERMINA
----------------
GAO
VSIZE(X)
返回X的大小(字节)数
SQL> select vsize(user),user from dual;

VSIZE(USER) USER
----------- ------------------------------
6 SYSTEM



60.AVG(DISTINCT|ALL)
all表示对所有的值求平均值,distinct只对不同的值求平均值
SQLWKS> create table table3(xm varchar(8),sal number(7,2));
语句已处理。
SQLWKS> insert into table3 values('gao',1111.11);
SQLWKS> insert into table3 values('gao',1111.11);
SQLWKS> insert into table3 values('zhu',5555.55);
SQLWKS> commit;

SQL> select avg(distinct sal) from gao.table3;

AVG(DISTINCTSAL)
----------------
3333.33

SQL> select avg(all sal) from gao.table3;

AVG(ALLSAL)
-----------
2592.59


61.MAX(DISTINCT|ALL)
求最大值,ALL表示对所有的值求最大值,DISTINCT表示对不同的值求最大值,相同的只取一次
SQL> select max(distinct sal) from scott.emp;

MAX(DISTINCTSAL)
----------------
5000


62.MIN(DISTINCT|ALL)
求最小值,ALL表示对所有的值求最小值,DISTINCT表示对不同的值求最小值,相同的只取一次
SQL> select min(all sal) from gao.table3;

MIN(ALLSAL)
-----------
1111.11


63.STDDEV(distinct|all)
求标准差,ALL表示对所有的值求标准差,DISTINCT表示只对不同的值求标准差
SQL> select stddev(sal) from scott.emp;

STDDEV(SAL)
-----------
1182.5032

SQL> select stddev(distinct sal) from scott.emp;

STDDEV(DISTINCTSAL)
-------------------
1229.951



64.VARIANCE(DISTINCT|ALL)
求协方差

SQL> select variance(sal) from scott.emp;

VARIANCE(SAL)
-------------
1398313.9


65.GROUP BY
主要用来对一组数进行统计
SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno;

DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
10 3 8750
20 5 10875
30 6 9400



66.HAVING
对分组统计再加限制条件
SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno having count(*)>=5;

DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
20 5 10875
30 6 9400
SQL> select deptno,count(*),sum(sal) from scott.emp having count(*)>=5 group by deptno ;

DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
20 5 10875
30 6 9400


67.ORDER BY
用于对查询到的结果进行排序输出
SQL> select deptno,ename,sal from scott.emp order by deptno,sal desc;

DEPTNO ENAME SAL
--------- ---------- ---------
10 KING 5000
10 CLARK 2450
10 MILLER 1300
20 SCOTT 3000
20 FORD 3000
20 JONES 2975
20 ADAMS 1100
20 SMITH 800
30 BLAKE 2850
30 ALLEN 1600
30 TURNER 1500
30 WARD 1250
30 MARTIN 1250
30 JAMES 950

">
<$BlogItemTitle$>

星期四, 九月 07, 2006

关于firefox对style.display属性的解释问题

最近在制作网站的过程中出现了一个问题,就是firefox下对遇style.display执行结果和ie不一样,真实郁闷,多方查找资料,终于发现了问题,代码如下:


<html>
<head>
<title>display</title>
<script type="text/javascript">
<!--
function show(){
var msg=document.getElementById("showmsg");
if(msg.style.display=="none"){
msg.style.display="block";
}
else
msg.style.display="none";
}
//-->
</script>
</head>
<body>
<table width="100%" >
<tr width="100%">
<td width="100%">
<font style="cursor:hand;" onclick="show()">
ddddddddddddddddd
</font>
</td>
</tr>
<tr id="showmsg" style="display:none;">
<td>dsffdafa</td>
</tr>
<tr><td>电风扇扩大发洒家艰苦</td></tr>
</table>
</body>
<html>



上面的HTML页面在IE和Firefox中的执行结果不同:
1)"display:none;"后面的内容站用原来块的内容空间//但Firefox好象把这个和"visibility:hidden;"一样处理的
2)"display:block;"将隐藏的内容显示出来//Firefox好象是为其重新开辟内容显示空间

最后正确有效的处理结果
发现个问题:
当将javascript脚本改下就可以了:
<script type="text/javascript">
<!--
function show(){
var msg=document.getElementById("showmsg");
if(msg.style.display=="none")
{ msg.style.display="";//即将此句有原来的msg.style.display="block";改为:msg.style.display=""; }
else
msg.style.display="none"; } //-->
</script>
呵呵~,搞定!

">
<$BlogItemTitle$>