针对有网友说看不见文章内容, 现提示如下: 点击每一个标题行任一地方都会展开和隐藏此文章内容(不要点击标题). 目前展开隐藏功能只支持IE浏览器,虽然可以改成支持FF浏览器,不过现在一直没时间去弄,等有时间再修改了。 |
blog名称:乱闪Blog 日志总数:267 评论数量:1618 留言数量:-26 访问次数:2654444 建立时间:2005年1月1日 |
|

| |
鼠标经过时图片就会迅速的抖动
|
以下是代码: <style>
.shakeimage{
position:relative
}
</style>
<script language="javascript1.2">
var rector=3
var stopit=0
var a=1
function init(which){
stopit=0
shake=which
shake.style.left=0
shake.style.top=0
}
function rattleimage(){
if ((!document.all&&!document.getElementById)||stopit==1)
return
if (a==1){
shake.style.top=parseInt(shake.style.top)+rector
}
else if (a==2){
shake.style.left=parseInt(shake.style.left)+rector
}
else if (a==3){
shake.style.top=parseInt(shake.style.top)-rector
}
else{
shake.style.left=parseInt(shake.style.left)-rector
}
if (a<4)
a++
else
a=1
setTimeout("rattleimage()",50)
}
function stoprattle(which){
stopit=1
which.style.left=0
which.style.top=0
}
</script>
<body>
<center><img src=uploadfile/200512923158778.JPG class="shakeimage" onMouseover="init(this);rattleimage()" onMouseout="stoprattle(this)"></center>
</body> [Ctrl+A 全选 Ctrl+C 复制,如不能正常显示请刷新一下] |
|
不间断连续图片滚动效果的制作方法
|
先制作向上滚动的效果: 插入代码: <!-- 指向链接图片url --> <base href="http://www.it365cn.com"> <div id=demo style=overflow:hidden;height:150;width:90;background:#214984;color:#ffffff> <div id=demo1> <!-- 定义图片 --> <img src="images/logo_1.gif"> <img src="images/logo/flashempire.gif"> <img src="images/logo.gif"> <img src="images/logo/5dmedia.gif"> <img src="images/logo/macromedia.gif"> <img src="images/logo/sucaiw.gif"> <img src="images/logo/blueieda.gif"> <img src="images/logo/htmlcn.gif"> <img src="images/logo/fwcn.gif"> </div> <div id=demo2></div> </div>
<script> var speed=30 demo2.innerHTML=demo1.innerHTML function Marquee(){ if(demo2.offsetTop-demo.scrollTop<=0) demo.scrollTop-=demo1.offsetHeight else{ demo.scrollTop++ } } var MyMar=setInterval(Marquee,speed) demo.onmouseover=function() {clearInterval(MyMar)} demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)} </script>
制作向下滚动的效果: 将上面“制作向上滚动的效果”中的红色字体Js部分替换成: <script> var speed=30 demo2.innerHTML=demo1.innerHTML demo.scrollTop=demo.scrollHeight function Marquee(){ if(demo1.offsetTop-demo.scrollTop>=0) demo.scrollTop+=demo2.offsetHeight else{ demo.scrollTop-- } } var MyMar=setInterval(Marquee,speed) demo.onmouseover=function() {clearInterval(MyMar)} demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)} </script>
制作向左滚动的效果: <div id=demo style=overflow:hidden;height:33;width:500;background:#214984;color:#ffffff> <table align=left cellpadding=0 cellspace=0 border=0> <tr> <td id=demo1 valign=top><img src="images/logo_1.gif"><img src="images/logo/flashempire.gif"><img src="images/logo.gif"><img src="images/logo/5dmedia.gif"><img src="images/logo/macromedia.gif"><img src="images/logo/sucaiw.gif"><img src="images/logo/blueieda.gif"><img src="images/logo/htmlcn.gif"><img src="images/logo/fwcn.gif"> </td> <td id=demo2 valign=top></td> </tr> </table> </div>
<script> var speed=30 demo2.innerHTML=demo1.innerHTML function Marquee(){ if(demo2.offsetWidth-demo.scrollLeft<=0) demo.scrollLeft-=demo1.offsetWidth else{ demo.scrollLeft++ } } var MyMar=setInterval(Marquee,speed) demo.onmouseover=function() {clearInterval(MyMar)} demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)} </script>
制作向右滚动的效果: 将上面“制作向左滚动的效果”中的红色字体Js部分替换成: <script> var speed=30 demo2.innerHTML=demo1.innerHTML demo.scrollLeft=demo.scrollWidth function Marquee(){ if(demo.scrollLeft<=0) demo.scrollLeft+=demo2.offsetWidth else{ demo.scrollLeft-- } } var MyMar=setInterval(Marquee,speed) demo.onmouseover=function() {clearInterval(MyMar)} demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)} </script>
|
|
高级查找/替换、正则表达式练习器、Javascript脚本程序调试器
|
下面是我设计的一个的javascript程序,虽然简单,但却给我带来了极大的便利。我一直用它来调试一些javascript程序,用来测试正则表达式匹配,除了具备普通字符串的查找替换功能外,还可以通过使用正则表达式来实现一般的文本编辑器所不具备的高级查找/替换功能。
使用很简单了,在文本框输入一段javascript程序,单击执行脚本程序按钮即可运行程序,如果程序出错会给出详细的错误信息。在文本框输入一段文字,在查询表达式框输入表达式(可以是普通字符串或正则表达式),在替换框输入替换文本,然后执行查找/替换。该程序还支持多步Undo/Redo功能。
以下是代码: <HTML>
<HEAD>
<title>Power Maintenance Tools </title>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=gb_2312-80">
</HEAD>
<body>
<div style="FONT-WEIGHT:bold;FONT-SIZE:11pt;WIDTH:700px;TEXT-ALIGN:center">
高级查找/替换、正则表达式练习器、Javascript脚本程序调试器<br>
<textarea id='text1' rows='8' cols='82'></textarea><br>
<span id="spanFirst">查询表达式</span>:<input id="txtFirst" type="text" size="60"><br>
<span id="spanSecond">替换为</span>:<input id="txtSecond" type="text" size="56"><br>
<input type="button" id="btnExe" value="运行脚本程序">
<input type="button" id="btnSchRpl" value="执行查找/替换">
<input type="button" id="btnUndo" value="撤消" disabled="true">
<input type="button" id="btnRedo" value="重做" disabled="true">
<br></div>
<script>
var aryUndo=[],aryRedo=[]
function btnExe.onclick()
{
if(text1.value=="")return false
aryCommand=text1.value.split("\r\n")
var line
try{
for(line=0;line<=aryCommand.length-1;line++)
{
eval(aryCommand[line]+";")
}
}
catch(e){
var msg="执行脚本程序程序出错,在第"+(line+1)+"行。\n"
msg+="错误代码:"+e.number+"\n"
msg+="错误信息:"+e.description+"\n"
alert(msg)
}
}
function btnSchRpl.onclick()
{
if(txtFirst.value=="")
{
alert("请输入查询条件!")
txtSecond.focus()
return false
}
aryUndo[aryUndo.length]=text1.value
aryRedo=[]
btnRedo.disabled=true
btnUndo.disabled=false
var s=new RegExp(txtFirst.value,"ig")
text1.value=text1.value.replace(s,txtSecond.value)
}
function btnUndo.onclick()
{
aryRedo[aryRedo.length]=text1.value
btnRedo.disabled=false
text1.value =aryUndo[aryUndo.length-1]
aryUndo.length--
if(aryUndo.length==0)btnUndo.disabled=true
}
function btnRedo.onclick()
{
aryUndo[aryUndo.length]=text1.value
btnUndo.disabled=false
text1.value=aryRedo[aryRedo.length-1]
aryRedo.length--
if(aryRedo.length==0)btnRedo.disabled=true
}
</script>
</body>
</HTML> [Ctrl+A 全选 Ctrl+C 复制,如不能正常显示请刷新一下] |
|
很牛X的右键菜单
|
以下是代码: <HTML><HEAD><TITLE>右键菜单</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<STYLE type=text/css>BODY {
FONT-SIZE: 12px;
}
.info{FONT-SIZE: 14px;color:#FFFFFF;font-family:@Tahoma,@宋体;width:20px}
TABLE {
CURSOR: default; FONT-SIZE: 12px; MARGIN: 0px
}
TR {
HEIGHT: 20px
}
TR.over {
BACKGROUND-COLOR: #000080; COLOR: #ffffff; CURSOR: default; FONT-SIZE: 12px
}
TR.out {
BACKGROUND-COLOR: #efefef; COLOR: #000000; FONT-SIZE: 12px
}
DIV.rm_div {
BACKGROUND-COLOR: #efefef; BORDER-BOTTOM: #ffffff 1px outset; BORDER-LEFT: #ffffff 1px outset; BORDER-RIGHT: #ffffff 1px outset; BORDER-TOP: #ffffff 1px outset; DISPLAY: none; FILTER: Alpha(Opacity='95'); HEIGHT: 0px; PADDING-BOTTOM: 1px; PADDING-LEFT: 1px; PADDING-RIGHT: 1px; PADDING-TOP: 1px; POSITION: absolute; WIDTH: 0px
}
HR.sperator {
BORDER-BOTTOM: #ffffff 1px inset; BORDER-LEFT: #ffffff 1px inset; BORDER-RIGHT: #ffffff 1px inset; BORDER-TOP: #ffffff 1px inset; WIDTH: 95%
}
.w2kfont {
FONT-FAMILY: Tahoma; FONT-SIZE: 8pt
}
</STYLE>
<SCRIPT language=JScript>
<!--
function RightMenu()
{
this.AddExtendMenu=AddExtendMenu;
this.AddItem=AddItem;
this.GetMenu=GetMenu;
this.HideAll=HideAll;
this.I_OnMouseOver=I_OnMouseOver;
this.I_OnMouseOut=I_OnMouseOut;
this.I_OnMouseUp=I_OnMouseUp;
this.P_OnMouseOver=P_OnMouseOver;
this.P_OnMouseOut=P_OnMouseOut;
A_rbpm = new Array();
HTMLstr = "";
HTMLstr += "<!-- RightButton PopMenu -->\n";
HTMLstr += "\n";
HTMLstr += "<!-- PopMenu Starts -->\n";
HTMLstr += "<div id='E_rbpm' class='rm_div'>\n";
// rbpm = right button pop menu
HTMLstr += "<table width='100%' border='0' cellspacing='0'>\n";
HTMLstr += "<tr><td height='264' width='20' valign='bottom' bgcolor='#000000' onclick=window.event.cancelBubble=true; class=info>某某制作<br>:<br>某某网站\n";
HTMLstr += "</td><td height='264' width='120' style='padding: 1' valign='bottom'>\n";
HTMLstr += "<table width='100%' border='0' cellspacing='0'>\n";
HTMLstr += "<!-- Insert A Extend Menu or Item On Here For E_rbpm -->\n";
HTMLstr += "</table></td></tr></table>\n";
HTMLstr += "</div>\n";
HTMLstr += "<!-- Insert A Extend_Menu Area on Here For E_rbpm -->";
HTMLstr += "\n";
HTMLstr += "<!-- PopMenu Ends -->\n";
}
function AddExtendMenu(id,img,wh,name,parent)
{
var TempStr = "";
eval("A_"+parent+".length++");
eval("A_"+parent+"[A_"+parent+".length-1] = id"); // 将此项注册到父菜单项的ID数组中去
TempStr += "<div id='E_"+id+"' class='rm_div'>\n";
TempStr += "<table width='100%' border='0' cellspacing='0'>\n";
TempStr += "<!-- Insert A Extend Menu or Item On Here For E_"+id+" -->";
TempStr += "</table>\n";
TempStr += "</div>\n";
TempStr += "<!-- Insert A Extend_Menu Area on Here For E_"+id+" -->";
TempStr += "<!-- Insert A Extend_Menu Area on Here For E_"+parent+" -->";
HTMLstr = HTMLstr.replace("<!-- Insert A Extend_Menu Area on Here For E_"+parent+" -->",TempStr);
eval("A_"+id+" = new Array()");
TempStr = "";
TempStr += "<!-- Extend Item : P_"+id+" -->\n";
TempStr += "<tr id='P_"+id+"' class='out'";
TempStr += " onmouseover='P_OnMouseOver(\""+id+"\",\""+parent+"\")'";
TempStr += " onmouseout='P_OnMouseOut(\""+id+"\",\""+parent+"\")'";
TempStr += " onmouseup=window.event.cancelBubble=true;";
TempStr += " onclick=window.event.cancelBubble=true;";
TempStr += "><td nowrap>";
TempStr += "<font face='Wingdings' style='font-size:18px'>0</font> "+name+"  </td><td style='font-family: webdings; text-align: ;'>4";
TempStr += "</td></tr>\n";
TempStr += "<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->";
HTMLstr = HTMLstr.replace("<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->",TempStr);
}
function AddItem(id,img,wh,name,parent,location)
{
var TempStr = "";
var ItemStr = "<!-- ITEM : I_"+id+" -->";
if(id == "sperator")
{
TempStr += ItemStr+"\n";
TempStr += "<tr class='out' onclick='window.event.cancelBubble=true;' onmouseup='window.event.cancelBubble=true;'><td colspan='2' height='1'><hr class='sperator'></td></tr>";
TempStr += "<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->";
HTMLstr = HTMLstr.replace("<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->",TempStr);
return;
}
if(HTMLstr.indexOf(ItemStr) != -1)
{
alert("I_"+id+"already exist!");
return;
}
TempStr += ItemStr+"\n";
TempStr += "<tr id='I_"+id+"' class='out'";
TempStr += " onmouseover='I_OnMouseOver(\""+id+"\",\""+parent+"\")'";
TempStr += " onmouseout='I_OnMouseOut(\""+id+"\")'";
TempStr += " onclick='window.event.cancelBubble=true;'";
if(location == null)
TempStr += " onmouseup='I_OnMouseUp(\""+id+"\",\""+parent+"\",null)'";
else
TempStr += " onmouseup='I_OnMouseUp(\""+id+"\",\""+parent+"\",\""+location+"\")'";
TempStr += "><td nowrap>";
TempStr +="<font face='Wingdings' style='font-size:18px'>"+wh+"</font> "+ name+" ";
TempStr += "</td><td></td></tr>\n";
TempStr += "<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->";
HTMLstr = HTMLstr.replace("<!-- Insert A Extend Menu or Item On Here For E_"+parent+" -->",TempStr);
}
function GetMenu()
{
return HTMLstr;
}
function I_OnMouseOver(id,parent)
{
var Item;
if(parent != "rbpm")
{
var ParentItem;
ParentItem = eval("P_"+parent);
ParentItem.className="over";
}
Item = eval("I_"+id);
Item.className="over";
HideAll(parent,1);
}
function I_OnMouseOut(id)
{
var Item;
Item = eval("I_"+id);
Item.className="out";
}
function I_OnMouseUp(id,parent,location)
{
var ParentMenu;
window.event.cancelBubble=true;
OnClick();
ParentMenu = eval("E_"+parent);
ParentMenu.display="none";
if(location == null)
eval("Do_"+id+"()");
else
window.open(location);
}
function P_OnMouseOver(id,parent)
{
var Item;
var Extend;
var Parent;
if(parent != "rbpm")
{
var ParentItem;
ParentItem = eval("P_"+parent);
ParentItem.className="over";
}
HideAll(parent,1);
Item = eval("P_"+id);
Extend = eval("E_"+id);
Parent = eval("E_"+parent);
Item.className="over";
Extend.style.display="block";
Extend.style.posLeft=document.body.scrollLeft+Parent.offsetLeft+Parent.offsetWidth-4;
if(Extend.style.posLeft+Extend.offsetWidth > document.body.scrollLeft+document.body.clientWidth)
Extend.style.posLeft=Extend.style.posLeft-Parent.offsetWidth-Extend.offsetWidth+8;
if(Extend.style.posLeft < 0) Extend.style.posLeft=document.body.scrollLeft+Parent.offsetLeft+Parent.offsetWidth;
Extend.style.posTop=Parent.offsetTop+Item.offsetTop+1;
if(Extend.style.posTop+Extend.offsetHeight > document.body.scrollTop+document.body.clientHeight)
Extend.style.posTop=document.body.scrollTop+document.body.clientHeight-Extend.offsetHeight;
if(Extend.style.posTop < 0) Extend.style.posTop=0;
}
function P_OnMouseOut(id,parent)
{
}
function HideAll(id,flag)
{
var Area;
var Temp;
var i;
if(!flag)
{
Temp = eval("E_"+id);
Temp.style.display="none";
}
Area = eval("A_"+id);
if(Area.length)
{
for(i=0; i < Area.length; i++)
{
HideAll(Area[i],0);
Temp = eval("E_"+Area[i]);
Temp.style.display="none";
Temp = eval("P_"+Area[i]);
Temp.className="out";
}
}
}
document.onmouseup=OnMouseUp;
document.onclick=OnClick;
function OnMouseUp()
{
if(window.event.button == 2)
{
var PopMenu;
PopMenu = eval("E_rbpm");
HideAll("rbpm",0);
PopMenu.style.display="block";
PopMenu.style.posLeft=document.body.scrollLeft+window.event.clientX;
PopMenu.style.posTop=document.body.scrollTop+window.event.clientY;
if(PopMenu.style.posLeft+PopMenu.offsetWidth > document.body.scrollLeft+document.body.clientWidth)
PopMenu.style.posLeft=document.body.scrollLeft+document.body.clientWidth-PopMenu.offsetWidth;
if(PopMenu.style.posLeft < 0) PopMenu.style.posLeft=0;
if(PopMenu.style.posTop+PopMenu.offsetHeight > document.body.scrollTop+document.body.clientHeight)
PopMenu.style.posTop=document.body.scrollTop+document.body.clientHeight-PopMenu.offsetHeight;
if(PopMenu.style.posTop < 0) PopMenu.style.posTop=0;
}
}
function OnClick()
{
HideAll("rbpm",0);
}
// Add Your Function on following
function Do_viewcode(){window.location="view-source:"+window.location.href;}
function Do_help(){window.showHelp(window.location);}
function Do_exit() {window.close();}
function Do_refresh() {window.location.reload();}
function Do_back() {history.back();}
function Do_forward() {history.forward();}
function Do_help(){
var s_help='<style>body,td{font:menu;padding:2}</style>';
s_help+='<title>帮助-www.51windows.Net</title>';
s_help+='<body bgcolor=menu>';
s_help+='<br> 欢迎光临无忧视窗!本系统和您的Windows系统操作很相似。单击开始,打开开始菜单,双击桌面图标打开相关文件!<span style="color:blue;cursor:hand" onclick=showHelp("windows.chm::/MS-ITS:ntdef.chm::/default.htm")>本机帮助..</span>';
showModalDialog("about:"+s_help+"","","dialogHeight:110px;dialogWidth:210px;help:yes;status:no")}
-->
</SCRIPT>
<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
<BODY bgColor=#336699 oncontextmenu=window.event.returnValue=false>
<DIV id=snwcwt> 请点击右键</DIV>
<SCRIPT language=JScript>
<!--
var menu = new RightMenu();
menu.AddItem("update","start_update","4","<font class=w2kfont>Web Update</font>","rbpm","http://");
menu.AddItem("suan","suan","a","大蒜之乡","rbpm","http://");
menu.AddItem("sperator","","","","rbpm",null);
menu.AddExtendMenu("program","start_pro","24","程序<font class=w2kfont>(<u>P</u>)</font>","rbpm",null);
menu.AddExtendMenu("p_acc","folder","+","附件","program",null);
menu.AddItem("p_acc1","html","+","<font class=w2kfont>Microsoft FrontPage 2000</font>","program","51w/game/");
menu.AddItem("p_acc2","html","+","<font class=w2kfont>Norton AntiVirus Corporate Edition</font>","program","http://");
menu.AddExtendMenu("p_lgame","folder","16","小游戏","p_acc",null);
menu.AddItem("p_game1","folder","+","扫雷","p_lgame","51w/game/");
menu.AddItem("p_game2","folder","+","超级玛力","p_lgame","51w/game/");
menu.AddItem("p_game3","folder","+","五子棋","p_lgame","51w/game/");
menu.AddItem("p_game4","folder","+","俄罗斯方块","p_lgame","51w/game/");
menu.AddExtendMenu("doc","start_doc","24","文档<font class=w2kfont>(<u>D</u>)</font>","rbpm",null);
menu.AddItem("d_photo","folder","+","我的邮票","doc",null);
menu.AddExtendMenu("fav","start_fav","24","收藏<font class=w2kfont>(<u>A</u>)</font>","rbpm",null);
menu.AddExtendMenu("f_bbs","folder","16","论坛","fav",null);
menu.AddItem("f_bbs1","html","+","蓝色理想","f_bbs","http://www.blueidea.com/bbs/");
menu.AddItem("f_bbs2","html","+","无忧脚本","f_bbs","http://www.51js.com/");
menu.AddItem("f_bbs3","html","+","CSDN专家门诊","f_bbs","http://www.csdn.net/Expert/");
menu.AddItem("f_bbs4","html","+","洪恩在线网上交流","f_bbs","http://");
menu.AddExtendMenu("f_webpage","folder","16","网页制作","fav",null);
menu.AddItem("f_webpage1","html","","<font disabled>(空)</font>","f_webpage","http://");
menu.AddExtendMenu("f_study","folder","16","网上学习","fav",null);
menu.AddItem("f_s1","html","","<font disabled>(空)</font>","f_study","http://matrix.hongen.com/forum/");
menu.AddExtendMenu("f_link","folder","16","友情链接","fav",null);
menu.AddItem("f_link1","html","+","无忧视窗","f_link","http://www.51windows.com");
menu.AddExtendMenu("setting","start_set","24","设置<font class=w2kfont>(<u>S</u>)</font>","rbpm",null);
menu.AddItem("s_panel","folder","+","控制面板(C)","setting","http://");
menu.AddItem("sperator","","","","setting",null);
menu.AddItem("s_data","s_user","+","用户资料(D)","setting","http://");
menu.AddItem("s_display1","s_taskbar","+","任务栏和开始菜单(T)","setting","http://");
menu.AddExtendMenu("find","start_find","24","查找<font class=w2kfont>(<u>F</u>)","rbpm",null);
menu.AddItem("l_search","search","4","文件或文件夹上(<u>F</u>)...","find","http://");
menu.AddItem("i_search","esearch","4","在Internet上(<u>I</u>)...","find","http://");
menu.AddItem("u_search","f_user","4","用户(<u>P</u>)...","find","http://");
menu.AddItem("help","start_help","V"," 帮助<font class=w2kfont>(<u>H</u>)</font>","rbpm",null);
menu.AddItem("sperator","","","","rbpm",null);
menu.AddItem("logoff","start_logoff","v"," 注销<font class=w2kfont>(<u>L</u>)</font>","rbpm",null);
menu.AddItem("shut","start_shut","x","退出<font class=w2kfont>(<u>U</u>)</font>","rbpm",null);
document.writeln(menu.GetMenu());
-->
</SCRIPT>
</TD></TR></TABLE></BODY></HTML> [Ctrl+A 全选 Ctrl+C 复制,如不能正常显示请刷新一下] |
|
利用鼠标中键缩放图片
|
这个自然是javascript需要做的事。鼠标中键的事件是onmousewheel,以下是一个示例的html代码。其中加入了一下onload事件,他判断图片的宽度是否大于200,是的话,将其设为200,以防止图片过大,影响页面的排版。
以下是代码: <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>利用鼠标中键缩放图片</title>
<script language="JavaScript">
function bbimg(o){
var zoom=parseInt(o.style.zoom, 10)||100;
zoom+=event.wheelDelta/12;
if (zoom>0)
o.style.zoom=zoom+'%';
return false;
}
</script>
</head>
<body>
<center><img src="uploadfile/2005115214625668.JPG" onload="if(this.width>200)this.width=200" onmousewheel = "bbimg(this);"></center>
</body>
</html>
[Ctrl+A 全选 Ctrl+C 复制,如不能正常显示请刷新一下] |
|
EXISTS 和 ALL
|
EXISTS使用了一个子查询作为条件,只有当子查询返回行的时候这个条件才为真,如果子查询不返回任何的行条件就为假。如果商店在处理Chair的时候,有个顾客想看看所有拥有者的列表,就可以使用EXSIST,语句如下:
SELECT OWNERFIRSTNAME, OWNERLASTNAME
FROM ANTIQUEOWNERS
WHERE EXISTS
(SELECT *
FROM ANTIQUES
WHERE ITEM = 'Chair');
如果在Antiques列中有Chair,那么子查询就会返回一行或者多行,就使得EXISTS子句为真,然后让SQL列出拥有者来。如果没有搜索到Chair,则没有行被返回,条件就为假。
ALL是另外一个不寻常的关键字,因为ALL查询通常可以用不同的方法来进行,并且可能是一种更为简单的方法。举个例子来说明吧:
SELECT BUYERID, ITEM
FROM ANTIQUES
WHERE PRICE >= ALL
(SELECT PRICE
FROM ANTIQUES);
上面这条语句将返回最高价格的Item以及它的买方。子查询返回了Antiques表中的所有的Price列,而外层的查询逐行查询Antiques表,并且如果它的Price大于等于(或者ALL)列中的Prices,它就会被列出,它就是最好价格的Item。这里必须使用">="的原因是最高价格的Item要等于列表中的最高价格,因为这个Item在Price列中。 |
|
ACCESS中使用SQL语句应注意的地方及几点技巧
|
以下SQL语句在ACCESS XP的查询中测试通过 建表: Create Table Tab1 ( ID Counter, Name string, Age integer, [Date] DateTime); 技巧: 自增字段用 Counter 声明. 字段名为关键字的字段用方括号[]括起来,数字作为字段名也可行.
建立索引: 下面的语句在Tab1的Date列上建立可重复索引 Create Index iDate ON Tab1 ([Date]); 完成后ACCESS中字段Date索引属性显示为 - 有(有重复). 下面的语句在Tab1的Name列上建立不可重复索引 Create Unique Index iName ON Tab1 (Name); 完成后ACCESS中字段Name索引属性显示为 - 有(无重复). 下面的语句删除刚才建立的两个索引 Drop Index iDate ON Tab1; Drop Index iName ON Tab1;
ACCESS与SQLSERVER中的UPDATE语句对比: SQLSERVER中更新多表的UPDATE语句: UPDATE Tab1 SET a.Name = b.Name FROM Tab1 a,Tab2 b WHERE a.ID = b.ID; 同样功能的SQL语句在ACCESS中应该是 UPDATE Tab1 a,Tab2 b SET a.Name = b.Name WHERE a.ID = b.ID; 即:ACCESS中的UPDATE语句没有FROM子句,所有引用的表都列在UPDATE关键字后. 上例中如果Tab2可以不是一个表,而是一个查询,例: UPDATE Tab1 a,(Select ID,Name From Tab2) b SET a.Name = b.Name WHERE a.ID = b.ID;
访问多个不同的ACCESS数据库-在SQL中使用In子句: Select a.*,b.* From Tab1 a,Tab2 b In 'db2.mdb' Where a.ID=b.ID; 上面的SQL语句查询出当前数据库中Tab1和db2.mdb(当前文件夹中)中Tab2以ID为关联的所有记录. 缺点-外部数据库不能带密码.
在ACCESS中访问其它ODBC数据源 下例在ACCESS中查询SQLSERVER中的数据 SELECT * FROM Tab1 IN [ODBC] [ODBC;Driver=SQL Server;UID=sa;PWD=;Server=127.0.0.1;DataBase=Demo;] 外部数据源连接属性的完整参数是: [ODBC;DRIVER=driver;SERVER=server;DATABASE=database;UID=user;PWD=password;] 其中的DRIVER=driver可以在注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ 中找到
ACCESS支持子查询
ACCESS支持外连接,但不包括完整外部联接,如支持 LEFT JOIN 或 RIGHT JOIN 但不支持 FULL OUTER JOIN 或 FULL JOIN
ACCESS中的日期查询 注意:ACCESS中的日期时间分隔符是#而不是引号 Select * From Tab1 Where [Date]>#2002-1-1#; 在DELPHI中我这样用 SQL.Add(Format( 'Select * From Tab1 Where [Date]>#%s#;', [DateToStr(Date)]));
ACCESS中的字符串可以用双引号分隔,但SQLSERVER不认,所以为了迁移方便和兼容, 建议用单引号作为字符串分隔符. |
|
SQL Server联机丛书:删除存储过程
|
删除存储过程不再需要存储过程时可将其删除。如果另一个存储过程调用某个已删除的存储过程,则 Microsoft® SQL Server™ 2000 会在执行该调用过程时显示一条错误信息。但如果定义了同名和参数相同的新存储过程来替换已删除存储过程,那么引用该过程的其它过程仍能顺利执行。例如,如果存储过程 proc1 引用存储过程 proc2,而 proc2 被删除,但由创建了另一个名为 proc2 的存储过程,现在 proc1 将引用这一新存储过程,proc1 也不必重新编译。
存储过程分组后,将无法删除组内的单个存储过程。删除一个存储过程会将同一组内的所有存储过程都删除。
DROP PROCEDURE
从当前数据库中删除一个或多个存储过程或过程组。
语法
DROP PROCEDURE { procedure } [ ,...n ]
参数
procedure
是要删除的存储过程或存储过程组的名称。过程名称必须符合标识符规则。有关更多信息,请参见使用标识符。可以选择是否指定过程所有者名称,但不能指定服务器名称和数据库名称。
n
是表示可以指定多个过程的占位符。
注释
若要查看过程名称列表,请使用 sp_help。若要显示过程定义(存储在 syscomments 系统表内),请使用 sp_helptext。除去某个存储过程时,将从 sysobjects 和 syscomments 系统表中删除有关该过程的信息。
不能除去组内的个别过程,必须除去整个过程组。
不论用户定义的系统过程(以 sp_ 为前缀)是否为当前数据库,都将其从 master 数据库中除去。如果在当前的数据库未找到系统过程,则 Microsoft® SQL Server™ 尝试将其从 master 数据库除去。
权限
默认情况下,将 DROP PROCEDURE 权限授予过程所有者,该权限不可转让。然而,db_owner 和 db_ddladmin 固定数据库角色成员和 sysadmin 固定服务器角色成员可以通过在 DROP PROCEDURE 内指定所有者除去任何对象。
示例
下例删除 byroyalty 存储过程(在当前数据库内)。DROP PROCEDURE byroyalty
GO
|
|
SQL Server联机丛书:查看存储过程
|
几个系统存储过程用系统表提供有关存储过程的信息。使用这些存储过程可以:
查看用于创建存储过程的 Transact-SQL 语句。这对于没有用于创建存储过程的 Transact-SQL 脚本文件的用户是很有用的。
获得有关存储过程的信息(如存储过程的所有者、创建时间及其参数)。
列出指定存储过程所使用的对象及使用指定存储过程的过程。此信息可用来识别那些受数据库中某个对象的更改或删除影响的过程。
查看存储过程的定义
sp_helptext
显示规则、默认值、未加密的存储过程、用户定义函数、触发器或视图的文本。
语法
sp_helptext [ @objname = ] 'name'
参数
[@objname =] 'name'
对象的名称,将显示该对象的定义信息。对象必须在当前数据库中。name 的数据类型为 nvarchar(776),没有默认值。
返回代码值
0(成功)或 1(失败)
结果集
列名
数据类型
描述
Text
nvarchar(255)
对象定义文本
注释
sp_helptext 在多个行中显示用来创建对象的文本,其中每行有 Transact-SQL 定义的 255 个字符。这些定义只驻留在当前数据库的 syscomments 表的文本中。
权限
执行权限默认授予 public 角色。
示例
下面的示例显示 employee_insupd 触发器的文本,该触发器在数据库 pubs 中。USE pubs
EXEC sp_helptext 'employee_insupd'
查看有关存储过程的信息 sp_help
报告有关数据库对象(sysobjects 表中列出的任何对象)、用户定义数据类型或 Microsoft® SQL Server™ 所提供的数据类型的信息。
语法
sp_help [ [ @objname = ] name ]
参数
[@objname =] name
是 sysobjects 中的任意对象的名称,或者是在 systypes 表中任何用户定义数据类型的名称。Name 的数据类型为 nvarchar(776),默认值为 NULL。不能使用数据库名称。
返回代码值
0(成功)或 1(失败)
结果集
返回的结果集取决于 name 是否已指定、何时指定以及它是何种数据库对象等因素。
如果执行不带参数的 sp_help,则返回当前数据库中现有的所有类型对象的摘要信息。
列名
数据类型
描述
Name
nvarchar(128)
对象名
Owner
nvarchar(128)
对象所有者
Object_type
nvarchar(31)
对象类型
如果 name 是 SQL Server 数据类型或用户定义数据类型,则 sp_help 返回此结果集。
列名
数据类型
描述
Type_name
nvarchar(128)
数据类型名称。
Storage_type
nvarchar(128)
SQL Server 类型名称。
Length
smallint
数据类型的物理长度(以字节为单位)。
Prec
int
精度(总的数字位数)。
Scale
int
小数点右边的数字位数。
Nullable
varchar(35)
指明是否允许 NULL 值:是或否。
Default_name
nvarchar(128)
绑定到该类型的默认值名称。如果没有绑定默认值,则为 NULL。
Rule_name
nvarchar(128)
绑定到该类型的规则名称。如果没有绑定默认值,则为 NULL。
Collation
sysname
数据类型的排序规则。如果是非字符数据类型,则为 NULL。
如果 name 是任意数据库对象(而不是数据类型),那么 sp_help 将返回此结果集,以及基于指定对象类型的其它结果集。
列名
数据类型
描述
Name
nvarchar(128)
表名
Owner
nvarchar(128)
表的所有者
Type
nvarchar(31)
表的类型
Created_datetime
datetime
创建的日期表
根据指定的数据库对象,sp_help 返回其它结果集。
如果 name 是系统表、用户表或者视图,则 sp_help 返回这些结果集(例外,对于视图,不返回描述数据文件在文件组中所处位置的结果集)。
按列对象返回其它结果集:
列名
数据类型
描述
Column_name
nvarchar(128)
列名。
Type
nvarchar(128)
列数据类型。
Computed
varchar(35)
指出是否计算了在列中的值:(是或否)。
Length
int
以字节为单位的列长度。
Prec
char(5)
列精度。
Scale
char(5)
列数值范围。
Nullable
varchar(35)
指出在列中是否允许 NULL 值:是或否。
TrimTrailingBlanks
varchar(35)
剪裁尾随空格(是或否)。
FixedLenNullInSource
varchar(35)
只是为了向后兼容。
Collation
sysname
列的排序规则。如果是非字符数据类型,则为 NULL。
按标识列返回的其它结果集:
列名
数据类型
描述
Identity
nvarchar(128)
其数据类型被声明为标识的列名。
Seed
numeric
标识列的起始值。
Increment
numeric
此列中的值所使用的增量。
Not For Replication
int
当重复登录(例如 sqlrepl)试图在表中插入数据时,无法强制使用 IDENTITY 属性: 1 = True 0 = False
按列返回的其它结果集:
列名
数据类型
描述
RowGuidCol
sysname
全局唯一标识符列的名称。
按文件组返回的其它结果集:
列名
数据类型
描述
Data_located_on_filegroup
nvarchar(128)
数据所在的文件组(主要文件组、次要文件组或事务日志)。
按索引返回的其它结果集:
列名
数据类型
描述
index_name
sysname
索引名。
index_description
varchar(210)
索引的描述。
index_keys
nvarchar(2078)
生成索引所在列的列名。
按约束返回的其它结果集
列名
数据类型
描述
constrain_type
nvarchar(146)
约束的类型。
constrain_name
nvarchar(128)
约束名。
delete_action
nvarchar(9)
指明 DELETE 操作是:无操作、层叠或暂缺。
(仅适用于 FOREIGN KEY 约束。)
update_action
nvarchar(9)
指明 UPDATE 操作是:无操作、层叠或暂缺。
(仅适用于 FOREIGN KEY 约束。)
status_enabled
varchar(8)
指明是否启用约束:启用、禁用或暂缺。(仅适用于 CHECK 和 FOREIGN KEY 约束。)
Status_for_replication
varchar(19)
指明约束是否用于复制。(仅适用于 CHECK 和 FOREIGN KEY 约束。)
constrain_keys
nvarchar(2078)
构成约束的列名。或者(对于默认值和规则而言)指定义默认值或规则的文本。
按引用对象返回的其它结果集:
列名
数据类型
描述
Table is referenced by
nvarchar(516)
识别引用表的其它数据库对象。
如果 name 是系统存储过程或扩展存储过程,那么 sp_help 将返回此结果集。
列名
数据类型
描述
Parameter_name
nvarchar(128)
存储过程参数名。
Type
nvarchar(128)
存储过程参数的数据类型。
Length
smallint
最大物理存储长度(以字节为单位)。
Prec
int
精度(总的数字位数)。
Scale
int
小数点右边的数字个数。
Param_order
smallint
参数的顺序。
注释
sp_help 过程仅在当前数据库中查找对象。
当没有指定 name 时,sp_helptrigger 列出当前数据库中所有对象的名称、所有者和对象类型。sp_helptrigger 提供有关触发器的信息。
权限
执行权限默认授予 public 角色。
示例
A. 返回有关所有对象的信息
下面的示例列出有关 sysobjects 中每个对象的信息。USE master
EXEC sp_help
B. 返回有关单个对象的信息
下面的示例显示有关 publishers 表的信息。USE pubs
EXEC sp_help publishers
查看存储过程的相关性 sp_depends显示有关数据库对象相关性的信息(例如,依赖表或视图的视图和过程,以及视图或过程所依赖的表和视图)。 不报告对当前数据库以外对象的引用。语法sp_depends [ @objname = ] 'object' 参数[@objname =] 'object'被检查相关性的数据库对象。对象可以是表、视图、存储过程或触发器。Object 的数据类型为 varchar(776),没有默认值。返回代码值0(成功)或 1(失败)结果集sp_depends 显示两个结果集。下面的结果集显示 object 所依赖的对象。列名数据类型描述namenvarchar(40)存在相关性的项目名称。typenvarchar(16)项目类型。updatednvarchar(7)是否更新项目。selectednvarchar(8)项目是否用于 SELECT 语句。columnsysname存在相关性的列或参数。 下面的结果集显示依赖 object 的对象。列名数据类型描述namenvarchar(40)存在相关性的项目名称。typenvarchar(16)项目类型。 注释若一个对象引用另一个对象,则认为前者依赖后者。sp_depends 通过查看 sysdepends 表确定相关性。权限执行权限默认授予 public 角色。示例下面的示例列出依赖 Customers 表的数据库对象。USE Northwind
EXEC sp_depends 'Customers' 查看关于扩展存储过程的信息sp_helpextendedproc显示当前定义的扩展存储过程,以及此过程(函数)所属动态链接库的名称。语法sp_helpextendedproc [ [@funcname = ] 'procedure' ]参数[@funcname =] 'procedure'是要显示其信息的扩展存储过程的名称。procedure 的数据类型为 sysname,默认值为 NULL。返回代码值0(成功)或 1(失败)结果集列名数据类型描述namesysname扩展存储过程的名称。dllnvarchar(255)动态链接库的名称。 注释指定 procedure 时,sp_helpextendedproc 报告指定扩展存储过程的信息。不提供 procedure 时, sp_helpextendedproc 返回全部扩展存储过程的名称,以及每个扩展存储过程所属的 DLL 名称。权限执行权限默认授予 public 角色。示例A. 报告所有扩展存储过程的帮助下面的示例报告所有扩展存储过程的信息。USE master
EXEC sp_helpextendedproc
B. 报告单个扩展存储过程的帮助下面的示例报告 xp_cmdshell 扩展存储过程的信息。USE master
EXEC sp_helpextendedproc xp_cmdshell |
|
SQL Server联机丛书:执行存储过程
|
EXECUTE
执行标量值的用户定义函数、系统过程、用户定义存储过程或扩展存储过程。同时支持 Transact-SQL 批处理内的字符串的执行
若要唤醒调用函数,请使用 EXECUTE stored_procedure 中描述的语法。
语法 执行存储过程:
[ [ EXEC [ UTE ] ] { [ @return_status = ] { procedure_name [ ;number ] | @procedure_name_var } [ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] ] [ ,...n ] [ WITH RECOMPILE ]
执行字符串:
EXEC [ UTE ] ( { @string_variable | [ N ] 'tsql_string' } [ + ...n ] )
参数
@return_status 是一个可选的整型变量,保存存储过程的返回状态。这个变量在用于 EXECUTE 语句前,必须在批处理、存储过程或函数中声明过。
在用于唤醒调用标量值用户定义函数时,@return_status 变量可以是任何标量数据类型。
procedure_name 是拟调用的存储过程的完全合法或者不完全合法的名称。过程名称必须符合标识符规则。有关更多信息,请参见使用标识符。无论服务器的代码页或排序方式如何,扩展存储过程的名称总是区分大小写。 用户可以执行在另一数据库中创建的过程,只要该用户拥有此过程或有在该数据库中执行它的适当的权限。用户可以在另一台运行 Microsoft® SQL Server™ 的服务器上执行过程,只要该用户有适当的权限使用该服务器(远程访问),并能在数据库中执行该过程。如果指定了服务器名称但没有指定数据库名称,SQL Server 会在用户默认的数据库中寻找该过程。
;number 是可选的整数,用于将相同名称的过程进行组合,使得它们可以用一句 DROP PROCEDURE 语句除去。该参数不能用于扩展存储过程。 在同一应用程序中使用的过程一般都以该方式组合。例如,在订购应用程序中使用的过程可以 orderproc;1、orderproc;2 等来命名。DROP PROCEDURE orderproc 语句将除去整个组。在对过程分组后,不能除去组中的单个过程。例如,DROP PROCEDURE orderproc;2 是不允许的。有关过程组的更多信息,请参见 CREATE PROCEDURE。
@procedure_name_var 是局部定义变量名,代表存储过程名称。
@parameter 是过程参数,在 CREATE PROCEDURE 语句中定义。参数名称前必须加上符号 (@)。在以 @parameter_name = value 格式使用时,参数名称和常量不一定按照 CREATE PROCEDURE 语句中定义的顺序出现。但是,如果有一个参数使用 @parameter_name = value 格式,则其它所有参数都必须使用这种格式。 默认情况下,参数可为空。如果传递 NULL 参数值,且该参数用于 CREATE 或 ALTER TABLE 语句中不允许为 NULL 的列(例如,插入至不允许为 NULL 的列),SQL Server 就会报错。为避免将 NULL 参数值传递给不允许为 NULL 的列,可以在过程中添加程序设计逻辑或采用默认值(使用 CREATE 或 ALTER TABLE 语句中的 DEFAULT 关键字)。
value 是过程中参数的值。如果参数名称没有指定,参数值必须以 CREATE PROCEDURE 语句中定义的顺序给出。 如果参数值是一个对象名称、字符串或通过数据库名称或所有者名称进行限制,则整个名称必须用单引号括起来。如果参数值是一个关键字,则该关键字必须用双引号括起来。
如果在 CREATE PROCEDURE 语句中定义了默认值,用户执行该过程时可以不必指定参数。如果该过程使用了带 LIKE 关键字的参数名称,则默认值必须是常量,并且可以包含 %、_、[ ] 及 [^] 通配符。 默认值也可以为 NULL。通常,过程定义会指定当参数值为 NULL 时应该执行的操作。
@variable 是用来保存参数或者返回参数的变量。
OUTPUT 指定存储过程必须返回一个参数。该存储过程的匹配参数也必须由关键字 OUTPUT 创建。使用游标变量作参数时使用该关键字。 如果使用 OUTPUT 参数,目的是在调用批处理或过程的其它语句中使用其返回值,则参数值必须作为变量传递(即 @parameter = @variable)。如果一个参数在 CREATE PROCEDURE 语句中不是定义为 OUTPUT 参数,则对该参数指定 OUTPUT 的过程不能执行。不能使用 OUTPUT 将常量传递给存储过程;返回参数需要变量名称。在执行过程之前,必须声明变量的数据类型并赋值。返回参数可以是 text 或 image 数据类型以外的任意数据类型。
DEFAULT 根据过程的定义,提供参数的默认值。当过程需要的参数值没有事先定义好的默认值,或缺少参数,或指定了 DEFAULT 关键字,就会出错。
n 是占位符,表示在它前面的项目可以多次重复执行。例如,EXECUTE 语句可以指定一个或者多个 @parameter、value 或 @variable。
WITH RECOMPILE 强制编译新的计划。如果所提供的参数为非典型参数或者数据有很大的改变,使用该选项。在以后的程序执行中使用更改过的计划。该选项不能用于扩展存储过程。建议尽量少使用该选项,因为它消耗较多系统资源。
@string_variable 是局部变量的名称。@string_variable 可以是 char、varchar、nchar 或 nvarchar 数据类型,最大值为服务器的可用内存。如果字符串长度超过 4,000 个字符,则把多个局部变量串联起来用于 EXECUTE 字符串。有关系统提供的 SQL Server 数据类型更多的信息,请参见数据类型。
[N]'tsql_string' 是一个常量,tsql_string 可以是 nvarchar 或 varchar 数据类型。如果包含 N,则该字符串将解释为 nvarchar 数据类型,最大值为服务器的可用内存。如果字符串长度超过 4,000 个字符,则把多个局部变量串联起来用于 EXECUTE 字符串。
注释
如果过程名称的前三个字符为 sp_,SQL Server 会在 Master 数据库中寻找该过程。如果没能找到合法的过程名称,SQL Server 会寻找所有者名称为 dbo 的过程。若要将存储过程名称解析为与系统存储过程同名的用户定义存储过程,请提供一个完全合法的过程名称。
参数可以通过利用 value 或 @parameter_name = value 来提供。参数不是事务的一个部分;因而如果事务中的参数值更改,且该事务在以后回滚,该参数值不会退回到以前的值。返回给调用方的值总是过程返回时的值。
当一个存储过程调用另一个存储过程时,会产生嵌套。当调用的过程开始执行时,嵌套级会增加,当调用过程执行结束时,嵌套级则会减少。嵌套级最高为32级,超过32级时,会导致整个调用过程链失败。当前的嵌套级存储在 @@NESTLEVEL 函数中。
SQL Server 目前使用返回值 0 到 -14 来表示存储过程的执行状态。值 –15 到 -99 留作后用。有关保留的返回状态值的列表的更多信息,请参见 RETURN。
因为远程存储过程和扩展存储过程不在事务的作用域中(除非在 BEGIN DISTRIBUTED TRANSACTION 语句中发出或者是和不同的配置选项一起使用),所以通过调用执行的命令不能回滚。有关更多信息,请参见系统存储过程和 BEGIN DISTRIBUTED TRANSACTION。
当使用游标变量时,如果执行的过程传递一个分配有游标的游标变量,就会出错。
在执行存储过程时,如果语句是批处理中的第一个语句,则不一定要指定 EXECUTE 关键字。
使用带字符串的 EXECUTE 命令
使用字符串串联运算符 (+) 为动态执行创建长字符串。每个字符串表达式可以是 Unicode 与 non-Unicode 数据类型的混合。
尽管每个 [N] 'tsql_string' 或 @string_variable 不得超过 8,000 个字节,SQL Server 语法分析器中对这种串联只进行逻辑处理而不占用物理内存。例如,该语句决不会生成长 16,000 个串联起来的字符串:
EXEC('name_of_8000_char_string' + 'another_name_of_8000_char_string')
在 EXECUTE 语句执行前,不会编译 EXECUTE 语句内的语句。 数据库环境的更改只在 EXECUTE 语句结束前有效。例如,在这个例子的 EXEC 后,数据库环境是 master:
USE master EXEC ("USE pubs") SELECT * FROM authors
权限
存储过程的 EXECUTE 权限默认给该存储过程的所有者,该所有者可以将此权限转让给其他用户。当遇到 EXECUTE 语句时,即使 EXECUTE 语句是在存储过程中,也会检查在 EXECUTE 字符串内使用该语句的权限。当运行一个执行字符串的存储过程时,系统会在执行该过程的用户环境中,而不是在创建该过程的用户环境中检查权限。但是,如果某用户拥有两个存储过程,并且第一个过程调用第二个过程,则在第二个过程中不进行 EXECUTE 权限检查。
示例
A. 使用 EXECUTE 传递单个参数
showind 存储过程需要参数 (@tabname),它是一个表的名称。下面这个例子执行 showind 存储过程,以 titles 为参数值。
说明 showind 存储过程只是用来作为一个例子,pubs 数据库并没有此过程。
EXEC showind titles 在执行过程中变量可以显式命名: EXEC showind @tabname = titles
如果这是 isql 脚本或批处理中第一个语句,则 EXEC 语句可以省略:showind titles -或- showind @tabname = titlesB. 使用多个参数与一个输出参数这个例子执行 roy_check 存储过程,传递三个参数。第三个参数 @pc 是输出参数。过程执行完后,返回变量可以从变量@percent 得到。 说明 roy_check 存储过程只是用作举例,pubs 数据库中并没有此过程。DECLARE @percent int
EXECUTE roy_check 'BU1032', 1050, @pc = @percent OUTPUT
SET Percent = @percent
C.使用带一个变量的 EXECUTE 'tsql_string' 语句这个例子显示 EXECUTE 语句如何处理动态生成的、含有变量的字符串。这个例子创建 tables_cursor 游标来保存所有用户定义表 (type = U) 的列表。 说明 此例子只用作举例。DECLARE tables_cursor CURSOR FOR SELECT name FROM sysobjects WHERE type = 'U' OPEN tables_cursor DECLARE @tablename sysname FETCH NEXT FROM tables_cursor INTO @tablename WHILE (@@FETCH_STATUS <> -1) BEGIN /* A @@FETCH_STATUS of -2 means that the row has been deleted. There is no need to test for this because this loop drops all user-defined tables. */. EXEC ('DROP TABLE ' + @tablename) FETCH NEXT FROM tables_cursor INTO @tablename END PRINT 'All user-defined tables have been dropped from the database.' DEALLOCATE tables_cursorD.使用带远程存储过程的 EXECUTE 语句这个例子在远程服务器 SQLSERVER1 上执行 checkcontract 存储过程,在 @retstat 中保存返回状态,说明运行成功或失败。DECLARE @retstat int EXECUTE @retstat = SQLSERVER1.pubs.dbo.checkcontract '409-56-4008'E. 使用带扩展存储过程的 EXECUTE 语句下例使用 xp_cmdshell 扩展存储过程列出文件扩展名为 .exe 的所有文件的目录。USE master EXECUTE xp_cmdshell 'dir *.exe'F. 使用带一个存储过程变量的 EXECUTE 语句这个例子创建一个代表存储过程名称的变量。DECLARE @proc_name varchar(30) SET @proc_name = 'sp_who' EXEC @proc_name G. 使用带 DEFAULT 的 EXECUTE 语句这个例子创建了一个存储过程,过程中第一个和第三个参数为默认值。当运行该过程时,如果调用时没有传递值或者指定了默认值, 这些默认值就会赋给第一个和第三个参数。注意 DEFAULT 关键字有多种使用方法。 USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'proc_calculate_taxes' AND type = 'P') DROP PROCEDURE proc_calculate_taxes GO -- Create the stored procedure. CREATE PROCEDURE proc_calculate_taxes (@p1 smallint = 42, @p2 char(1), @p3 varchar(8) = 'CAR') AS SELECT * FROM mytableproc_calculate_taxes 存储过程可以以多种组合方式执行: EXECUTE proc_calculate_taxes @p2 = 'A' EXECUTE proc_calculate_taxes 69, 'B' EXECUTE proc_calculate_taxes 69, 'C', 'House' EXECUTE proc_calculate_taxes @p1 = DEFAULT, @p2 = 'D' EXECUTE proc_calculate_taxes DEFAULT, @p3 = 'Local', @p2 = 'E' EXECUTE proc_calculate_taxes 69, 'F', @p3 = DEFAULT EXECUTE proc_calculate_taxes 95, 'G', DEFAULT EXECUTE proc_calculate_taxes DEFAULT, 'H', DEFAULT EXECUTE proc_calculate_taxes DEFAULT, 'I', @p3 = DEFAULT |
|
SQL Server联机丛书:存储过程及其创建
|
存储过程可以使得对数据库的管理、以及显示关于数据库及其用户信息的工作容易得多。存储过程是 SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量、有条件执行以及其它强大的编程功能。
存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数、输出参数、返回单个或多个结果集以及返回值。
可以出于任何使用 SQL 语句的目的来使用存储过程,它具有以下优点:
可以在单个存储过程中执行一系列 SQL 语句。
可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。
存储过程在创建时即在服务器上进行编译,所以执行起来比单个 SQL 语句快。
存储过程的功能取决于数据库所提供的功能。
创建存储过程
可使用 Transact-SQL 语句 CREATE PROCEDURE 创建存储过程。创建存储过程前,请考虑下列事项:
不能将 CREATE PROCEDURE 语句与其它 SQL 语句组合到单个批处理中。
创建存储过程的权限默认属于数据库所有者,该所有者可将此权限授予其他用户。
存储过程是数据库对象,其名称必须遵守标识符规则。
只能在当前数据库中创建存储过程。
创建存储过程时,应指定:
所有输入参数和向调用过程或批处理返回的输出参数。
执行数据库操作(包括调用其它过程)的编程语句。
返回至调用过程或批处理以表明成功或失败(以及失败原因)的状态值。
系统存储过程
Microsoft® SQL Server™ 2000 中的许多管理活动是通过一种称为系统存储过程的特殊过程执行的。系统存储过程在 master 数据库中创建并存储,带有 sp_ 前缀。可从任何数据库中执行系统存储过程,而无需使用 master 数据库名称来完全限定该存储过程的名称。
强烈建议您不要创建以 sp_ 为前缀的存储过程。SQL Server 始终按照下列顺序查找以 sp_ 开头的存储过程:
在 master 数据库中查找存储过程。
根据所提供的任何限定符(数据库名称或所有者)查找该存储过程。
如果未指定所有者,则使用 dbo 作为所有者查找该存储过程。
因此,虽然当前数据库中可能存在带 sp_ 前缀的用户创建的存储过程,但总会先检查 master 数据库(即使该存储过程已用数据库名称限定)。
重要 如果用户创建的存储过程与系统存储过程同名,则永远不执行用户创建的存储过程。
分组
如果将一个不同的标识号赋予某过程,则可以用与现有某存储过程相同的名称创建该过程,这样可允许将这些过程进行逻辑分组。同名的分组过程可以同时删除。在同一应用程序中使用的过程一般都以该方式分组。例如,用于 my_app 应用程序的过程可能被命名为 my_proc;1、my_proc;2 等。删除 my_proc 即删除该整个组。将过程分组后,就无法删除该组内的单个过程。
临时存储过程
专用和全局临时存储过程与临时表类似,都可以用向该过程名称添加 # 和 ## 前缀的方法进行创建。# 表示本地临时存储过程,## 表示全局临时存储过程。SQL Server 关闭后,这些过程将不再存在。
临时存储过程在连接到 SQL Server 的早期版本时很有用,这些早期版本不支持再次使用 Transact-SQL 语句或批处理执行计划。连接到 SQL Server 2000 的应用程序应使用 sp_executesql 系统存储过程,而不使用临时存储过程。有关更多信息,请参见执行计划的高速缓存和重新使用。
只有创建本地临时过程的连接才能执行该过程,当该连接关闭(用户从 SQL Server 中注销)时,将自动删除该过程。
任何连接都可执行全局临时存储过程。只有创建该过程的用户所用的连接关闭,并且所有其它连接所用的该过程的当前执行版本运行完毕后,全局临时存储过程才不再存在。一旦用于创建该过程的连接关闭,将不再允许启动执行该全局临时存储过程。只允许那些已启动执行该存储过程的连接完成该过程的运行。
如果直接在 tempdb 数据库中创建没有 # 或 ## 前缀的存储过程,则由于每次启动 SQL Server 时 tempdb 都要重新创建,因此当关闭 SQL Server 时将自动删除该存储过程。直接在 tempdb 中创建的过程即使在创建该过程的连接终止后也会存在。与任何其它对象一样,可向其他用户授予、拒绝和废除执行该临时存储过程的权限。
CREATE PROCEDURE
创建存储过程,存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL 语句的集合。
可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时过程)。
也可以创建在 Microsoft® SQL Server™ 启动时自动运行的存储过程。
语法
CREATE PROC [ EDURE ] procedure_name [ ; number ] [ { @parameter data_type } [ VARYING ] [ = default ] [ OUTPUT ] ] [ ,...n ]
[ WITH { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
参数
procedure_name
新存储过程的名称。过程名必须符合标识符规则,且对于数据库及其所有者必须唯一。有关更多信息,请参见使用标识符。
要创建局部临时过程,可以在 procedure_name 前面加一个编号符 (#procedure_name),要创建全局临时过程,可以在 procedure_name 前面加两个编号符 (##procedure_name)。完整的名称(包括 # 或 ##)不能超过 128 个字符。指定过程所有者的名称是可选的。
;number
是可选的整数,用来对同名的过程分组,以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。例如,名为 orders 的应用程序使用的过程可以命名为 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 语句将除去整个组。如果名称中包含定界标识符,则数字不应包含在标识符中,只应在 procedure_name 前后使用适当的定界符。
@parameter
过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的默认值)。存储过程最多可以有 2.100 个参数。
使用 @ 符号作为第一个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身;相同的参数名称可以用在其它过程中。默认情况下,参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。有关更多信息,请参见 EXECUTE。
data_type
参数的数据类型。所有数据类型(包括 text、ntext 和 image)均可以用作存储过程的参数。不过,cursor 数据类型只能用于 OUTPUT 参数。如果指定的数据类型为 cursor,也必须同时指定 VARYING 和 OUTPUT 关键字。有关 SQL Server 提供的数据类型及其语法的更多信息,请参见数据类型。
说明 对于可以是 cursor 数据类型的输出参数,没有最大数目的限制。
VARYING
指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变化)。仅适用于游标参数。
default
参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。默认值必须是常量或 NULL。如果过程将对该参数使用 LIKE 关键字,那么默认值中可以包含通配符(%、_、[] 和 [^])。
OUTPUT
表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。使用 OUTPUT 参数可将信息返回给调用过程。Text、ntext 和 image 参数可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以是游标占位符。
n
表示最多可以指定 2.100 个参数的占位符。
{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
RECOMPILE 表明 SQL Server 不会缓存该过程的计划,该过程将在运行时重新编译。在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时,请使用 RECOMPILE 选项。
ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。使用 ENCRYPTION 可防止将过程作为 SQL Server 复制的一部分发布。
说明 在升级过程中,SQL Server 利用存储在 syscomments 中的加密注释来重新创建加密过程。
FOR REPLICATION
指定不能在订阅服务器上执行为复制创建的存储过程。.使用 FOR REPLICATION 选项创建的存储过程可用作存储过程筛选,且只能在复制过程中执行。本选项不能和 WITH RECOMPILE 选项一起使用。
AS
指定过程要执行的操作。
sql_statement
过程中要包含的任意数目和类型的 Transact-SQL 语句。但有一些限制。
n
是表示此过程可以包含多条 Transact-SQL 语句的占位符。
注释
存储过程的最大大小为 128 MB。
用户定义的存储过程只能在当前数据库中创建(临时过程除外,临时过程总是在 tempdb 中创建)。在单个批处理中,CREATE PROCEDURE 语句不能与其它 Transact-SQL 语句组合使用。
默认情况下,参数可为空。如果传递 NULL 参数值并且该参数在 CREATE 或 ALTER TABLE 语句中使用,而该语句中引用的列又不允许使用 NULL,则 SQL Server 会产生一条错误信息。为了防止向不允许使用 NULL 的列传递 NULL 参数值,应向过程中添加编程逻辑或为该列使用默认值(使用 CREATE 或 ALTER TABLE 的 DEFAULT 关键字)。
建议在存储过程的任何 CREATE TABLE 或 ALTER TABLE 语句中都为每列显式指定 NULL 或 NOT NULL,例如在创建临时表时。ANSI_DFLT_ON 和 ANSI_DFLT_OFF 选项控制 SQL Server 为列指派 NULL 或 NOT NULL 特性的方式(如果在 CREATE TABLE 或 ALTER TABLE 语句中没有指定的话)。如果某个连接执行的存储过程对这些选项的设置与创建该过程的连接的设置不同,则为第二个连接创建的表列可能会有不同的为空性,并且表现出不同的行为方式。如果为每个列显式声明了 NULL 或 NOT NULL,那么将对所有执行该存储过程的连接使用相同的为空性创建临时表。
在创建或更改存储过程时,SQL Server 将保存 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 的设置。执行存储过程时,将使用这些原始设置。因此,所有客户端会话的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 设置在执行存储过程时都将被忽略。在存储过程中出现的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 语句不影响存储过程的功能。
其它 SET 选项(例如 SET ARITHABORT、SET ANSI_WARNINGS 或 SET ANSI_PADDINGS)在创建或更改存储过程时不保存。如果存储过程的逻辑取决于特定的设置,应在过程开头添加一条 SET 语句,以确保设置正确。从存储过程中执行 SET 语句时,该设置只在存储过程完成之前有效。之后,设置将恢复为调用存储过程时的值。这使个别的客户端可以设置所需的选项,而不会影响存储过程的逻辑。
说明 SQL Server 是将空字符串解释为单个空格还是解释为真正的空字符串,由兼容级别设置控制。如果兼容级别小于或等于 65,SQL Server 就将空字符串解释为单个空格。如果兼容级别等于 70,则 SQL Server 将空字符串解释为空字符串。有关更多信息,请参见 sp_dbcmptlevel。
获得有关存储过程的信息
若要显示用来创建过程的文本,请在过程所在的数据库中执行 sp_helptext,并使用过程名作为参数。
说明 使用 ENCRYPTION 选项创建的存储过程不能使用 sp_helptext 查看。
若要显示有关过程引用的对象的报表,请使用 sp_depends。
若要为过程重命名,请使用 sp_rename。
引用对象
SQL Server 允许创建的存储过程引用尚不存在的对象。在创建时,只进行语法检查。执行时,如果高速缓存中尚无有效的计划,则编译存储过程以生成执行计划。只有在编译过程中才解析存储过程中引用的所有对象。因此,如果语法正确的存储过程引用了不存在的对象,则仍可以成功创建,但在运行时将失败,因为所引用的对象不存在。有关更多信息,请参见延迟名称解析和编译。
延迟名称解析和兼容级别
SQL Server 允许 Transact-SQL 存储过程在创建时引用不存在的表。这种能力称为延迟名称解析。不过,如果 Transact-SQL 存储过程引用了该存储过程中定义的表,而兼容级别设置(通过执行 sp_dbcmptlevel 来设置)为 65,则在创建时会发出警告信息。而如果在运行时所引用的表不存在,将返回错误信息。有关更多信息,请参见 sp_dbcmptlevel 和延迟名称解析和编译。
执行存储过程
成功执行 CREATE PROCEDURE 语句后,过程名称将存储在 sysobjects 系统表中,而 CREATE PROCEDURE 语句的文本将存储在 syscomments 中。第一次执行时,将编译该过程以确定检索数据的最佳访问计划。
使用 cursor 数据类型的参数
存储过程只能将 cursor 数据类型用于 OUTPUT 参数。如果为某个参数指定了 cursor 数据类型,也必须指定 VARYING 和 OUTPUT 参数。如果为某个参数指定了 VARYING 关键字,则数据类型必须是 cursor,并且必须指定 OUTPUT 关键字。
说明 cursor 数据类型不能通过数据库 API(例如 OLE DB、ODBC、ADO 和 DB-Library)绑定到应用程序变量上。因为必须先绑定 OUTPUT 参数,应用程序才可以执行存储过程,所以带有 cursor OUTPUT 参数的存储过程不能通过数据库 API 调用。只有将 cursor OUTPUT 变量赋值给 Transact-SQL 局部 cursor 变量时,才可以通过 Transact-SQL 批处理、存储过程或触发器调用这些过程。
Cursor 输出参数
在执行过程时,以下规则适用于 cursor 输出参数:
对于只进游标,游标的结果集中返回的行只是那些存储过程执行结束时处于或超出游标位置的行,例如:
在过程中的名为 RS 的 100 行结果集上打开一个非滚动游标。
过程提取结果集 RS 的头 5 行。
过程返回到其调用者。
返回到调用者的结果集 RS 由 RS 的第 6 到 100 行组成,调用者中的游标处于 RS 的第一行之前。
对于只进游标,如果存储过程完成后,游标位于第一行的前面,则整个结果集将返回给调用批处理、存储过程或触发器。返回时,游标将位于第一行的前面。
对于只进游标,如果存储过程完成后,游标的位置超出最后一行的结尾,则为调用批处理、存储过程或触发器返回空结果集。
说明 空结果集与空值不同。
对于可滚动游标,在存储过程执行结束时,结果集中的所有行均会返回给调用批处理、存储过程或触发器。返回时,游标保留在过程中最后一次执行提取时的位置。
对于任意类型的游标,如果游标关闭,则将空值传递回调用批处理、存储过程或触发器。如果将游标指派给一个参数,但该游标从未打开过,也会出现这种情况。
说明 关闭状态只有在返回时才有影响。例如,可以在过程中关闭游标,稍后再打开游标,然后将该游标的结果集返回给调用批处理、存储过程或触发器。
临时存储过程
SQL Server 支持两种临时过程:局部临时过程和全局临时过程。局部临时过程只能由创建该过程的连接使用。全局临时过程则可由所有连接使用。局部临时过程在当前会话结束时自动除去。全局临时过程在使用该过程的最后一个会话结束时除去。通常是在创建该过程的会话结束时。
临时过程用 # 和 ## 命名,可以由任何用户创建。创建过程后,局部过程的所有者是唯一可以使用该过程的用户。执行局部临时过程的权限不能授予其他用户。如果创建了全局临时过程,则所有用户均可以访问该过程,权限不能显式废除。只有在 tempdb 数据库中具有显式 CREATE PROCEDURE 权限的用户,才可以在该数据库中显式创建临时过程(不使用编号符命名)。可以授予或废除这些过程中的权限。
说明 频繁使用临时存储过程会在 tempdb 中的系统表上产生争用,从而对性能产生负面影响。建议使用 sp_executesql 代替。sp_executesql 不在系统表中存储数据,因此可以避免这一问题。
自动执行存储过程
SQL Server 启动时可以自动执行一个或多个存储过程。这些存储过程必须由系统管理员创建,并在 sysadmin 固定服务器角色下作为后台过程执行。这些过程不能有任何输入参数。
对启动过程的数目没有限制,但是要注意,每个启动过程在执行时都会占用一个连接。如果必须在启动时执行多个过程,但不需要并行执行,则可以指定一个过程作为启动过程,让该过程调用其它过程。这样就只占用一个连接。
在启动时恢复了最后一个数据库后,即开始执行存储过程。若要跳过这些存储过程的执行,请将启动参数指定为跟踪标记 4022。如果以最低配置启动 SQL Server(使用 -f 标记),则启动存储过程也不会执行。有关更多信息,请参见跟踪标记。
若要创建启动存储过程,必须作为 sysadmin 固定服务器角色的成员登录,并在 master 数据库中创建存储过程。
使用 sp_procoption 可以:
将现有存储过程指定为启动过程。
停止在 SQL Server 启动时执行过程。
查看 SQL Server 启动时执行的所有过程的列表。
存储过程嵌套
存储过程可以嵌套,即一个存储过程可以调用另一个存储过程。在被调用过程开始执行时,嵌套级将增加,在被调用过程执行结束后,嵌套级将减少。如果超出最大的嵌套级,会使整个调用过程链失败。可用 @@NESTLEVEL 函数返回当前的嵌套级。
若要估计编译后的存储过程大小,请使用下列性能监视计数器。
性能监视器对象名
性能监视计数器名称
SQLServer:缓冲区管理器
高速缓存大小(页面数)
SQLServer:高速缓存管理器
高速缓存命中率
高速缓存页
高速缓存对象计数*
* 各种分类的高速缓存对象均可以使用这些计数器,包括特殊 sql、准备 sql、过程、触发器等。
有关更多信息,请参见 SQL Server:Buffer Manager 对象和 SQL Server:Cache Manager 对象。
sql_statement 限制
除了 SET SHOWPLAN_TEXT 和 SET SHOWPLAN_ALL 之外(这两个语句必须是批处理中仅有的语句),任何 SET 语句均可以在存储过程内部指定。所选择的 SET 选项在存储过程执行过程中有效,之后恢复为原来的设置。
如果其他用户要使用某个存储过程,那么在该存储过程内部,一些语句使用的对象名必须使用对象所有者的名称限定。这些语句包括:
ALTER TABLE
CREATE INDEX
CREATE TABLE
所有 DBCC 语句
DROP TABLE
DROP INDEX
TRUNCATE TABLE
UPDATE STATISTICS
权限
CREATE PROCEDURE 的权限默认授予 sysadmin 固定服务器角色成员和 db_owner 和 db_ddladmin 固定数据库角色成员。sysadmin 固定服务器角色成员和 db_owner 固定数据库角色成员可以将 CREATE PROCEDURE 权限转让给其他用户。执行存储过程的权限授予过程的所有者,该所有者可以为其它数据库用户设置执行权限。
示例
A. 使用带有复杂 SELECT 语句的简单过程
下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info_all' AND type = 'P')
DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
GO
au_info_all 存储过程可以通过以下方法执行:EXECUTE au_info_all
-- Or
EXEC au_info_all
如果该过程是批处理中的第一条语句,则可使用:au_info_all
B. 使用带有参数的简单过程
下面的存储过程从四个表的联接中只返回指定的作者(提供了姓名)、出版的书籍以及出版社。该存储过程接受与传递的参数精确匹配的值。USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info' AND type = 'P')
DROP PROCEDURE au_info
GO
USE pubs
GO
CREATE PROCEDURE au_info
@lastname varchar(40),
@firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
au_info 存储过程可以通过以下方法执行:EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'
如果该过程是批处理中的第一条语句,则可使用:au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'
C. 使用带有通配符参数的简单过程
下面的存储过程从四个表的联接中只返回指定的作者(提供了姓名)、出版的书籍以及出版社。该存储过程对传递的参数进行模式匹配,如果没有提供参数,则使用预设的默认值。USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info2' AND type = 'P')
DROP PROCEDURE au_info2
GO
USE pubs
GO
CREATE PROCEDURE au_info2
@lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname
GO
au_info2 存储过程可以用多种组合执行。下面只列出了部分组合:EXECUTE au_info2
-- Or
EXECUTE au_info2 'Wh%'
-- Or
EXECUTE au_info2 @firstname = 'A%'
-- Or
EXECUTE au_info2 '[CK]ars[OE]n'
-- Or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- Or
EXECUTE au_info2 'H%', 'S%'
D. 使用 OUTPUT 参数
OUTPUT 参数允许外部过程、批处理或多条 Transact-SQL 语句访问在过程执行期间设置的某个值。下面的示例创建一个存储过程 (titles_sum),并使用一个可选的输入参数和一个输出参数。
首先,创建过程:USE pubs
GO
IF EXISTS(SELECT name FROM sysobjects
WHERE name = 'titles_sum' AND type = 'P')
DROP PROCEDURE titles_sum
GO
USE pubs
GO
CREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUT
AS
SELECT 'Title Name' = title
FROM titles
WHERE title LIKE @@TITLE
SELECT @@SUM = SUM(price)
FROM titles
WHERE title LIKE @@TITLE
GO
接下来,将该 OUTPUT 参数用于控制流语言。
说明 OUTPUT 变量必须在创建表和使用该变量时都进行定义。
参数名和变量名不一定要匹配,不过数据类型和参数位置必须匹配(除非使用 @@SUM = variable 形式)。 DECLARE @@TOTALCOST money
EXECUTE titles_sum 'The%', @@TOTALCOST OUTPUT
IF @@TOTALCOST < 200
BEGIN
PRINT ' '
PRINT 'All of these titles can be purchased for less than $200.'
END
ELSE
SELECT 'The total cost of these titles is $'
+ RTRIM(CAST(@@TOTALCOST AS varchar(20)))
下面是结果集:Title Name
------------------------------------------------------------------------
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking
(3 row(s) affected)
Warning, null value eliminated from aggregate.
All of these titles can be purchased for less than $200.
E. 使用 OUTPUT 游标参数
OUTPUT 游标参数用来将存储过程的局部游标传递回调用批处理、存储过程或触发器。
首先,创建以下过程,在 titles 表上声明并打开一个游标:USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'titles_cursor' and type = 'P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT *
FROM titles
OPEN @titles_cursor
GO
接下来,执行一个批处理,声明一个局部游标变量,执行上述过程以将游标赋值给局部变量,然后从该游标提取行。USE pubs
GO
DECLARE @MyCursor CURSOR
EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
F. 使用 WITH RECOMPILE 选项
如果为过程提供的参数不是典型的参数,并且新的执行计划不应高速缓存或存储在内存中,WITH RECOMPILE 子句会很有帮助。USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'titles_by_author' AND type = 'P')
DROP PROCEDURE titles_by_author
GO
CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%'
WITH RECOMPILE
AS
SELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name',
title AS Title
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON ta.title_id = t.title_id
WHERE au_lname LIKE @@LNAME_PATTERN
GO
G. 使用 WITH ENCRYPTION 选项
WITH ENCRYPTION 子句对用户隐藏存储过程的文本。下例创建加密过程,使用 sp_helptext 系统存储过程获取关于加密过程的信息,然后尝试直接从 syscomments 表中获取关于该过程的信息。IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'encrypt_this' AND type = 'P')
DROP PROCEDURE encrypt_this
GO
USE pubs
GO
CREATE PROCEDURE encrypt_this
WITH ENCRYPTION
AS
SELECT *
FROM authors
GO
EXEC sp_helptext encrypt_this
下面是结果集:The object's comments have been encrypted.
接下来,选择加密存储过程内容的标识号和文本。SELECT c.id, c.text
FROM syscomments c INNER JOIN sysobjects o
ON c.id = o.id
WHERE o.name = 'encrypt_this'
下面是结果集:
说明 text 列的输出显示在单独一行中。执行时,该信息将与 id 列信息出现在同一行中。
id text
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????e?????????????????????????????????????????
(1 row(s) affected)
H. 创建用户定义的系统存储过程
下面的示例创建一个过程,显示表名以 emp 开头的所有表及其对应的索引。如果没有指定参数,该过程将返回表名以 sys 开头的所有表(及索引)。IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'sp_showindexes' AND type = 'P')
DROP PROCEDURE sp_showindexes
GO
USE master
GO
CREATE PROCEDURE sp_showindexes
@@TABLE varchar(30) = 'sys%'
AS
SELECT o.name AS TABLE_NAME,
i.name AS INDEX_NAME,
indid AS INDEX_ID
FROM sysindexes i INNER JOIN sysobjects o
ON o.id = i.id
WHERE o.name LIKE @@TABLE
GO
USE pubs
EXEC sp_showindexes 'emp%'
GO
下面是结果集:TABLE_NAME INDEX_NAME INDEX_ID
---------------- ---------------- ----------------
employee employee_ind 1
employee PK_emp_id 2
(2 row(s) affected)
I. 使用延迟名称解析
下面的示例显示四个过程以及延迟名称解析的各种可能使用方式。尽管引用的表或列在编译时不存在,但每个存储过程都可创建。IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc1' AND type = 'P')
DROP PROCEDURE proc1
GO
-- Creating a procedure on a nonexistent table.
USE pubs
GO
CREATE PROCEDURE proc1
AS
SELECT *
FROM does_not_exist
GO
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'P' AND o.name = 'proc1'
GO
USE master
GO
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc2' AND type = 'P')
DROP PROCEDURE proc2
GO
-- Creating a procedure that attempts to retrieve information from a
-- nonexistent column in an existing table.
USE pubs
GO
CREATE PROCEDURE proc2
AS
DECLARE @middle_init char(1)
SET @middle_init = NULL
SELECT au_id, middle_initial = @middle_init
FROM authors
GO
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'P' and o.name = 'proc2'
|
|
制作最清晰缩略图的完整类
|
Public Class ClassUpPic Private vPicFile As System.Web.UI.HtmlControls.HtmlInputFile Private vSmallPicSize, vUpFileSize As Integer Private vUpPicPath, vNewPicName, vTmpPicName As String Private PicMin, PicMax, vPicMax As System.Drawing.Image Private PicFormat As System.Drawing.Imaging.ImageFormat Private MinHeight, MinWidth As Decimal Private Myfile As IO.File
Public Sub New(ByVal PicFile As System.Web.UI.HtmlControls.HtmlInputFile, ByVal UpPicType As PicType) vPicFile = PicFile vUpFileSize = HttpContext.Current.Application("UpFileSize") Select Case UpPicType Case PicType.Face vUpPicPath = "upload/images/Face" vSmallPicSize = 150 vNewPicName = HttpContext.Current.Session("MemberID") & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") Case PicType.Photo vUpPicPath = "upload/images/Photo" vSmallPicSize = 150 vNewPicName = System.Guid.NewGuid.ToString() & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") Case PicType.Pic vUpPicPath = "upload/images/Pic" vSmallPicSize = 550 vNewPicName = System.Guid.NewGuid.ToString() & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") End Select End Sub
Public Function GetSavedFileName() As String ’检验图片类型================================================================= If vPicFile.PostedFile.FileName = "" Then Throw New NotSupportedException("文件为空,请您选择上传的图片文件!") End If If Left(vPicFile.PostedFile.ContentType, 5) <> "image" Then Throw New NotSupportedException("文件格式不合法,请选取有效的图片文件!" & vPicFile.PostedFile.ContentType) End If If vPicFile.PostedFile.ContentLength > vUpFileSize Then Dim MaxNumber As Decimal = vUpFileSize / 1024 / 1024 Throw New NotSupportedException("上传的图片文件太大,最大支持" & Format(MaxNumber, "##,##0") & "M!") End If
’检验数量限制=================================================================
’保存大文件================================================================= vPicFile.PostedFile.SaveAs(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vNewPicName) vPicFile.Dispose()
’缩略图片文件================================================================= PicMax = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vNewPicName) If Not (PicMax.RawFormat Is PicFormat.Gif Or PicMax.RawFormat Is PicFormat.Png) Then If PicMax.Height > vSmallPicSize Or PicMax.Width > vSmallPicSize Then vTmpPicName = System.Guid.NewGuid.ToString() & ".png" vPicMax = PicMax PicMax.Save(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName, PicFormat.Png) vPicMax.Dispose() PicMax = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName) End If End If ’保存小文件================================================================= GetMinPic(PicMax).Save(HttpContext.Current.Server.MapPath(vUpPicPath & "/min/") & vNewPicName, PicFormat.Jpeg) PicMax.Dispose()
’删除临时png文件================================================================= If vTmpPicName <> "" Then Myfile.Delete(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName)
Return vNewPicName End Function
Private Function GetMinPic(ByVal MaxPic As System.Drawing.Image) As System.Drawing.Image If MaxPic.Height > vSmallPicSize Or MaxPic.Width > vSmallPicSize Then If MaxPic.Height > MaxPic.Width Then MinWidth = MaxPic.Width / (MaxPic.Height / vSmallPicSize) MinHeight = vSmallPicSize Else MinWidth = vSmallPicSize MinHeight = MaxPic.Height / (MaxPic.Width / vSmallPicSize) End If Return MaxPic.GetThumbnailImage(CInt(MinWidth), CInt(MinHeight), Nothing, New System.IntPtr()) Else Return MaxPic End If End Function
Enum PicType Face = 1 Photo = 2 Pic = 3 End Enum
Private Function GetRightByChar(ByVal StrValue As String, ByVal CharValue As String) As String Dim MyStr() As String = Split(StrValue, CharValue) Return MyStr(MyStr.Length - 1) End Function End Class |
|
ASP.NET学习手记:验证用户表单输入
|
运行环境:Win2000 Advance Server+IIS5.0+NGWS SDK(80M的). 其中验证email地址的函数用的是廖兄精华区中的代码. <%@ Page Language="C#" %>
<html> <script language="javascript"> function ClientValidateEmail(source, value) { var strr; re=/(\w+@\w+\.\w+)(\.{0,1}\w*)(\.{0,1}\w*)/i; re.exec(value); if (RegExp.$3!=""&&RegExp.$3!="."&&RegExp.$2!=".") strr=RegExp.$1+RegExp.$2+RegExp.$3 else if (RegExp.$2!=""&&RegExp.$2!=".") strr=RegExp.$1+RegExp.$2 else strr=RegExp.$1 if (strr!=value) return false; else return true; } </script> <body>
<h3>ASP.NET验证用户输入</h3>
<form method=post runat=server> <hr width=600 size=1 noshade> <table> <tr> <td> <asp:ValidationSummary ID="valSum" runat="server" HeaderText="你必须输入下面这些表单域:" DisplayMode="bulletlist" Font-Name="宋体" Font-Size="12" /> </td> </tr> </table> <center> <p> <!-- 登陆信息 --> <table border=0 width=600 > <tr><td colspan=3> <table border=0 cellpadding=0 cellspacing=0 width="100%"> <tr><td> <b>登陆信息</b> </td></tr> </table> </td></tr> <tr> <td align=right> Email地址: </td> <td> <asp:TextBox id=email width=200px maxlength=60 runat=server /> </td> <td> <asp:RequiredFieldValidator id="emailReqVal" ControlToValidate="email" ErrorMessage="Email地址" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:CustomValidator id="emailRegexVal" runat="server" ControlToValidate="email" ClientValidationFunction="ClientValidateEmail" Display="Static" Font-Name="宋体" Font-Size="12"> 非法Email地址 </asp:CustomValidator> </td> </tr>
<tr> <td align=right> 密码: </td> <td> <asp:TextBox id=passwd TextMode="Password" maxlength=20 runat=server/> </td> <td> <asp:RequiredFieldValidator id="passwdReqVal" ControlToValidate="passwd" ErrorMessage="用户密码" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="passwdRegexBal" ControlToValidate="passwd" ValidationExpression=".*[!@#$%^&*+;:].*" Display="Static" Font-Name="宋体" Font-Size="12" Width="100%" runat=server> 密码必须包含如下字符: (!@#$%^&*+;:) </asp:RegularExpressionValidator> </td> </tr> <tr> <td align=right> 确认密码 </td> <td> <asp:TextBox id=passwd2 TextMode="Password" maxlength=20 runat=server/> </td> <td> <asp:RequiredFieldValidator id="passwd2ReqVal" ControlToValidate="passwd2" ErrorMessage="确认密码" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:CompareValidator id="CompareValidator1" ControlToValidate="passwd2" ControlToCompare="passwd" Display="Static" Font-Name="宋体" Font-Size="12" runat=server> 密码不符合 </asp:CompareValidator> </td> </tr> <tr><td colspan=3> </td></tr>
<!-- 私人信息 --> <tr><td colspan=3> <table border=0 cellpadding=0 cellspacing=0 width="100%"> <tr><td> <b>个人信息</b> </td></tr> </table> </td></tr> <tr> <td align=right> 姓名: </td> <td> <asp:TextBox id=pname maxlength=20 width=200px runat=server /> </td> <td> </td> </tr> <tr> <td align=right> 地址: </td> <td> <asp:TextBox id=address width=200px runat=server /> </td> <td> </td> </tr> <tr> <td align=right> 邮编: </td> <td> <ASP:TextBox id=postcode width=60px maxlength=6 runat=server /> </td> <td> <asp:RegularExpressionValidator id="RegularExpressionValidator1" ControlToValidate="postcode" ValidationExpression="^\d{6}$" Display="Static" Font-Name="宋体" Font-Size="12" runat=server> 邮编必须是6位数字 </asp:RegularExpressionValidator> </td> </tr> <tr> <td align=right> 性别: </td> <td> <ASP:RadioButtonList id=sexType runat=server> <asp:ListItem>男</asp:ListItem> <asp:ListItem>女</asp:ListItem> </ASP:RadioButtonList> </td> <td> <asp:RequiredFieldValidator id="sexTypeReqVal" ControlToValidate="sexType" ErrorMessage="性别" Display="Static" InitialValue="" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> </td> </tr> <tr> <td align=right> 出生年份: </td> <td> <ASP:DropDownList id=expYear runat=server> <asp:ListItem></asp:ListItem> <asp:ListItem >1976</asp:ListItem> <asp:ListItem >1975</asp:ListItem> </ASP:DropDownList> </td> <td> <asp:RequiredFieldValidator id="expDateReqVal" ControlToValidate="expYear" ErrorMessage="出生年份" Display="Static" InitialValue="" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> </td> </tr> </table> <p> <input runat="server" type=submit value="提 交"> <p> </form> </center> </body> </html>
|
|
认识ASP.NET配置文件Web.config
|
一、认识Web.config文件
Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中。当你通过VB.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认的 Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置,你可以在该子目录下新建一个Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息,也可以重写或修改父目录中定义的设置。
在运行时对Web.config文件的修改不需要重启服务就可以生效(注:<processModel> 节例外)。当然Web.config文件是可以扩展的。你可以自定义新配置参数并编写配置节处理程序以对它们进行处理。
二、web.config配置文件(默认的配置设置)以下所有的代码都应该位于
<configuration> <system.web>
和
</system.web> </configuration>
之间,出于学习的目的下面的示例都省略了这段XML标记
1、<authentication> 节
作用:配置 ASP.NET 身份验证支持(为Windows、Forms、PassPort、None四种)。该元素只能在计算机、站点或应用程序级别声明。<authentication> 元素必需与<authorization> 节配合使用。
示例:
以下示例为基于窗体(Forms)的身份验证配置站点,当没有登陆的用户访问需要身份验证的网页,网页自动跳转到登陆网页。
<authentication mode="Forms" > <forms loginUrl="logon.aspx" name=".FormsAuthCookie"/>
</authentication>
其中元素loginUrl表示登陆网页的名称,name表示Cookie名称
2、<authorization> 节
作用:控制对 URL 资源的客户端访问(如允许匿名用户访问)。此元素可以在任何级别(计算机、站点、应用程序、子目录或页)上声明。必需与<authentication> 节配合使用。
示例:以下示例禁止匿名用户的访问
<authorization> <deny users="?"/> </authorization>
注:你可以使用user.identity.name来获取已经过验证的当前的用户名;可以使用 web.Security.FormsAuthentication.RedirectFromLoginPage方法将已验证的用户重定向到用户刚才请求的页面.具体的实例请参考:
Forms验证 http://www.fanvb.net/websample/dataauth.aspx
3、<compilation>节
作用:配置 ASP.NET 使用的所有编译设置。默认的debug属性为“True”.在程序编译完成交付使用之后应将其设为True(Web.config文件中有详细说明,此处省略示例)
4、<customErrors>
作用:为 ASP.NET 应用程序提供有关自定义错误信息的信息。它不适用于 XML Web services 中发生的错误。
示例:当发生错误时,将网页跳转到自定义的错误页面。
<customErrors defaultRedirect="ErrorPage.aspx" mode="RemoteOnly"> </customErrors>
其中元素defaultRedirect表示自定义的错误网页的名称。mode元素表示:对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。
5、<httpRuntime>节
作用:配置 ASP.NET HTTP 运行库设置。该节可以在计算机、站点、应用程序和子目录级别声明。
示例:控制用户上传文件最大为4M,最长时间为60秒,最多请求数为100
<httpRuntime maxRequestLength="4096" executionTimeout="60" appRequestQueueLimit="100"/>
6、 <pages>
作用:标识特定于页的配置设置(如是否启用会话状态、视图状态,是否检测用户的输入等)。<pages>可以在计算机、站点、应用程序和子目录级别声明。
示例:不检测用户在浏览器输入的内容中是否存在潜在的危险数据(注:该项默认是检测,如果你使用了不检测,一要对用户的输入进行编码或验证),在从客户端回发页时将检查加密的视图状态,以验证视图状态是否已在客户端被篡改。(注:该项默认是不验证)
<pages buffer="true" enableViewStateMac="true" validateRequest="false"/>
7、<sessionState>
作用:为当前应用程序配置会话状态设置(如设置是否启用会话状态,会话状态保存位置)。
示例:
<sessionState mode="InProc" cookieless="true" timeout="20"/> </sessionState>
注:
mode="InProc"表示:在本地储存会话状态(你也可以选择储存在远程服务器或SAL服务器中或不启用会话状态)
cookieless="true"表示:如果用户浏览器不支持Cookie时启用会话状态(默认为False)
timeout="20"表示:会话可以处于空闲状态的分钟数
8、<trace>
作用:配置 ASP.NET 跟踪服务,主要用来程序测试判断哪里出错。
示例:以下为Web.config中的默认配置:
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
注:
enabled="false"表示不启用跟踪;requestLimit="10"表示指定在服务器上存储的跟踪请求的数目
pageOutput="false"表示只能通过跟踪实用工具访问跟踪输出;
traceMode="SortByTime"表示以处理跟踪的顺序来显示跟踪信息
localOnly="true" 表示跟踪查看器 (trace.axd) 只用于宿主 Web 服务器
三、自定义Web.config文件配置节
自定义Web.config文件配置节过程分为两步。
一是在在配置文件顶部 <configSections> 和 </configSections>标记之间声明配置节的名称和处理该节中配置数据的 .NET Framework 类的名称。
二是在 <configSections> 区域之后为声明的节做实际的配置设置。
示例:创建一个节存储数据库连接字符串
<configuration> <configSections> <section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections>
<appSettings> <add key="scon" value="server=a;database=northwind;uid=sa;pwd=123"/> </appSettings>
<system.web> ...... </system.web> </configuration>
四、访问Web.config文件
你可以通过使用ConfigurationSettings.AppSettings 静态字符串集合来访问 Web.config 文件示例:获取上面例子中建立的连接字符串。
Dim sconstr As String = ConfigurationSettings.AppSettings("SconStr") Dim scon = New SqlConnection(sconstr) |
|
插入Access记录后马上得到自动编号值的方法
|
首先须保证获得记录集的方式支持bookmark属性,如1,3
插入一条带自动编号字段的记录后,获取该记录的bookmark属性值
temp = rs.bookmark
然后
rs.bookmark = temp
试试!!
Response.write rs.Fields("ID"). |
|
ASP中生成静态页面技术
|
<!--#include file="conn.asp"--> <% dim str function menu(id) set rs=server.CreateObject("adodb.recordset") sql="select * from menu where id1="&id&" order by url,id" rs.open sql,conn,1,1 str=str+"<table border='0' cellspacing='0' cellpadding='0'>"+chr(13) i=1 while not rs.eof ChildCount=conn.execute("select count(*) from menu where id1="&rs("id"))(0) if ChildCount=0 then if i=rs.recordcount then menutype="file1" else menutype="file" end if menuname="<a href='"&rs("url")&"' target='_blank'>"&rs("menuname")&"</a>" onmouseup="" else if i=rs.recordcount then menutype="menu3" listtype="list1" onmouseup=" onMouseUp=change1('a"&rs("id")&"','b"&rs("id")&"');" else menutype="menu1" listtype="list" onmouseup=" onMouseUp=change2('a"&rs("id")&"','b"&rs("id")&"');" end if menuname=rs("menuname") end if str=str+"<tr><td id='b"&rs("id")&"' class='"&menutype&"'"&onmouseup&">"&menuname&"</td></tr>"+chr(13) if ChildCount>0 then str=str+"<tr id='a"&rs("id")&"' style='display:none'><td class='"&listtype&"'>"+chr(13) menu(rs("id")) str=str+"</td></tr>"+chr(13) end if rs.movenext i=i+1 wend str=str+"</table>"+chr(13) rs.close set rs=nothing end function
menu(0)
set fso=server.CreateObject("scripting.filesystemobject") set f1=fso.opentextfile(server.MapPath("demo.htm"),2,true) f1.write("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>") f1.write("<html>") f1.write("<head>") f1.write("<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>") f1.write("<title>哈哈~~~!这回速度超快了吧?</title>") f1.write("<meta name='keywords' content='asp2004,树,菜单,无限级'>") f1.write("<meta name='author' content='小灰,quxiaohui_0@163.com'>") f1.write("<link href='style.css' rel='stylesheet' type='text/css'>") f1.write("<script language='javascript' src='function.js'></script>") f1.write("</head>") f1.write("<body>") f1.write("<a href='http://asp2004.net' target='_blank'>http://asp2004.net</a>提供最新下载《<a href='menu.asp'>管理</a>》<br>")
f1.write(str)
f1.write("</body>") f1.write("</html>") f1.close set fso=nothing
response.Redirect("demo.htm") %> 演示:http://asp2004.net/temp/treemenu/menu.asp 源代码下载:http://asp2004.net/temp/treemenu.rar |
|
XMLHTTP抓取数据时乱码问题解决
|
CSDN原帖: http://community.csdn.net/Expert/topic/3316/3316086.xml?temp=.2790033
内码问题.用这段代码的吧,我已经改得很精简了. '使用XMLHTTP抓取地址并进次内容处理 Function GetBody(Url) Dim objXML On Error Resume Next Set objXML = CreateObject("Microsoft.XMLHTTP") With objXML .Open "Get", Url, False, "", "" .Send GetBody = .ResponseBody End With GetBody=BytesToBstr(GetBody,"GB2312") Set objXML = Nothing End Function '使用Adodb.Stream处理二进制数据 Function BytesToBstr(strBody,CodeBase) dim objStream set objStream = Server.CreateObject("Adodb.Stream") objStream.Type = 1 objStream.Mode =3 objStream.Open objStream.Write strBody objStream.Position = 0 objStream.Type = 2 objStream.Charset = CodeBase BytesToBstr = objStream.ReadText objStream.Close set objStream = nothing End Function
|
|
利用XMLHTTP无刷新添加数据之Post篇
|
我们传统的提交数据的方法都是用<Form>来实现的. <Form>标记中的Method属性确定了表单元素的数据在发送到服务器时, 如何对HTTP请求信息进行打包.
Method 属性可以使用的方法 Method属性 发送表单元素的方式 读取数据的Request集合 Get 标识在URL的最后 QueryString Post 在HTTP请求的主体内(HTTP请求的自由区域) Form
这篇文章用XMLHTTP来实现Form的Method=Post.
ClientPost.htm
<script language="JavaScript"> function AddDataPost(sUserId,sUserName) { /* *--------------- AddDataPost(sUserId,sUserName) ----------------- * AddDataPost(sUserId,sUserName) * 功能:通过XMLHTTP添加数据.相当于Form的Method=Post. * 参数:sUserId,字符串,发送条件. * 参数:sUserName,字符串,发送条件. * 实例:AddDataPost(document.all.userid.value,document.all.username.value); * author:wanghr100(灰豆宝宝.net) * update:2004-5-30 14:46 *--------------- AddDataPost(sUserId,sUserName) ----------------- */ var oBao = new ActiveXObject("Microsoft.XMLHTTP"); //特殊字符:+,%,&,=,?等的传输解决办法. //Update:2004-6-1 12:22 //escape(sUserId),escape(sUserName); sUserId = escape(sUserId); sUserName = escape(sUserName); var userInfo = "userid="+sUserId+"&username="+sUserName; oBao.open("POST","Server.asp",false); oBao.setRequestHeader("Content-Type","application/x-www-form-urlencoded") oBao.send(userInfo); //清空输入框数据. document.all.userid.value=""; document.all.username.value=""; //服务器端处理返回的是经过escape编码的字符串. alert(unescape(oBao.responseText)) } </script> <input type="button" onclick="AddDataPost(document.all.userid.value,document.all.username.value)" value="AddDataPost"><br> userid:<input type="text" name="userid"><br> username:<input type="text" name="username">
Server.asp 服务器端处理.
<% @Language="JavaScript" %> <% function OpenDB(sdbname) { /* *--------------- OpenDB(sdbname) ----------------- * OpenDB(sdbname) * 功能:打开数据库sdbname,返回conn对象. * 参数:sdbname,字符串,数据库名称. * 实例:var conn = OpenDB("database.mdb"); * author:wanghr100(灰豆宝宝.net) * update:2004-5-12 8:18 *--------------- OpenDB(sdbname) ----------------- */ var connstr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="+Server.MapPath(sdbname); var conn = Server.CreateObject("ADODB.Connection"); conn.Open(connstr); return conn; } var sResult = ""; var oConn = OpenDB("data.mdb"); //相当于Form的Method=Post. //相当于Form的Method=Post. //特殊字符:+,%,&,=,?等的传输解决办法.客户端传输过来是经过escape编码的. //所以服用器端应该先unescape解码. //Update:2004-6-1 12:22 //unescape(Request.Form("userid"))..... var userid = unescape(Request.Form("userid")); var username = unescape(Request.Form("username")); sResult = "userid:"+userid+"\nusername:"+username+"\n 添加成功." var sql = "Insert into users(userid,username)Values('"+userid+"','"+username+"')"; oConn.Execute(sql); Response.Write(escape(sResult)); %>
数据库设计 data.mdb 表users. 字段 id 自动编号 userid 文本 username 文本
表:users 数据: id userid username
|
|
利用XMLHTTP无刷新添加数据之Get篇
|
我们传统的提交数据的方法都是用<Form>来实现的. <Form>标记中的Method属性确定了表单元素的数据在发送到服务器时, 如何对HTTP请求信息进行打包.
Method 属性可以使用的方法 Method属性 发送表单元素的方式 读取数据的Request集合 Get 标识在URL的最后 QueryString Post 在HTTP请求的主体内(HTTP请求的自由区域) Form
这篇文章用XMLHTTP来实现Form的Method=Get.
ClientGet.htm
<script language="JavaScript"> function AddDataGet(sUserId,sUserName) { /* *--------------- AddDataGet(sUserId,sUserName) ----------------- * AddDataGet(sUserId,sUserName) * 功能:通过XMLHTTP添加数据.相当于Form的Method=Get. * 参数:sUserId,字符串,发送条件. * 参数:sUserName,字符串,发送条件. * 实例:AddDataGet(document.all.userid.value,document.all.username.value); * author:wanghr100(灰豆宝宝.net) * update:2004-5-30 14:46 *--------------- AddDataGet(sUserId,sUserName) ----------------- */ var oBao = new ActiveXObject("Microsoft.XMLHTTP"); //特殊字符:+,%,&,=,?等的传输解决办法.用escape编码. //Update:2004-6-1 12:22 //escape(sUserId),escape(sUserName); oBao.open("POST","Server.asp?userid="+escape(sUserId)+"&username="+escape(sUserName),false); oBao.send(); //清空输入框数据. document.all.userid.value=""; document.all.username.value=""; //服务器端处理返回的是经过escape编码的字符串. alert(unescape(oBao.responseText)) } </script> <input type="button" onclick="AddDataGet(document.all.userid.value,document.all.username.value)" value="AddDataGet"><br> userid:<input type="text" name="userid"><br> username:<input type="text" name="username">
Server.asp 服务器端处理.
<% @Language="JavaScript" %> <% function OpenDB(sdbname) { /* *--------------- OpenDB(sdbname) ----------------- * OpenDB(sdbname) * 功能:打开数据库sdbname,返回conn对象. * 参数:sdbname,字符串,数据库名称. * 实例:var conn = OpenDB("database.mdb"); * author:wanghr100(灰豆宝宝.net) * update:2004-5-12 8:18 *--------------- OpenDB(sdbname) ----------------- */ var connstr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="+Server.MapPath(sdbname); var conn = Server.CreateObject("ADODB.Connection"); conn.Open(connstr); return conn; } var sResult = ""; var oConn = OpenDB("data.mdb"); //相当于Form的Method=Get. //相当于Form的Method=Get. //特殊字符:+,%,&,=,?等的传输解决办法.客户端传输过来是经过escape编码的. //所以服用器端应该先用unescape解码. //Update:2004-6-1 12:22 //unescape(Request.QueryString("userid"))..... var userid = unescape(Request.QueryString("userid")); var username = unescape(Request.QueryString("username")); sResult = "userid:"+userid+"\nusername:"+username+"\n 添加成功." var sql = "Insert into users(userid,username)Values('"+userid+"','"+username+"')"; oConn.Execute(sql); Response.Write(escape(sResult)); %>
数据库设计 data.mdb 表users. 字段 id 自动编号 userid 文本 username 文本
表:users 数据: id userid username |
|
使用ASP生成HTML文件
|
'共有两个页面index.htm是首页.程序比较简单,主要是用了ASP里的文件操作对象。
index.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Untitled Document</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head>
<body> <table width="770" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td><form name="form1" method="post" action="send.asp"> <table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#CCFFFF"> <tr> <td height="20"><div align="center">发送消息</div></td> </tr> <tr> <td><div align="center"> <textarea name="msg" cols="100" rows="6"></textarea> </div></td> </tr> <tr> <td><div align="center"> <input type="submit" name="Submit" value="Submit"> <input type="reset" name="Submit2" value="Reset"> </div></td> </tr> </table> </form></td> </tr> </table> </body> </html> '//send.asp
<% function chan_time(shijian)'转换日期时间函数 s_year=year(shijian) if len(s_year)=2 then s_year="20"&s_year s_month=month(shijian) if s_month<10 then s_month="0"&s_month s_day=day(shijian) if s_day<10 then s_day="0"&s_day s_hour=hour(shijian) if s_hour<10 then s_hour="0"&s_hour s_minute=minute(shijian) if s_minute<10 then s_minute="0"&s_minute chan_time=s_year & s_month & s_day & s_hour & s_minute end function
function chan_data(shijian) '转换日期时间函数 s_year=year(shijian) if len(s_year)=2 then s_year="20"&s_year s_month=month(shijian) if s_month<10 then s_month="0"&s_month s_day=day(shijian) if s_day<10 then s_day="0"&s_day chan_data=s_year & s_month & s_day end function
function chan_file(shijian)'转换日期时间函数 s_month=month(shijian) if s_month<10 then s_month="0"&s_month s_day=day(shijian) if s_day<10 then s_day="0"&s_day s_hour=hour(shijian) if s_hour<10 then s_hour="0"&s_hour s_minute=minute(shijian) if s_minute<10 then s_minute="0"&s_minute s_ss=second(shijian) if s_ss<10 then s_ss="0"&s_ss chan_file = s_month & s_day & s_hour & s_minute & s_ss end function top="<html><head><title>news</title></head><body>" botom="</body></html>" msg=request.Form("msg") msg=replace(msg,vbcrlf,"") msg=replace(msg,chr(9),"") msg=replace(msg," "," ") msg=replace(msg,"\r\n","<br>") msg=replace(msg,"\n","<br>") msg=top&msg&botom Set fs=Server.CreateObject("Scripting.FileSystemObject") all_tree2=server.mappath("news")&"\"&chan_data(now) if (fs.FolderExists(all_tree2)) then'判断今天的文件夹是否存在 else fs.CreateFolder(all_tree2) end if pass=chan_file(now) randomize '使用系统计时器来初始化乱数产生器 pass=rnd(pass) pass=get_pass(pass) pass=left(pass,10)
file1=pass files=file1&".txt" filez=all_tree2&"\"&files
set ts = fs.createtextfile(filez,true) '写文件 for z=1 to len(msg) write_now=mid(msg,z,1) ts.write(write_now) next ' ts.writeline(all_msg) ts.close set ts=nothing '文件生成
if err.number<>0 or err then%> <script language="javascript"> alert("不能完成") </script> <%else%> <script language="javascript"> alert("已完成") history.back(); </script> <%end if Set MyFile = fs.GetFile(filez) all_tree2=server.mappath("news")&"\"&chan_data(now) if (fs.FolderExists(all_tree2)) then else fs.CreateFolder(all_tree2) end if MyFile.name= left(MyFile.name,len(MyFile.name)-4)&".htm" set MyFile=nothing set fs=nothing set fdir=nothing function get_pass(pass)
pass=cstr(pass) pass=replace(pass," ","") pass=replace(pass," ","") pass=replace(pass,"-","") pass=replace(pass," ","") pass=replace(pass,":","") pass=replace(pass,".","") pass=replace(pass,"+","") pass=replace(pass,"_","") pass=replace(pass,"<","") pass=replace(pass,">","") pass=replace(pass,"!","") pass=replace(pass,"@","") pass=replace(pass,"#","") pass=replace(pass,"$","") pass=replace(pass,"%","") pass=replace(pass,"^","") pass=replace(pass,"&","") pass=replace(pass,"*","") pass=replace(pass,"(","") pass=replace(pass,")","") pass=replace(pass,"=","") pass=replace(pass,"\","") pass=replace(pass,"/","") pass=replace(pass,"|","") get_pass=pass
end function %>
'//
把send.asp和index.htm放到你的ASP目录下,然后再建一个news文件夹。打开浏览器,在地址栏里输入:http://你的机器名/你的ASP虚拟目录名/index.html输入文字,然后提交,OK!看看你的ASP目录里新建的news文件夹里是不是多了个新的文件夹,而且是以当前日期命名的。里面有你刚刚提交的文字,看看是不是生成了HTML文件。怎么样,你可以在此基础上做个简单的新闻发布系统。。 |
|
|