The important thing in life is to have a great aim , and the determination

常用链接

统计

IT技术链接

保险相关

友情链接

基金知识

生活相关

最新评论

#

模式与框架

1.什么是模式?
模式,即pattern,其实就是解决某一类问题的方法论,你把解决某类问题的方法总结归纳到理论高度,这就是模式。
 
Alexander给出的经典定义是:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需再重复相同的工作。

模式有不同的领域,建筑领域有建筑模式,软件设计领域也有设计模式。当一个领域逐渐成熟的时候,自然会出现很多模式。

什么是框架?

框架,即framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单地说就是使用别人搭建好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。

2。为什么要用模式?

因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。

为什么要使用框架?

因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础的工作,你只需要集中精力完成系统业务逻辑设计。而且框架一般是成熟,稳健的,它可以处理系统很多细节的问题,比如,事物处理,安全性,数据流控制等问题。还有框架一般都是经过很多人使用,所以结构很好,所以扩展性也好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。

框架一般处在低层的应用平台(如J2EE)和高层业务逻辑之间的中间层。

软件为什么要分层?

为了实现“高内聚、低耦合”。把问题划分开来各个解决,易于控制,易于扩展,易于分配资源。。。



posted @ 2008-10-10 09:39 鸿雁 阅读(238) | 评论 (0)编辑 收藏

Javascript中最常用的55个经典技巧

1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键
<table border oncontextmenu=return(false)><td>no</table> 可用于Table

2. <body onselectstart="return false"> 取消选取、防止复制

3. onpaste="return false" 不准粘贴

4. oncopy="return false;" oncut="return false;" 防止复制

5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标

6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夹中显示出你的图标


7. <input style="ime-mode:disabled"> 关闭输入法


8. 永远都会带着框架
<script language="JavaScript"><!--
if (window == top)top.location.href = "frames.htm"; //frames.htm为框架网页
// --></script>


9. 防止被人frame
<SCRIPT LANGUAGE=JAVASCRIPT><!--
if (top.location != self.location)top.location=self.location;
// --></SCRIPT>


10. 网页将不能被另存为
<noscript><*** src="/*.html>";</***></noscript>


11. <input type=button value="/查看网页源代码
onclick="window.location = "view-source:"+ "http://www.pconline.com.cn"">
12.删除时确认
<a href=""javascript :if(confirm("确实要删除吗?"))location="boos.asp?&areyou=删除&page=1"">删除</a>


13. 取得控件的绝对位置
//Javascript
<script language="Javascript">
function getIE(e){
var t=e.offsetTop;
var l=e.offsetLeft;
while(e=e.offsetParent){
t+=e.offsetTop;
l+=e.offsetLeft;
}
alert("top="+t+"/nleft="+l);
}
</script>
//VBScript
<script language="VBScript"><!--
function getIE()
dim t,l,a,b
set a=document.all.img1
t=document.all.img1.offsetTop
l=document.all.img1.offsetLeft
while a.tagName<>"BODY"
set a = a.offsetParent
t=t+a.offsetTop
l=l+a.offsetLeft
wend
msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置"
end function
--></script>


14. 光标是停在文本框文字的最后
<script language="javascript">
function cc()
{
var e = event.srcElement;
var r =e.createTextRange();
r.moveStart("character",e.value.length);
r.collapse(true);
r.select();
}
</script>
<input type=text name=text1 value="123" onfocus="cc()">


15. 判断上一页的来源
javascript :
document.referrer


16. 最小化、最大化、关闭窗口
<object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Minimize"></object>
<object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Maximize"></object>
<OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
<PARAM NAME="Command" value="/Close"></OBJECT>
<input type=button value="/最小化 onclick=hh1.Click()>
<input type=button value="/blog/最大化 onclick=hh2.Click()>
<input type=button value=关闭 onclick=hh3.Click()>
本例适用于IE


17.屏蔽功能键Shift,Alt,Ctrl
<script>
function look(){
if(event.shiftKey)
alert("禁止按Shift键!"); //可以换成ALT CTRL
}
document.onkeydown=look;
</script>


18. 网页不会被缓存
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
或者<META HTTP-EQUIV="expires" CONTENT="0">


19.怎样让表单没有凹凸感?
<input type=text style="""border:1 solid #000000">

<input type=text style="border-left:none; border-right:none; border-top:none; border-bottom:
1 solid #000000"></textarea>


20.<div><span>&<layer>的区别?
<div>(division)用来定义大段的页面元素,会产生转行
<span>用来定义同一行内的元素,跟<div>的唯一区别是不产生转行
<layer>是ns的标记,ie不支持,相当于<div>


21.让弹出窗口总是在最上面:
<body onblur="this.focus();">


22.不要滚动条?
让竖条没有:
<body style="overflow:scroll;overflow-y:hidden">
</body>
让横条没有:
<body style="overflow:scroll;overflow-x:hidden">
</body>
两个都去掉?更简单了
<body scroll="no">
</body>


23.怎样去掉图片链接点击后,图片周围的虚线?
<a href="#" onFocus="this.blur()"><img src="/logo.jpg" border=0></a>


24.电子邮件处理提交表单
<form name="form1" method="post" action=mailto:****@***.com
enctype="text/plain">
<input type=submit>
</form>


25.在打开的子窗口刷新父窗口的代码里如何写?
window.opener.location.reload()


26.如何设定打开页面的大小
<body onload="top.resizeTo(300,200);">
打开页面的位置<body onload="top.moveBy(300,200);">


27.在页面中如何加入不是满铺的背景图片,拉动页面时背景图不动
<STYLE>
body
{background-image:url(/logo.gif); background-repeat:no-repeat;
background-position:center;background-attachment: fixed}
</STYLE>


28. 检查一段字符串是否全由数字组成
<script language="Javascript"><!--
function checkNum(str){return str.match(//D/)==null}
alert(checkNum("1232142141"))
alert(checkNum("123214214a1"))
// --></script>


29. 获得一个窗口的大小
document.body.clientWidth; document.body.clientHeight


30. 怎么判断是否是字符
if (/[^/x00-/xff]/g.test(s)) alert("含有汉字");
else alert("全是字符");


31.TEXTAREA自适应文字行数的多少
<textarea rows=1 name=s1 cols=27 onpropertychange
="this.style.posHeight=this.scrollHeight">
</textarea>


32. 日期减去天数等于第二个日期
<script language=Javascript>
function cc(dd,dadd)
{
//可以加上错误处理
var a = new Date(dd)
a = a.valueOf()
a = a - dadd * 24 * 60 * 60 * 1000
a = new Date(a)
alert(a.getFullYear() + "年" + (a.getMonth() + 1) + "月" + a.getDate() + "日")
}
cc("12/23/2002",2)
</script>


33. 选择了哪一个Radio
<HTML><script language="vbscript">
function checkme()
for each ob in radio1
if ob.checked then
window.alert ob.value
next
end function
</script><BODY>
<INPUT name="radio1" type="radio" value="/style" checked>Style
<INPUT name="radio1" type="radio" value="/blog/barcode">Barcode
<INPUT type="button" value="check" onclick="checkme()">
</BODY></HTML>


34.脚本永不出错
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide
function killErrors() {
return true;
}
window.onerror = killErrors;
// -->
</SCRIPT>


35.ENTER键可以让光标移到下一个输入框
<input onkeydown="if(event.keyCode==13)event.keyCode=9">


36. 检测某个网站的链接速度:
把如下代码加入<body>区域中:
<script language=Javascript>
tim=1
setInterval("tim++",100)
b=1
var autourl=new Array()
autourl[1]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.njcatv.net"
autourl[2]="javacool.3322.net"
autourl[3]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.sina.com.cn"
autourl[4]="www.nuaa.edu.cn"
autourl[5]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.cctv.com"
function butt(){
***("<form name=autof>")
for(var i=1;i<autourl.length;i++)
***("<input type=text name=txt"+i+" size=10 value="/测试中……> =》<input type=text
name=url"+i+" size=40> =》<input type=button value="/blog/GO
onclick=window.open(this.form.url"+i+".value)><br>")
***("<input type=submit value=刷新></form>")
}
butt()
function auto(url){
document.forms[0]["url"+b].value=url
if(tim>200)
{document.forms[0]["txt"+b].value="/链接超时"}
else
{document.forms[0]["txt"+b].value="/blog/时间"+tim/10+"秒"}
b++
}
function run(){for(var i=1;i<autourl.length;i++)***("<img src=http://"+autourl+"/"+Math.random()+" width=1 height=1
onerror=auto("http://"+autourl+"")>")}
run()</script>


37. 各种样式的光标
auto :标准光标
default :标准箭头
hand :手形光标
wait :等待光标
text :I形光标
vertical-text :水平I形光标
no-drop :不可拖动光标
not-allowed :无效光标
help :?帮助光标
all-scroll :三角方向标
move :移动标
crosshair :十字标
e-resize
n-resize
nw-resize
w-resize
s-resize
se-resize
sw-resize


38.页面进入和退出的特效
进入页面<meta http-equiv="Page-Enter" content="revealTrans(duration=x, transition=y)">
推出页面<meta http-equiv="Page-Exit" content="revealTrans(duration=x, transition=y)">  
这个是页面被载入和调出时的一些特效。duration表示特效的持续时间,以秒为单位。transition表示使用哪种特效,取值为1-23:
  0 矩形缩小
  1 矩形扩大
  2 圆形缩小
  3 圆形扩大
  4 下到上刷新
  5 上到下刷新
  6 左到右刷新
  7 右到左刷新
  8 竖百叶窗
  9 横百叶窗
  10 错位横百叶窗
  11 错位竖百叶窗
  12 点扩散
  13 左右到中间刷新
  14 中间到左右刷新
  15 中间到上下
  16 上下到中间
  17 右下到左上
  18 右上到左下
  19 左上到右下
  20 左下到右上
  21 横条
  22 竖条
  23 以上22种随机选择一种


39.在规定时间内跳转
<META http-equiv=V="REFRESH" content="5;URL=http://www.51js.com">


40.网页是否被检索
<meta name="ROBOTS" content="属性值">
  其中属性值有以下一些:
  属性值为"all": 文件将被检索,且页上链接可被查询;
  属性值为"none": 文件不被检索,而且不查询页上的链接;
  属性值为"index": 文件将被检索;
  属性值为"follow": 查询页上的链接;
  属性值为"noindex": 文件不检索,但可被查询链接;
  属性值为"nofollow": 文件不被检索,但可查询页上的链接。


41、email地址的分割
把如下代码加入<body>区域中
<a href="mailto:webmaster@sina.com">webmaster@sina.com</a>


42、流动边框效果的表格
把如下代码加入<body>区域中
<SCRIPT>
l=Array(6,7,8,9,'a','b','b','c','d','e','f')
Nx=5;Ny=35
t="<table border=0 cellspacing=0 cellpadding=0 height="+((Nx+2)*16)+"><tr>"
for(x=Nx;x<Nx+Ny;x++)
t+="<td width=16 id=a_mo"+x+"> </td>"
t+="</tr><tr><td width=10 id=a_mo"+(Nx-1)+"> </td><td colspan="+(Ny-2)+" rowspan="+(Nx)+"> </td><td width=16 id=a_mo"+(Nx+Ny)+"></td></tr>"
for(x=2;x<=Nx;x++)
t+="<tr><td width=16 id=a_mo"+(Nx-x)+"> </td><td width=16 id=a_mo"+(Ny+Nx+x-1)+"> </td></tr>"
t+="<tr>"
for(x=Ny;x>0;x--)
t+="<td width=16 id=a_mo"+(x+Nx*2+Ny-1)+"> </td>"
***(t+"</tr></table>")
var N=Nx*2+Ny*2
function f1(y){
for(i=0;i<N;i++){
c=(i+y)%20;if(c>10)c=20-c
document.all["a_mo"+(i)].bgColor=""""#0000"+l[c]+l[c]+"'"}
y++
setTimeout('f1('+y+')','1')}
f1(1)
</SCRIPT>


43、JavaScript主页弹出窗口技巧
窗口中间弹出
<script>
window.open("http://www.cctv.com","","width=400,height=240,top="+(screen.availHeight-240)/2+",left="+(screen.availWidth-400)/2);
</script>
============
<html>
<head>
<script language="LiveScript">
function WinOpen() {
    msg=open("","DisplayWindow","toolbar=no,directories=no,menubar=no");
    msg.***("<HEAD><TITLE>哈 罗!</TITLE></HEAD>");
    msg.***("<CENTER><H1>酷 毙 了!</H1><h2>这 是<B>JavaScript</B>所 开 的 视 窗!</h2></CENTER>");
}
</script>
</head>
<body>
<form>
<input type="button" name="Button1" value="Push me" onclick="WinOpen()">
</form>
</body>
</html>
==============
一、在下面的代码中,你只要单击打开一个窗口,即可链接到赛迪网。而当你想关闭时,只要单击一下即可关闭刚才打开的窗口。
  代码如下:
  <SCRIPT language="JavaScript">
  <!--
  function openclk() {
  another=open('1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>http://www.ccidnet.com','NewWindow');
  }
  function closeclk() {
  another.close();
  }
  //-->
  </SCRIPT>
  <FORM>
  <INPUT TYPE="BUTTON" NAME="open" value="/打开一个窗口" onClick="openclk()">
  <BR>
  <INPUT TYPE="BUTTON" NAME="close" value="/blog/关闭这个窗口" onClick="closeclk()">
  </FORM>
  二、上面的代码也太静了,为何不来点动感呢?如果能给页面来个降落效果那该多好啊!
  代码如下:
  <script>
  function drop(n) {
  if(self.moveBy){
  self.moveBy (0,-900);
  for(i = n; i > 0; i--){
  self.moveBy(0,3);
  }
  for(j = 8; j > 0; j--){
  self.moveBy(0,j);
  self.moveBy(j,0);
  self.moveBy(0,-j);
  self.moveBy(-j,0);
  }
  }
  }
  </script>
  <body onLoad="drop(300)">
  三、讨厌很多网站总是按照默认窗口打开,如果你能随心所欲控制打开的窗口那该多好。
  代码如下:
  <SCRIPT LANGUAGE="JavaScript">
  <!-- Begin
  function popupPage(l, t, w, h) {
  var windowprops = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes" +
  ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
  var URL = "http://www.80cn.com";
  popup = window.open(URL,"MenuPopup",windowprops);
  }
  // End -->
  </script>
  <table>
  <tr>
  <td>
  <form name=popupform>
  <pre>
  打开页面的参数<br>
  离开左边的距离: <input type=text name=left size=2 maxlength=4> pixels
  离开右边的距离: <input type=text name=top size=2 maxlength=4> pixels
  窗口的宽度: <input type=text name=width size=2 maxlength=4> pixels
  窗口的高度: <input type=text name=height size=2 maxlength=4> pixels
  </pre>
  <center>
  <input type=button value="打开这个窗口!" onClick="popupPage(this.form.left.value, this.form.top.value, this.form.width.value,
this.form.height.value)">
  </center>
  </form>
  </td>
  </tr>
  </table>你只要在相对应的对话框中输入一个数值即可,将要打开的页面的窗口控制得很好。


44、页面的打开移动
把如下代码加入<body>区域中
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
for (t = 2; t > 0; t--) {
for (x = 20; x > 0; x--) {
for (y = 10; y > 0; y--) {
parent.moveBy(0,-x);
   }
}
for (x = 20; x > 0; x--) {
for (y = 10; y > 0; y--) {
parent.moveBy(0,x);
   }
}
for (x = 20; x > 0; x--) {
for (y = 10; y > 0; y--) {
parent.moveBy(x,0);
   }
}
for (x = 20; x > 0; x--) {
for (y = 10; y > 0; y--) {
parent.moveBy(-x,0);
     }
   }
}
//-->
//   End -->
</script>


45、显示个人客户端机器的日期和时间
<script language="LiveScript">
<!-- Hiding
   today = new Date()
   ***("现 在 时 间 是: ",today.getHours(),":",today.getMinutes())
   ***("<br>今 天 日 期 为: ", today.getMonth()+1,"/",today.getDate(),"/",today.getYear());
// end hiding contents -->
</script>


46、自动的为你每次产生最後修改的日期了:
<html>
<body>
This is a simple HTML- page.
<br>
Last changes:
   <script language="LiveScript">
   <!--   hide script from old browsers
     ***(document.lastModified)
   // end hiding contents -->
   </script>
</body>
</html>


47、不能为空和邮件地址的约束:
<html>
<head>
<script language="JavaScript">
<!-- Hide
function test1(form) {
   if (form.text1.value == "")
     alert("您 没 写 上 任 何 东 西, 请 再 输 入 一 次 !")
   else {
    alert("嗨 "+form.text1.value+"! 您 已 输 入 完 成 !");
   }
}
function test2(form) {
   if (form.text2.value == "" ||
       form.text2.value.indexOf('@', 0) == -1)
         alert("这 不 是 正 确 的 e-mail address! 请 再 输 入 一 次 !");
   else alert("您 已 输 入 完 成 !");
}
// -->
</script>
</head>
<body>
<form name="first">
Enter your name:<br>
<input type="text" name="text1">
<input type="button" name="button1" value="输 入 测 试" onClick="test1(this.form)">
<P>
Enter your e-mail address:<br>
<input type="text" name="text2">
<input type="button" name="button2" value="输 入 测 试" onClick="test2(this.form)">
</body>


48、跑马灯
<html>
<head>
<script language="JavaScript">
<!-- Hide
var scrtxt="怎麽样 ! 很酷吧 ! 您也可以试试."+"Here goes your message the visitors to your
page will "+"look at for hours in pure fascination...";
var lentxt=scrtxt.length;
var width=100;
var pos=1-width;
function scroll() {
   pos++;
   var scroller="";
   if (pos==lentxt) {
     pos=1-width;
   }
   if (pos<0) {
     for (var i=1; i<=Math.abs(pos); i++) {
       scroller=scroller+" ";}
     scroller=scroller+scrtxt.substring(0,width-i+1);
   }
   else {
     scroller=scroller+scrtxt.substring(pos,width+pos);
   }
   window.status = scroller;
   setTimeout("scroll()",150);
   }
//-->
</script>
</head>
<body onLoad="scroll();return true;">
这里可显示您的网页 !
</body>
</html>


49、在网页中用按钮来控制前页,后页和主页的显示。
<html>
<body>
<FORM NAME="buttonbar">
      <INPUT TYPE="button" VALUE="Back" onClick="history.back()">
      <INPUT TYPE="button" VALUE="JS- Home" onClick="location='script.html'">
      <INPUT TYPE="button" VALUE="Next" onCLick="history.forward()">
</FORM>
</body>
</html>
50、查看某网址的源代码
把如下代码加入<body>区域中
<SCRIPT>
function add()
{
var ress=document.forms[0].luxiaoqing.value
window.location="view-source:"+ress;
}
</SCRIPT>
输入要查看源代码的URL地址:
<FORM><input type="text" name="luxiaoqing" size=40 value="http://"></FORM>
<FORM><br>
<INPUT type="button" value="查看源代码" onClick=add()>
</FORM>


51、title显示日期
把如下代码加入<body>区域中:
<script language="JavaScript1.2">
<!--hide
var isnMonth = new
Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
var isnDay = new
Array("星期日","星期一","星期二","星期三","星期四","星期五","星期六","星期日");
today = new Date () ;
Year=today.getYear();
Date=today.getDate();
if (document.all)
document.title="今天是: "+Year+"年"+isnMonth[today.getMonth()]+Date+"日"+isnDay[today.getDay()]
//--hide-->
</script>


52、显示所有链接
把如下代码加入<body>区域中
<script language="JavaScript1.2">
<!--
function extractlinks(){
var links=document.all.tags("A")
var total=links.length
var win2=window.open("","","menubar,scrollbars,toolbar")
win2.***("<font size='2'>一共有"+total+"个连接</font><br>")
for (i=0;i<total;i++){
win2.***("<font size='2'>"+links[i].outerHTML+"</font><br>")
}
}
//-->
</script>
<input type="button" onClick="extractlinks()" value="显示所有的连接">


53、回车键换行
把如下代码加入<body>区域中
<script type="text/javascript">                
function handleEnter (field, event) {
   var keyCode = event.keyCode ? event.keyCode : event.which ?
event.which : event.charCode;
   if (keyCode == 13) {
    var i;
    for (i = 0; i < field.form.elements.length; i++)
     if (field == field.form.elements[i])
      break;
    i = (i + 1) % field.form.elements.length;
    field.form.elements[i].focus();
    return false;
   }
   else
   return true;
}      
</script>
<form>
<input type="text" onkeypress="return handleEnter(this, event)"><br>
<input type="text" onkeypress="return handleEnter(this, event)"><br>
<textarea>回车换行


54、确认后提交
把如下代码加入<body>区域中
<SCRIPT LANGUAGE="JavaScript">
<!--
function msg(){
if (confirm("你确认要提交嘛!"))
document.lnman.submit()
}
//-->
</SCRIPT>
<form name="lnman" method="post" action="">
   <p>
     <input type="text" name="textfield" value="确认后提交">
   </p>
   <p>
     <input type="button" name="Submit" value="提交" onclick="msg();">
   </p>
</form>


55、改变表格的内容
把如下代码加入<body>区域中
<script ***script>
var arr=new Array()
arr[0]="一一一一一";
arr[1]="二二二二二";
arr[2]="三三三三三";
</script>
<select onchange="zz.cells[this.selectedIndex].innerHTML=arr[this.selectedIndex]">
   <option value=a>改变第一格</option>
   <option value=a>改变第二格</option>
   <option value=a>改变第三格</option>
</select>
<table id=zz border=1>
   <tr height=20>
     <td width=150>第一格</td>
<td width=150>第二格</td>
<td width=150>第三格</td>
   </tr>
</table>

posted @ 2008-10-09 20:10 鸿雁 阅读(199) | 评论 (0)编辑 收藏

struts+spring+hibernate的web应用示例

     摘要: struts+spring+hibernate的web应用<一> 架构搭建 开发工具: Eclipse 3.2 + NLpack1-eclipse-SDK-3.2.1-win32( 中文语言包 ) 插件: tomcatPluginV31 :用于 tomcat 项目建立和管理。 Properties Editor : struts 中的资源国际化的中文编辑插件,不需要...  阅读全文

posted @ 2008-03-01 21:39 鸿雁 阅读(821) | 评论 (0)编辑 收藏

如何查找、删除表中重复的记录

软件环境:

1Windows NT4.0+ORACLE 8.0.4

2ORACLE安装路径为:C:"ORANT

问题提出:

1、当我们想要为一个表创建唯一索引时,如果该表有重复的记录,则无法创建成功。

方法原理:

1Oracle中,每一条记录都有一个rowidrowid在整个数据库中是唯一的,

  rowid确定了每条记录是在ORACLE中的哪一个数据文件、块、行上。

2、在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中

  那些具有最大rowid的就可以了,其余全部删除。

3、以下语句用到了3项技巧:rowid、子查询、别名。

实现方法:

SQL> create table a (

 2 bm char(4),            --编码

 3 mc varchar2(20)            --名称

 4 )

 5 /

表已建立.

SQL> insert into a values('1111','1111');

SQL> insert into a values('1112','1111');

SQL> insert into a values('1113','1111');

SQL> insert into a values('1114','1111');

SQL> insert into a select * from a;

插入4个记录.

SQL> commit;

完全提交.

SQL> select rowid,bm,mc from a;

ROWID              BM   MC

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

000000D5.0000.0002 1111 1111

000000D5.0001.0002 1112 1111

000000D5.0002.0002 1113 1111

000000D5.0003.0002 1114 1111

000000D5.0004.0002 1111 1111

000000D5.0005.0002 1112 1111

000000D5.0006.0002 1113 1111

000000D5.0007.0002 1114 1111

 

查询到8记录.

查出重复记录

SQL> select rowid,bm,mc from a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);

ROWID              BM   MC

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

000000D5.0000.0002 1111 1111

000000D5.0001.0002 1112 1111

000000D5.0002.0002 1113 1111

000000D5.0003.0002 1114 1111

 

删除重复记录

SQL> delete from a a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);

删除4个记录.

SQL> select rowid,bm,mc from a;

ROWID              BM   MC

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

000000D5.0004.0002 1111 1111

000000D5.0005.0002 1112 1111

000000D5.0006.0002 1113 1111

000000D5.0007.0002 1114 1111

 

come from :: http://dev.csdn.net/article/59/59333.shtm

-测试数据

/*-----------------------------

select * from tt

-----------------------------*/

id          pid        

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

1           1

1           1

2           2

3           3

3           3

3           3

(所影响的行数为 6 行)

首先,如何查询table中有重复记录

select *,count(1) as rownum

from tt

group by id, pid

having count(1) > 1

id          pid         rownum     

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

1           1           2

3           3           3

 

(所影响的行数为 2 行)

方法一:使用distinct和临时表

if object_id('tempdb..#tmp') is not null

drop table #tmp

select distinct * into #tmp from tt

truncate table tt

insert into tt select * from #tmp

方法二:添加标识列

alter table tt add NewID int identity(1,1)

go 

delete from tt where exists(select 1 from tt a where a.newid>tt.newid and tt.id=a.id and tt.pid=a.pid)

go

alter table tt drop column NewID

go

--测试结果

/*-----------------------------

select * from tt

-----------------------------*/

id          pid        

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

1           1

2           2

3           3

(所影响的行数为 3 行)

*---*-- * 8 8 * * * * 8* * * * 8 8 *

USE CEO

CREATE TABLE TT

(

TTNO CHAR(4),

TTNAME VARCHAR(10)

)

INSERT INTO TT (TTNO,TTNAME) VALUES ('1425','WHERE')

INSERT INTO TT (TTNO,TTNAME) VALUES ('1425','WHERE')

INSERT INTO TT (TTNO,TTNAME) VALUES ('1424','WHEREIS')

INSERT INTO TT (TTNO,TTNAME) VALUES ('1435','WHEREIS')

INSERT INTO TT (TTNO,TTNAME) VALUES ('1435','WHEREIS')

方法二:添加标识列(最有效方法)

alter table tt add newid2 int identity(1,1)

go

delete from tt where exists( select 1 from tt   a where a.newid2>tt.newid2 and tt.ttno=a.ttno and tt.ttname=a.ttname)

alter table tt drop column newid2

go

select * from tt

posted @ 2008-01-22 01:57 鸿雁 阅读(280) | 评论 (0)编辑 收藏

Java程序员:一刻钟精通正则表达式

开篇,还是得说说 ^ 和 $ 他们是分别用来匹配字符串的开始和结束,以下分别举例说明:

  "^The": 开头一定要有"The"字符串;

  "of despair$": 结尾一定要有"of despair" 的字符串;

  那么,

  "^abc$": 就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配。

  "notice": 匹配包含notice的字符串。

  你可以看见如果你没有用我们提到的两个字符(最后一个例子),就是说 模式(正则表达式) 可以出现在被检验字符串的任何地方,你没有把他锁定到两边。

  接着,说说 '*', '+',和 '?',

  他们用来表示一个字符可以出现的次数或者顺序. 他们分别表示:

  1.   "zero or more"相当于{0,},
  2.   "one or more"相当于{1,},
  3.   "zero or one."相当于{0,1}, 这里是一些例子:
  4.   "ab*": 和ab{0,}同义,匹配以a开头,后面可以接0个或者N个b组成的字符串("a", "ab", "abbb", 等);
  5.   "ab+": 和ab{1,}同义,同上条一样,但最少要有一个b存在 ("ab", "abbb", 等.);
  6.   "ab?":和ab{0,1}同义,可以没有或者只有一个b;
  7.   "a?b+$": 匹配以一个或者0个a再加上一个以上的b结尾的字符串.

  要点, '*', '+',和 '?'只管它前面那个字符.

  你也可以在大括号里面限制字符出现的个数,比如

  1.   "ab{2}": 要求a后面一定要跟两个b(一个也不能少)("abb");
  2.   "ab{2,}": 要求a后面一定要有两个或者两个以上b(如"abb", "abbbb", 等.);
  3.   "ab{3,5}": 要求a后面可以有2-5个b("abbb", "abbbb", or "abbbbb").

  现在我们把一定几个字符放到小括号里,比如:

  1.   "a(bc)*": 匹配 a 后面跟0个或者一个"bc";
  2.   "a(bc){1,5}": 一个到5个 "bc."

  还有一个字符 '│', 相当于OR 操作:

  "hi│hello": 匹配含有"hi" 或者 "hello" 的 字符串;

  "(b│cd)ef": 匹配含有 "bef" 或者 "cdef"的字符串;

  "(a│b)*c": 匹配含有这样多个(包括0个)a或b,后面跟一个c的字符串;

  一个点('.')可以代表所有的单一字符,不包括"\n"

  如果,要匹配包括"\n"在内的所有单个字符,怎么办?

  对了,用'[\n.]'这种模式.

  "a.[0-9]": 一个a加一个字符再加一个0到9的数字

  "^.{3}$": 三个任意字符结尾 .

  中括号括住的内容只匹配一个单一的字符

  "[ab]": 匹配单个的 a 或者 b ( 和 "a│b" 一样);

  "[a-d]": 匹配'a' 到'd'的单个字符 (和"a│b│c│d" 还有 "[abcd]"效果一样); 一般我们都用[a-zA-Z]来指定字符为一个大小写英文

  "^[a-zA-Z]": 匹配以大小写字母开头的字符串

  "[0-9]%": 匹配含有 形如 x% 的字符串

  ",[a-zA-Z0-9]$": 匹配以逗号再加一个数字或字母结尾的字符串

  你也可以把你不想要得字符列在中括号里,你只需要在总括号里面使用'^' 作为开头 "%[^a-zA-Z]%" 匹配含有两个百分号里面有一个非字母的字符串.

  要点:^用在中括号开头的时候,就表示排除括号里的字符。为了PHP能够解释,你必须在这些字符面前后加'',并且将一些字符转义.

  不要忘记在中括号里面的字符是这条规路的例外?在中括号里面, 所有的特殊字符,包括(''), 都将失去他们的特殊性质 "[*\+?{}.]"匹配含有这些字符的字符串.

  还有,正如regx的手册告诉我们: "如果列表里含有 ']', 最好把它作为列表里的第一个字符(可能跟在'^'后面). 如果含有'-', 最好把它放在最前面或者最后面, or 或者一个范围的第二个结束点[a-d-0-9]中间的‘-’将有效.

  看了上面的例子,你对{n,m}应该理解了吧.要注意的是,n和m都不能为负整数,而且n总是小于m. 这样,才能 最少匹配n次且最多匹配m次. 如"p{1,5}"将匹配 "pvpppppp"中的前五个p.

下面说说以\开头的

  \b 书上说他是用来匹配一个单词边界,就是...比如've\b',可以匹配love里的ve而不匹配very里有ve

  \B 正好和上面的\b相反.例子我就不举了

  .....突然想起来....可以到http://www.phpv.net/article.php/251 看看其它用\ 开头的语法

  好,我们来做个应用:

  如何构建一个模式来匹配 货币数量 的输入

  构建一个匹配模式去检查输入的信息是否为一个表示money的数字。我们认为一个表示money的数量有四种方式: "10000.00" 和 "10,000.00",或者没有小数部分, "10000" and "10,000". 现在让我们开始构建这个匹配模式:

^[1-9][0-9]*$

这是所变量必须以非0的数字开头.但这也意味着 单一的 "0" 也不能通过测试. 以下是解决的方法:

^(0│[1-9][0-9]*)$

  "只有0和不以0开头的数字与之匹配",我们也可以允许一个负号在数字之前:

^(0│-?[1-9][0-9]*)$

  这就是: "0 或者 一个以0开头 且可能 有一个负号在前面的数字." 好了,现在让我们别那么严谨,允许以0开头.现在让我们放弃 负号 , 因为我们在表示钱币的时候并不需要用到. 我们现在指定 模式 用来匹配小数部分:

^[0-9]+(\.[0-9]+)?$

  这暗示匹配的字符串必须最少以一个阿拉伯数字开头. 但是注意,在上面模式中 "10." 是不匹配的, 只有 "10" 和 "10.2" 才可以. (你知道为什么吗)

^[0-9]+(\.[0-9]{2})?$

  我们上面指定小数点后面必须有两位小数.如果你认为这样太苛刻,你可以改成:

^[0-9]+(\.[0-9]{1,2})?$

  这将允许小数点后面有一到两个字符. 现在我们加上用来增加可读性的逗号(每隔三位), 我们可以这样表示:

^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$

  不要忘记 '+' 可以被 '*' 替代 如果你想允许空白字符串被输入话 (为什么?). 也不要忘记反斜杆 ’\’ 在php字符串中可能会出现错误 (很普遍的错误).

  现在,我们已经可以确认字符串了, 我们现在把所有逗号都去掉 str_replace(",", "", $money) 然后在把类型看成 double然后我们就可以通过他做数学计算了.

再来一个:

  构造检查email的正则表达式

  在一个完整的email地址中有三个部分:

  1. 用户名 (在 '@' 左边的一切),

  2.'@',

  3. 服务器名(就是剩下那部分).

  用户名可以含有大小写字母阿拉伯数字,句号 ('.'), 减号('-'), and 下划线 ('_'). 服务器名字也是符合这个规则,当然下划线除外.

  现在, 用户名的开始和结束都不能是句点. 服务器也是这样. 还有你不能有两个连续的句点他们之间至少存在一个字符,好现在我们来看一下怎么为用户名写一个匹配模式:

^[_a-zA-Z0-9-]+$

  现在还不能允许句号的存在. 我们把它加上:

^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*$

  上面的意思就是说: "以至少一个规范字符(除了.)开头,后面跟着0个或者多个以点开始的字符串."

  简单化一点, 我们可以用 eregi()取代 ereg().eregi()对大小写不敏感, 我们就不需要指定两个范围 "a-z" 和 "A-Z" ? 只需要指定一个就可以了:

^[_a-z0-9-]+(\.[_a-z0-9-]+)*$

  后面的服务器名字也是一样,但要去掉下划线:

^[a-z0-9-]+(\.[a-z0-9-]+)*$

  好. 现在只需要用”@”把两部分连接:

^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$

  这就是完整的email认证匹配模式了,只需要调用

eregi(‘^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$ ’,$eamil)

  就可以得到是否为email了.


正则表达式的其他用法

  提取字符串

  ereg() and eregi() 有一个特性是允许用户通过正则表达式去提取字符串的一部分(具体用法你可以阅读手册). 比如说,我们想从 path/URL 提取文件名 ? 下面的代码就是你需要:

ereg("([^\\/]*)$", $pathOrUrl, $regs);
echo $regs[1];

  高级的代换

  ereg_replace() 和 eregi_replace()也是非常有用的: 假如我们想把所有的间隔负号都替换成逗号:

ereg_replace("[ \n\r\t]+", ",", trim($str));

  最后,我把另一串检查EMAIL的正则表达式让看文章的你来分析一下.

"^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'.'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$"

  如果能方便的读懂,那这篇文章的目的就达到了.

posted @ 2008-01-16 15:59 鸿雁 阅读(283) | 评论 (0)编辑 收藏

Hibernate3调用存储过程用法

DB2中简单存储过程 selectAllUsers

CREATE procedure selectAllUsers
DYNAMIC RESULT SETS 1
BEGIN
DECLARE temp_cursor1 CURSOR WITH RETURN TO CLIENT FOR
SELECT * FROM test;
OPEN temp_cursor1;
END;

映射文件中关于存储过程内容如下

<hibernate-mapping package="com.unmi.vo">
<class name="Test" table="TEST">
     ............
</class>

<sql-query callable="true" name="selectAllUsers">
<return alias="aa" class="Test">
<return-property name="oborqt" column="OBORQT"/>
<return-property name="moorqt" column="MOORQT"/>
<return-property name="roschn" column="ROSCHN"/>
<return-property name="plandate" column="PLANDATE"/>
</return>
{ ? = call selectAllUsers() }
</sql-query>
</hibernate-mapping>

{ ? = call selectAllUsers() } 也可以写成{ call selectAllUsers() },
如果有参数就写成
{ ? = call selectAllUsers(?,?,?) }
代码中对query设置相应位置上的值就OK

Java调用关键代码如下

Session session = HibernateUtil.currentSession();
Query query = session.getNamedQuery("selectAllUsers");
List list = query.list();
System.out.println(list);

要求你的存储过程必须能返回记录集,否则要出错
如果你的存储过程是完成非查询任务就应该在配置文件用以下三个标签
<sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
<sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
<sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>

posted @ 2008-01-11 18:31 鸿雁 阅读(265) | 评论 (0)编辑 收藏

数字智力测试题

——此文章摘自《Java程序员面试宝典》定价:46元 特价:38.9元 购买>>

    回答智力测试的一些基本方法如下。
    (1)排除法
    把一些无关的问题先予以排除,可以确定的问题先确定,尽可能缩小未知的范围,以便于问题的分析和解决。这种思维方式在我们的工作和生活中都是很有用处的。

    (2)递推法
    由已知条件层层向下分析,要确保每一步都能准确无误。可能会有几个分支,应本着先易后难的原则,先从简单的一支入手。

    (3)倒推法
    从问题最后的结果开始,一步一步往前推,直到求出问题的答案。有些问题用此法解起来很简单,如用其他方法则很难。

    (4)假设法
    对给定的问题,先做一个或一些假设,然后根据已给的条件进行分析,如果出现与题目给的条件有矛盾的情况,说明假设错误,可再做另一个或另一些假设。如果结果只有两种可能,那么问题就已经解决了。在科学史上,“假设”曾起了极大的作用。

    (5)计算法
    有些问题必须经计算才能解决。要注意的是,智力测验中的问题往往含有隐含的条件,有时给出的数是无用的。

    (6)分析法
    这是最基本的方法。各种方法常常要用到分析法。可以说,分析能力的高低,是一个人的智力水平的体现。分析能力不仅是先天性的,在很大程度上取决于后天的训练,应养成对客观事物进行分析的良好习惯。

    (7)作图法
    根据问题中已知的条件,采用适当的方法画出图形,有助于问题的解决。有些问题,在没画图之前,会觉得无处下手,画了图后就一目了然了。

    (8)综合法
    事实上,许多问题都要运用几种不同的方法才能解决。所谓综合法,就是综合各种方法(包括前述各种方法以外的方法)去解决某些问题。

    面试例题1:100美元哪里去了?

    3个朋友住进了一家宾馆。结账时,账单总计3 000美元。3个朋友每人分摊1 000美元,并把这3 000美元如数交给了服务员,委托他代到总台交账。但在交账时,正逢宾馆实施价格优惠,总台退还给服务员500美元,实收2 500美元。服务员从这500美元退款中扣下了200美元,只退还3个客人300美元。3个客人平分了这300美元,每人取回了100美元。这样,3个客人每人实际支付900美元,共支付2 700美元,加上服务员扣的200美元,共计2 900美元,那么这100美元的差额到哪里去了?

    答案:这道题纯粹是文字游戏,但是如果你的头脑不够清晰,很可能把你搞糊涂了。客人实际支付2 700美元,就等于总台实际结收的2 500美元加上服务员克扣的200美元。在这2 700美元上加上200美元是毫无道理的,而在这2 700美元上加退回的300美元,这是有道理的,因为这等于客人原先交给服务员的3 000美元。

    面试例题2:击鼠标比赛现在开始!参赛者有拉尔夫、威利和保罗。

    拉尔夫10秒钟能击10下鼠标,威利20秒钟能击20下鼠标,保罗5秒钟能击5下鼠标。以上各人所用的时间是这样计算的:从第一击开始,到最后一击结束。

    他们是否打平手?如果不是,谁最先击完40下鼠标?

    解析:n秒钟击n下鼠标其实是击第一下鼠标时才开始计时的,实际上击n-1下需要n秒钟,那么若击40下鼠标,拉尔夫需要(40-1)/(9/10)=39/0.9秒,威利需要(40-1)/(19/20)=39/0.95秒,保罗需要(40-1)/(4/5)=39/0.8秒,因此威利先击完。

    答案:威利先击完。

    面试例题3:父亲打电话给女儿,要她替自己买一些生活用品,同时告诉她,钱放在书桌上的一个信封里。女儿找到信封,看见上面写着98,以为信封内有98元,就把钱拿出来,数也没数放进书包里。在商店里,她买了90元的东西,付款时才发现,她不仅没有剩下8元,反而差了4元。回到家里,她把这事告诉了父亲,怀疑父亲把钱点错了。父亲笑着说,他并没有数错,错在女儿身上。

    问:女儿错在什么地方?

    答案:拿倒了,86看成是98了。

    面试例题4:3个孩子翻衣兜,他们把兜里所有的钱都掏出来,看看一共有多少钱。结果一共有320日元。其中有两枚硬币是100日元的,两枚是50日元的,两枚是10日元的。每一个孩子所带的硬币中没有相同的。而且,没带100日元硬币的孩子也没带10日元的硬币,没带50日元硬币的孩子也没带100日元的硬币。你能弄清楚这3个日本孩子原来各自带了什么硬币吗?

    答案:第一个小孩:100,50,10;第二个小孩:100,50;第三个小孩:10。

    面试例题5:有一种小虫,每隔2秒钟分裂一次。分裂后的2只新的小虫经过2秒钟后又会分裂。如果最初某瓶中只有一只小虫,那么2秒后变2只,再过2秒后就变4只……2分钟后,正好满满一瓶小虫。假设这个瓶内最初放入2只这样的小虫。

    问:经过多少时间后,正巧也是满满的一瓶?

    答案:经过1分58秒时间,也正巧是满满一瓶。因为从一只虫蜕变为2只虫只需2秒钟。在瓶内只有一只虫子的情况下,经过2秒钟后就变成2只。这时的情况和瓶内一开始就有2只虫子的情况是一样的。出现这两种情况的时间差是2秒钟。所以,经过1分58秒后,也正好是满满一瓶。

    面试例题6:斯芬克斯是古代希腊神话中的带翅膀的狮子女魔。传说她在底比斯附近要人猜谜,猜不出来就要杀人。一次,她要底比斯王子猜谜:“有一种动物,早上4条腿,中午2条腿,晚上3条腿,是什么动物?”聪明的王子说:“是人。”他猜中了。

    如果你是现代的斯芬克斯,会提出什么样的问题呢?比如,1和0之间加上什么符号才可以使得到的数比0大又比1小呢?你知道吗?

    答案:0.1

    面试例题7:你让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费?你让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费?

    答案:两次弄断就应分成三份,我把金条分成1/7、2/7和4/7三份。这样,第1天我就可以给他1/7;第2天我给他2/7,让他找回我1/7;第3天我就再给他1/7,加上原先的2/7就是3/7;第4天我给他那块4/7,让他找回那两块1/7和2/7的金条;第5天,再给他1/7;第6天和第2天一样;第7天给他找回的那个1/7。

     面试题8:对一批编号为1-100全部开关朝上(开)的灯进行以下操作:凡是1的倍数反方向拨一次开关;2的倍数反方向又拨一次开关;3的倍数反方向又拨一次开关。。。。。问:最后为关熄状态的灯的编号。    
   
  答案:  
  1,4,9,16,25,36,47,64,81,100关 

     面试题9:  
  小明和小强都是王老师的学生。王老师的生日是m月n日,2人都指导王老师的生日是下列10组中的一天,王老师把m值告诉了小明,把n值告诉了小强。王老师文他们知道他的生日是那一天吗?  
  3月4   日,3月5   日,3月9   日  
  6月   4日,6月   7日  
  9月   1日,9月   5日  
  12月   1日,12月   2日,12月   8日  
  小明说:我不知道的话,小强肯定也不知道  
  小强说:笨来我不知道,但是现在我知道了  
  小明说:哦,那我也知道了  
  情根据上面的对话推断出王老师的生日是哪一天?
  
   答案:9月1号准没错  
  首先小明是不知道的,所以不可能在某月的   2号,7号,8号,9号.去掉一些日子后;简化如下  
  3月4   日,3月5   日,  
  6月   4日,  
  9月   1日,9月   5日  
  12月   1日,  
  小强说他不知道,小明也不会知道.即小强知道的月数不会在有   2号,7号,8号,9号   的这些月数,因为如果在这些月数,小明是有可能知道的.最后只剩下   9月1日   和   9月5日.  
  这时候小明也清楚M是9月了,小强也因此知道N是1号.   


     神的交通工具是什么------神奇(骑)宝贝
  什么动物可以贴在墙上------海豹(报)
  什么颜色最会模仿------红(磨坊)模仿
  什么鸡最慢------尼可基(鸡)曼
  辣妹什么地方最香------腊梅处处香
  哪位古人跑得最快------曹操(说曹操曹操就到)
  什么动物没有方向感------麋鹿(迷路)
  茉莉花、太阳花、玫瑰花,哪一朵花最没力------茉莉花[好一朵美丽(没力)的茉莉花]
  猴子最付厌什么钱------平行线[没有相交(香蕉)]
  象皮、老虎皮、狮子つ囊桓霰冉喜?-----象皮擦(象皮差)
  木鱼掉进海里会变成什么------虱目鱼(湿木鱼)
  哪一位艺人讲的笑话最冷------蔡依琳(衣淋湿就冷)
  狼、老虎和狮子谁玩游戏一定会被淘汰------狼,桃太郎(淘汰狼)
  孔子有三位徒弟子贡、子路和子游,请问哪一位不是人------子路(指鹿为马)
  布跟纸怕什么------不怕一万只怕万一 (布怕一万纸怕万一)
  麒麟飞到北极会变成什么------冰淇淋(冰麒麟)
  哪个历史人物游泳必定沉下去------阿斗,扶(浮)不起的阿斗
  星星、月亮、太阳哪一个是哑巴------星星,歌中有「天上的星星不说话 」
  铅笔姓什么------萧,削(萧)铅笔
  糖果是公的还是母的------母的,因为它会生蚂蚁
  请问哪一种花没有孩子------五月花, 五月花卫生纸(未生子)
  左和右,谁喜欢独奏,谁又比较好------左solo, 右so good (左手锣,右手鼓)
  为什么蚕宝宝很有钱------蚕会结茧(节俭)
  周瑜与诸葛亮的母亲分别姓什么------[既]生瑜,[何]生亮
  和谁交往最辛苦------莉莉,粒粒(莉莉)皆辛苦
  蝴蝶、蚂蚁、蜘蛛、蜈蚣,哪一个没有领到酬劳------蜈蚣,无功(蜈蚣)不受禄
  哪位历史人物最欠扁------苏武,苏武牧羊北海边(被海扁)
  123456789哪个数字最勤劳,哪个数字最懒惰------1最勤劳2最懒惰(一不做二不休)
  谁家没有电话------天衣(天衣无缝 phone)
  怎样使麻雀安静下来------压它一下(鸦雀无声)
  哪一家的路最窄------冤家(冤家路窄)
  红豆的小孩是谁------南国(红豆生南国)
  有位妈妈生了连体婴,姐姐叫玛丽,那么妹妹叫什么------梦露,玛丽莲(连)梦露

posted @ 2008-01-05 15:05 鸿雁 阅读(1675) | 评论 (0)编辑 收藏

常用正则表达式


正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。

匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了

匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行

匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用

匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始

匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用

匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正

匹配特定字符串:
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式

原载地址:http://lifesinger.3322.org/myblog/?p=185

posted @ 2007-12-24 00:02 鸿雁 阅读(385) | 评论 (0)编辑 收藏

数据库和数据仓库的区别

数据库是面向事务的设计,数据仓库是面向主题设计的。数据库一般存储在线交易数据,数据仓库存储的一般是历史数据。

数据库设计是尽量避免冗余,一般采用符合范式的规则来设计,数据仓库在设计是有意引入冗余,采用反范式的方式来设计。

数据库是为捕获数据而设计,数据仓库是为分析数据而设计,它的两个基本的元素是维表和事实表。(维是看问题的角度,比如时间,部门,维表放的就是这些东西的定义,事实表里放着要查询的数据,同时有维的ID)

数据仓库,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,它决不是所谓的“大型数据库”。那么,数据仓库与传统数据库比较,有哪些不同呢?让我们先看看W.H.Inmon关于数据仓库的定义:面向主题的、集成的、与时间相关且不可修改的数据集合。

“面向主题的”:传统数据库主要是为应用程序进行数据处理,未必按照同一主题存储数据;数据仓库侧重于数据分析工作,是按照主题存储的。这一点,类似于传统农贸市场与超市的区别—市场里面,白菜、萝卜、香菜会在一个摊位上,如果它们是一个小贩卖的;而超市里,白菜、萝卜、香菜则各自一块。也就是说,市场里的菜(数据)是按照小贩(应用程序)归堆(存储)的,超市里面则是按照菜的类型(同主题)归堆的。

“与时间相关”:数据库保存信息的时候,并不强调一定有时间信息。数据仓库则不同,出于决策的需要,数据仓库中的数据都要标明时间属性。决策中,时间属性很重要。同样都是累计购买过九车产品的顾客,一位是最近三个月购买九车,一位是最近一年从未买过,这对于决策者意义是不同的。

“不可修改”:数据仓库中的数据并不是最新的,而是来源于其它数据源。数据仓库反映的是历史信息,并不是很多数据库处理的那种日常事务数据(有的数据库例如电信计费数据库甚至处理实时信息)。因此,数据仓库中的数据是极少或根本不修改的;当然,向数据仓库添加数据是允许的。

数据仓库的出现,并不是要取代数据库。目前,大部分数据仓库还是用关系数据库管理系统来管理的。可以说,数据库、数据仓库相辅相成、各有千秋

补充一下,数据仓库的方案建设的目的,是为前端查询和分析作为基础,由于有较大的冗余,所以需要的存储也较大。为了更好地为前端应用服务,数据仓库必须有如下几点优点,否则是失败的数据仓库方案。

1.效率足够高。客户要求的分析数据一般分为日、周、月、季、年等,可以看出,日为周期的数据要求的效率最高,要求24小时甚至12小时内,客户能看到昨天的数据分析。由于有的企业每日的数据量很大,设计不好的数据仓库经常会出问题,延迟1-3日才能给出数据,显然不行的。

2.数据质量。客户要看各种信息,肯定要准确的数据,但由于数据仓库流程至少分为3步,2次ETL,复杂的架构会更多层次,那么由于数据源有脏数据或者代码不严谨,都可以导致数据失真,客户看到错误的信息就可能导致分析出错误的决策,造成损失,而不是效益。

3.扩展性。之所以有的大型数据仓库系统架构设计复杂,是因为考虑到了未来3-5年的扩展性,这样的话,客户不用太快花钱去重建数据仓库系统,就能很稳定运行。主要体现在数据建模的合理性,数据仓库方案中多出一些中间层,使海量数据流有足够的缓冲,不至于数据量大很多,就运行不起来了.

posted @ 2007-12-05 00:07 鸿雁 阅读(185) | 评论 (0)编辑 收藏

数据抽取、清洗与转换 BI项目中ETL设计

       ETL是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程,目的是将企业中的分散、零乱、标准不统一的数据整合到一起,为企业的决策提供分析的依据

  ETLBI项目最重要的一个环节,通常情况下ETL会花掉整个项目的1/3的时间,ETL设计的好坏直接关接到BI项目的成败。ETL也是一个长期的过程,只有不断的发现问题并解决问题,才能使ETL运行效率更高,为项目后期开发提供准确的数据。

  ETL的设计分三部分:数据抽取、数据的清洗转换、数据的加载。在设计ETL的时候也是从这三部分出发。数据的抽取是从各个不同的数据源抽取到ODS中(这个过程也可以做一些数据的清洗和转换),在抽取的过程中需要挑选不同的抽取方法,尽可能的提高ETL的运行效率。ETL三个部分中,花费时间最长的是T(清洗、转换)的部分,一般情况下这部分工作量是整个ETL的2/3。数据的加载一般在数据清洗完了之后直接写入DW中去。

  ETL的实现有多种方法,常用的有三种,第一种是借助ETL工具如Oracle的OWB、SQL server 2000的DTS、SQL Server2005的SSIS服务、informatic等实现,第二种是SQL方式实现,第三种是ETL工具和SQL相结合。前两种方法各有优缺点,借助工具可以快速的建立起ETL工程,屏蔽复杂的编码任务,提高速度,降低难度,但是欠缺灵活性。SQL的方法优点是灵活,提高ETL运行效率,但是编码复杂,对技术要求比较高。第三种是综合了前面二种的优点,极大的提高ETL的开发速度和效率。

  数据的抽取

  数据的抽取需要在调研阶段做大量工作,首先要搞清楚以下几个问题:数据是从几个业务系统中来?各个业务系统的数据库服务器运行什么DBMS?是否存在手工数据,手工数据量有多大?是否存在非结构化的数据?等等类似问题,当收集完这些信息之后才可以进行数据抽取的设计。

  1、与存放DW的数据库系统相同的数据源处理方法

  这一类数源在设计比较容易,一般情况下,DBMS(包括SQLServer,Oracle)都会提供数据库链接功能,在DW数据库服务器和原业务系统之间建立直接的链接关系就可以写Select 语句直接访问。

  2、与DW数据库系统不同的数据源的处理方法。

  这一类数据源一般情况下也可以通过ODBC的方式建立数据库链接,如SQL Server和Oracle之间。如果不能建立数据库链接,可以有两种方式完成,一种是通过工具将源数据导出成.txt或者是.xls文件,然后再将这些源系统文件导入到ODS中。另外一种方法通过程序接口来完成。

  3、对于文件类型数据源(.txt,,xls),可以培训业务人员利用数据库工具将这些数据导入到指定的数据库,然后从指定的数据库抽取。或者可以借助工具实现,如SQL SERVER 2005 的SSIS服务的平面数据源和平面目标等组件导入ODS中去。

  4、增量更新问题

  对于数据量大的系统,必须考虑增量抽取。一般情况,业务系统会记录业务发生的时间,可以用作增量的标志,每次抽取之前首先判断ODS中记录最大的时间,然后根据这个时间去业务系统取大于这个时间的所有记录。利用业务系统的时间戳,一般情况下,业务系统没有或者部分有时间戳。

  数据的清洗转换

  一般情况下,数据仓库分为ODS、DW两部分,通常的做法是从业务系统到ODS做清洗,将脏数据和不完整数据过滤掉,再从ODS到DW的过程中转换,进行一些业务规则的计算和聚合。

           1、数据清洗

  数据清洗的任务是过滤那些不符合要求的数据,将过滤的结果交给业务主管部门,确认是否过滤掉还是由业务单位修正之后再进行抽取。不符合要求的数据主要是有不完整的数据、错误的数据和重复的数据三大类。

  •   A、不完整的数据,其特征是是一些应该有的信息缺失,如供应商的名称,分公司的名称,客户的区域信息缺失、业务系统中主表与明细表不能匹配等。需要将这一类数据过滤出来,按缺失的内容分别写入不同Excel文件向客户提交,要求在规定的时间内补全。补全后才写入数据仓库。
  •   B、错误的数据,产生原因是业务系统不够健全,在接收输入后没有进行判断直接写入后台数据库造成的,比如数值数据输成全角数字字符、字符串数据后面有一个回车、日期格式不正确、日期越界等。这一类数据也要分类,对于类似于全角字符、数据前后有不面见字符的问题只能写SQL的方式找出来,然后要求客户在业务系统修正之后抽取;日期格式不正确的或者是日期越界的这一类错误会导致ETL运行失败,这一类错误需要去业务系统数据库SQL的方式挑出来,交给业务主管部门要求限期修正,修正之后再抽取。
  •   C、重复的数据,特别是维表中比较常见,将重复的数据的记录所有字段导出来,让客户确认并整理。

  数据清洗是一个反复的过程,不可能在几天内完成,只有不断的发现问题,解决问题。对于是否过滤、是否修正一般要求客户确认;对于过滤掉的数据,写入Excel文件或者将过滤数据写入数据表,在ETL开发的初期可以每天向业务单位发送过滤数据的邮件,促使他们尽快的修正错误,同时也可以作为将来验证数据的依据。数据清洗需要注意的是不要将有用的数据过滤掉了,对于每个过滤规则认真进行验证,并要用户确认才行。

  2、数据转换

  数据转换的任务主要是进行不一致的数据转换、数据粒度的转换和一些商务规则的计算。

  •   A、不一致数据转换,这个过程是一个整合的过程,将不同业务系统的相同类型的数据统一,比如同一个供应商在结算系统的编码是XX0001,而在CRM中编码是YY0001,这样在抽取过来之后统一转换成一个编码。
  •   B、数据粒度的转换,业务系统一般存储非常明细的数据,而数据仓库中的数据是用来分析的,不需要非常明细的数据,一般情况下,会将业务系统数据按照数据仓库粒度进行聚合。
  •   C、商务规则的计算,不同的企业有不同的业务规则,不同的数据指标,这些指标有的时候不是简单的加加减减就能完成,这个时候需要在ETL中将这些数据指标计算好了之后存储在数据仓库中,供分析使用。

  ETL日志与警告发送

  1、ETL日志,记录日志的目的是随时可以知道ETL运行情况,如果出错了,出错在那里。

  ETL日志分为三类。第一类是执行过程日志,是在ETL执行过程中每执行一步的记录,记录每次运行每一步骤的起始时间,影响了多少行数据,流水账形式。第二类是错误日志,当某个模块出错的时候需要写错误日志,记录每次出错的时间,出错的模块以及出错的信息等。第三类日志是总体日志,只记录ETL开始时间,结束时间是否成功信息。

  如果使用ETL工具,工具会自动产生一些日志,这一类日志也可以作为ETL日志的一部分。

  2、警告发送

  ETL出错了,不仅要写ETL出错日志而且要向系统管理员发送警告,发送警告的方式有多种,常用的就是给系统管理员发送邮件,并附上出错的信息,方便管理员排查错误。

posted @ 2007-06-21 21:36 鸿雁 阅读(493) | 评论 (0)编辑 收藏

仅列出标题
共18页: First 上一页 6 7 8 9 10 11 12 13 14 下一页 Last