2007年04月02日

在ASP数据库编程时,经常使用Request对象获取传递的信息,实现数据库的操作,如下:
 ’将获取的信息赋值给变量
 rfname = Request.Form("firstname")
 rlname = Request.Form("lastname")
 rsex = Request.Form("sex")
 rage = Request.Form("age")
 
 ……

 ’插入语句,通过使用变量插入值
 strSQL = "INSERT INTO info(firstname,lastname,sex,age) VALUES(‘"&rfname&"’,'"&rlname&"’,'"&rsex&"’,"&rage&")"

 ’或如下
 strSQL = "INSERT INTO info(firstname,lastname,sex,age) VALUES(‘"+rfname+"’,'"+rlname+"’,'"+rsex+"’,"+rage+")"

 cn.Execute(strSQL)

说明:
如果传入的是字符型请在变量处使用(外单引号,内双引号)’"&变量&"’这种格式,如果传是数值型的可以直接用(只有双引号)"&变量&"

在ASP中,可以通过ADO访问数据库,经常会用到ASP的三个内建对象(ADO):Connection、Recordset、Cmmand对象;以下的示例简单的说明了如何使用三个ADO对数据库进行操作,简单起见,采用了Microsoft Access数据库的文件DSN;使用的是VBScript。

<%@ Language=VBScript %>
<html>
<head>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<title>操作数据库的几种方法</title>
</head>

<body>
Please Input Personal Information:<br>
<form method=post action="dbmeth.asp">
FirstName:<input type=text name="firstname">
<br>LastName:<input type=text name="lastname">
<br>Sex:<input type=text name="sex">
<br>Age:<input type=text name="age">
<br><input type=submit value="connection" NAME="use_db">
<input type=submit value="recordset" NAME="use_db">
<input type=submit value="command" NAME="use_db">
</form>

<%
strFName = Request.Form("firstname")
strLName = Request.Form("lastname")
strSex = Request.Form("sex")
intAge = Request.Form("age")
strCommand = Request.Form("use_db")
Response.Write strFName
Response.Write strLName
Response.Write strSex
Response.Write intAge
Response.Write strCommand

IF  strCommand = "connection" Then
‘使用Connection对象进行操作
 strDSN = "FILEDSN=test.dsn"
 set cn = Server.CreateObject("ADODB.Connection")
 cn.Open strDSN

 strSQL = "INSERT INTO info(firstname,lastname,sex,age) VALUES(‘"&strFName&"’,'"&strLName&"’,'"&strSex&"’,"&intAge&")"
 cn.Execute(strSQL)
 

 strSQL = "SELECT * FROM info"
 set rsInfo = cn.Execute(strSQL) ‘返回Recordset对象
 

 set objno = rsInfo("No")
 set objfname = rsInfo("firstname")
 set objlname = rsInfo("lastname")
 set objsex = rsInfo("sex")
 set objage = rsInfo("age")

 Response.Write "<table cellspacing=0 cellpadding=0 border=1><tr><td>No</td><td>firstname</td><td>lastname</td><td>sex</td><td>age</td></tr>"

 Do Until rsInfo.EOF
 Response.Write "<tr><td>"&objno&"</td><td>"&objfname&"</td><td>"&objlname&"</td><td>"&objsex&"</td><td>"&objage&"</td></tr>"
 rsInfo.MoveNext
 Loop

 Response.Write "</table>"

 cn.Close
 set rsInfo = Nothing
 set cn = Nothing
ElseIf strCommand = "recordset" Then
‘使用Recordset对象进行操作
 strDSN = "FILEDSN=test.dsn"
 ’set cn = Server.CreateObject("ADODB.Connection")
 ’cn.Open strDSN
 
 ’strSQL = "INSERT INTO info(firstname,lastname,sex,age) VALUES(‘good’,'hoo’,'male’,43)"
 ’cn.Execute(strSQL)
 
 set rsInfo = Server.CreateObject("ADODB.Recordset")
 
 strSQL = "INSERT INTO info(firstname,lastname,sex,age) VALUES(‘"&strFName&"’,'"&strLName&"’,'"&strSex&"’,"&intAge&")"
 ’rsInfo.Open strSQL,cn
 rsInfo.Open strSQL,strDSN
 
 strSQL = "SELECT * FROM info" 
 ’rsInfo.Open strSQL,cn
 rsInfo.Open strSQL,strDSN

 set objno = rsInfo("No")
 set objfname = rsInfo("firstname")
 set objlname = rsInfo("lastname")
 set objsex = rsInfo("sex")
 set objage = rsInfo("age")

 Response.Write "<table cellspacing=0 cellpadding=0 border=1><tr><td>No</td><td>firstname</td><td>lastname</td><td>sex</td><td>age</td></tr>"

 Do Until rsInfo.EOF
 Response.Write "<tr><td>"&objno&"</td><td>"&objfname&"</td><td>"&objlname&"</td><td>"&objsex&"</td><td>"&objage&"</td></tr>"
 rsInfo.MoveNext
 Loop

 Response.Write "</table>"

 rsInfo.Close
 set rsInfo = Nothing

ElseIf strCommand = "command" Then
‘使用Command对象进行操作
 strDSN = "FILEDSN=test.dsn"
 set cn = Server.CreateObject("ADODB.Connection")
 cn.Open strDSN
 
 set cm = Server.CreateObject("ADODB.Command")
 set cm.ActiveConnection = cn
 
 cm.CommandText = "INSERT INTO info(firstname,lastname,sex,age) VALUES(?,?,?,?)"
 cm.Prepared = True
 
 cm.Parameters.Append cm.CreateParameter("vfname",200,,255)
 cm.Parameters.Append cm.CreateParameter("vlname",200,,255)
 cm.Parameters.Append cm.CreateParameter("vsex",200,,255)
 cm.Parameters.Append cm.CreateParameter("vage",3,,4)
 ’CreateParameter中的Type参数应该使用数值
 
 cm("vfname")=strFName
 cm("vlname")=strLName
 cm("vsex")=strSex
 cm("vage")=intAge
 cm.Execute
 
 strSQL = "SELECT * FROM info"
 set rsInfo = cn.Execute(strSQL) ‘返回Recordset对象
 

 set objno = rsInfo("No")
 set objfname = rsInfo("firstname")
 set objlname = rsInfo("lastname")
 set objsex = rsInfo("sex")
 set objage = rsInfo("age")

 Response.Write "<table cellspacing=0 cellpadding=0 border=1><tr><td>No</td><td>firstname</td><td>lastname</td><td>sex</td><td>age</td></tr>"

 Do Until rsInfo.EOF
 Response.Write "<tr><td>"&objno&"</td><td>"&objfname&"</td><td>"&objlname&"</td><td>"&objsex&"</td><td>"&objage&"</td></tr>"
 rsInfo.MoveNext
 Loop

 Response.Write "</table>"

 cn.Close
 set rsInfo = Nothing
 set cm = Nothing
 set cn = Nothing 
End If
strGet = ""
%>

</body>
</html>

在SQL Server数据库编程时,常常需要判断一个数据库是否已经存在,如果不存在则创建此数据库。常用的方法有以下三种:

1. select * From master.dbo.sysdatabases where name=’test_db’

如果不存在查询结果,则说明name所表示的数据库不存在

2. object_id(‘test_db’)

如果无法获取对象ID(null),则说明此对象不存在;常用
if object_id(‘test_db’) is null 
或者
if (select object_id(‘test_db’)) is null 

3. db_id(‘test_db’)

如果不能获取数据库ID,则说明name所表示的数据库不存在;实际上此种方法也是在sysdatabases中查找,并返回数据库的ID;常用
if db_id(‘test_db’) is null 
或者
if (select db_id(‘test_db’)) is null 

下面以ASP编程为例来说明,先判断数据库是否存在,如果不存在则创建此数据库:

‘ strSQL = "if not exists (select * From master.dbo.sysdatabases where name=’test_db’) "& _
‘ strSQL = "if object_id(‘test_db’) is null "& _
strSQL = "use master if not exists (select db_id(‘test_db’)) "& _
"create database test_db on primary (name=’test_data’,filename=’d:\temp\test_db\test_db.mdf’,size=5MB,maxsize=unlimited,filegrowth=1%) "& _
"log on (name=’test_log’,filename=’d:\temp\test_db\test_log.ldf’,size=1MB,maxsize=unlimited,filegrowth=1%) "
cn.Execute(strSQL)

Microsoft SQL Server7.0是一种大型、分布式数据库系统,也可被认为是一种大型、分布式数据仓库。SQL Server是一个十分注重安全性的数据库,特别是在7.0版本发布以后,可以将数据库的许可直接授予Windows NT用户,数据库角色也可以包括NT 用户或组及SQL Server旧版本的用户和角色。另外,结合Microsoft Proxy Server ,则必须通过代理服务器才能在Internet 上访问SQL Server,这样更确保了数据的安全。

一. 连接方案

   在连接方案上,可选择TCP/IP套接字和命名管道的方法访问。具有NT用户帐号的用户适合于采用命名管道的方法,没有NT用户帐号的用户则不适合用此方法。这是因为在建立连接之前,数据库用户必须被NT确认,而选择TCP/IP套接字的连接则无此限制,该连接可直接连到数据库服务器,不必通过使用命名管道的中间计算机,只要通过了SQL Server确认用户就可获得访问权。

  由于是编写数据库连接的ASP应用程序,采用的数据访问编程模式是ADO;在ADO以前的数据访问编程模式有数据访问对象DAO和远程访问对象RDO,RDO以及DAO都是在ODBC下开发的,ODBC是用C语言编写的基于SQL的桌面规程。相反,ADO是在一种新型的规程OLE DB下开发的,OLE DB可以被看作是OLE技术在数据库中应用。它是基于C++开发的,给ODBC的功能提供了标准化的COM接口。C++是面向对象的,因此ADO也具有面向对象的特性。并能通过一系列COM接口来扩展自己。这一点对于ASP程序来说很重要。我们知道ASP程序使用的VBScript脚本语言的功能是很弱的,若要扩充VBScript的能力,使其能访问数据,则必须创建一个服务器端组件,通过COM接口来访问数据,而这正是ADO所擅长的。

二. 连接方法

在ASP脚本中可以通过三种实用的方法连接数据库:通过ODBC DSN建立连接,通过oledb建立连接和通过driver建立连接。

(一) 通过ODBC DSN建立连接

运用ODBC数据源,首先必须在控制面板的ODBC中设置数据源,然后再编写脚本和数据库源建立连接。

1、创建 ODBC DSN

  在编程连接网络上指定的服务器和数据库时,必须在Web服务器上创建数据源名(DSN)。要设置一个DSN,必须给服务器提供数据库的名字、通信所用的ODBC驱动、以及在网络中的地址。要注意的是:只有设置的DSN为一个系统DSN,才能让ADO在ASP中正常工作。如何确定DSN是系统DSN而不是用户或文件DSN呢?很简单,只有对于NT服务器上的所有用户和服务都可以访问的DSN才是系统DSN。

        通过在 Windows 的"开始"菜单打开"控制面板",您可以创建基于 DSN 的文件。双击"ODBC"图标,然后选择"系统 DSN"属性页,单击"添加",选择数据库驱动程序,然后单击"下一步"。按照后面的指示配置适用于您的数据库软件的 DSN。

        配置 SQL Server 数据库系统 DSN:在"创建新数据源"对话框中,从列表框中选择"SQL Server",然后单击"下一步"。键入 DSN 文件的名称,然后单击"下一步"。单击"完成"创建数据源。键入运行 SQL 服务程序的服务器的名称、登录 ID 和密码。在"创建 SQL Server 的新数据源"对话框中,在"服务器"列表框中键入包含 SQL Server 数据库的服务器的名称,然后单击"下一步"。选择验证登录 ID 的方式。如果要选择 SQL 服务器验证,请输入一个登录 ID 和密码,然后单击"下一步"。在"创建 SQL Server 的新数据源"对话框中,设置默认数据库、存储过程设置的驱动程序和 ANSI 标识,然后单击"下一步"。(要获取详细信息,请单击"帮助"。)在对话框(同样名为"创建 SQL Server 的新数据源")中,选择一种字符转换方法,然后单击"下一步"。(详细信息,请单击"帮助"。)在下一个对话框(同样名为"创建 SQL Server 的新数据源")中,选择登录设置。 注意典型情况下, 您只能使用日志来调试数据库访问问题。 在"ODBC Microsoft SQL Server 安装程序"对话框中,单击"测试数据源"。如果 DSN 正确创建,"测试结果"对话框将指出测试成功完成。

2、编写脚本和数据库源建立连接

        ADO(ActiveX Data Objects ) 提供 Connection 对象,可以使用该对象建立和管理应用程序和 ODBC 数据库之间的连接。Connection 对象具有各种属性和方法,可以使用它们打开和关闭数据库连接。编写数据库连接脚本,首先应创建 Connection 对象的实例,接着打开数据库连接:
<%
set conn=server.createobject("adodb.connection")
conn.open "DSN=ODBC名称;Database=数据库名称;UID=;PWD=;"
%>

(二) 通过oledb建立连接

        运用oledb方法建立页面与数据库的连接, 不需要创建 ODBC DSN数据源,直接编写如下的脚本和数据源建立连接,是一种简单易用的方法。
<%
set conn=server.createobject("adodb.connection")
conn.open "Provider=SQLOLEDB;server=SQL服务器名称或IP地址;database=数据库名称;uid=;pwd="
%>

(三) 通过driver建立连接

        通过driver建立页面与数据库的连接,同样不需要创建ODBC DSN数据源,但必须知道实际的数据库文件路径或者数据源名(例如,SQLserver的数据库)。
<%
set conn=server.createobject("adodb.connection")
conn.open "driver={sql server};server=SQL服务器名称或IP地址;database=数据库名称;uid=;pwd="%>

三. 存取控制

  设计ASP程序连接SQL SERVER的另一个重要问题是实现对SQL SERVER的存取控制。由于在关系型数据库中,DBMS本身的DCL语言只支持对表和字段的存取控制,而不直接支持对表中记录提供安全性保护。为实现其安全性,同时又不失B/S结构的开放性,可以考虑采用使用中间层存取程序逻辑结合触发器的方式来实现。使用中间层存取程序即用户端程序不直接访问DBMS,而是通过一个中间层的存取程序。

        以网上BBS应用为例,用户查询时,存取程序把表中的全部记录返回给用户;用户插入记录时,存取程序在新记录的User_name字段填写当前用户名,表明记录的主人,当用户删除和修改记录时,存取程序根据User_name字段向用户返回只属于他自己的记录,并允许用户从自己的记录中选择进行操作。使用触发器的方式则是所有用户直接访问表,但在表上建立如下的触发器:

CREATE TRIGGER trigger_1 on table_ 1 FOR INSERT AS
BEGIN
IF EXITS(SELECT * FROM inserted WHERE User_name<>User_name())
BEGIN
ROLLBACK TRANSACTION
RAISERROR(‘请输入正确的用户名’,16,-1)
END
END
CREATE TRIGGER trigger_2 on table_1 FOR UPDATE,DELETE AS
BEGIN
IF EXITS (SELECT * FROM deleted WHERE User_name<>User_name())
BEGIN
RAISERROR(‘你不能修改他人的数据’,16,-1)
END
END

  在上面的程序中,trigger_1对于用户名不正确的用户的插入请求予以否决。trigger_2对于试图修改他人的记录的请示予以否决。由于触发器附着在SQL Server的基本表中,无论用户通过何种方式更新记录,都无法跳过触发器的检查,因此使用触发器实现的安全性是相当高的。但由于在表中只能定义针对手稿删除和修改的触发器,不能定义针对查询的触发器,因此,要实现对查询的存取控制,则要通过中间层存取程序,只有向用户查询请示返回特定条件的记录来实现。

1.ASP与ACCESS数据库连接:
<%
dim conn,mdbfile
mdbfile=server.mappath("数据库名称.mdb")
set conn=server.createobject("adodb.connection")
conn.open "driver={microsoft access driver (*.mdb)};uid=admin;pwd=数据库密码;dbq="&mdbfile
%>

2. ASP与SQL数据库连接:

<%
dim conn
set conn=server.createobject("ADODB.connection")
con.open "PROVIDER=SQLOLEDB;DATA SOURCE=SQL服务器名称或IP地址;UID=sa;PWD=数据库密码;DATABASE=数据库名称
%>

建立记录集对象:

set rs=server.createobject("adodb.recordset")
rs.open SQL语句,conn,3,2

 

3. SQL常用命令使用方法:

(1) 数据记录筛选:

sql="select * from 数据表 where 字段名=字段值 order by 字段名 "
sql="select * from 数据表 where 字段名 like ‘%字段值%‘ order by 字段名 "
sql="select top 10 * from 数据表 where 字段名 order by 字段名 "
sql="select * from 数据表 where 字段名 in (‘值1‘,‘值2‘,‘值3‘)"
sql="select * from 数据表 where 字段名 between 值1 and 值2"

(2) 更新数据记录:

sql="update 数据表 set 字段名=字段值 where 条件表达式"
sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表达式"

(3) 删除数据记录:

sql="delete from 数据表 where 条件表达式"
sql="delete from 数据表" (将数据表所有记录删除)

(4) 添加数据记录:

sql="insert into 数据表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)"
sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到目标数据表)

(5) 数据记录统计函数:

AVG(字段名) 得出一个表格栏平均值
COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计
MAX(字段名) 取得一个表格栏最大的值
MIN(字段名) 取得一个表格栏最小的值
SUM(字段名) 把数据栏的值相加

引用以上函数的方法:

sql="select sum(字段名) as 别名 from 数据表 where 条件表达式"
set rs=conn.excute(sql)

用 rs("别名") 获取统的计值,其它函数运用同上。

(5) 数据表的建立和删除:

CREATE TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… )

例:CREATE TABLE tab01(name varchar(50),datetime default now())

DROP TABLE 数据表名称 (永久性删除一个数据表)

 

(6) 记录集对象的方法:

rs.movenext 将记录指针从当前的位置向下移一行
rs.moveprevious 将记录指针从当前的位置向上移一行
rs.movefirst 将记录指针移到数据表第一行
rs.movelast 将记录指针移到数据表最后一行
rs.absoluteposition=N 将记录指针移到数据表第N行
rs.absolutepage=N 将记录指针移到第N页的第一行
rs.pagesize=N 设置每页为N条记录
rs.pagecount 根据 pagesize 的设置返回总页数
rs.recordcount 返回记录总数
rs.bof 返回记录指针是否超出数据表首端,true表示是,false为否
rs.eof 返回记录指针是否超出数据表末端,true表示是,false为否
rs.delete 删除当前记录,但记录指针不会向下移动
rs.addnew 添加记录到数据表末端
rs.update 更新数据表记录

判断所填数据是数字型

if not isNumeric(request("字段名称")) then
response.write "不是数字"
else
response.write "数字"
end if

经常使用到有关数据库的操作。包括连接代码、SQL命令等等,又不曾刻意去记忆它们(我本人是不愿意去记这东东),所以常常在用到的时候又去查书本,翻来翻去。一些比较少用的数据库还不一定能顺利找到,所以现在把它们全归纳到这里,提供大家参考。(个人水平有限,有缺陷之处,欢迎大家指正。)

<一>。数据库的连接方法:

1.Access数据库的DSN-less连接方法:

set adocon=Server.Createobject("adodb.connection")
adoconn.Open"Driver={Microsoft Access Driver(*.mdb)};DBQ="& _
Server.MapPath("数据库所在路径")

2.Access OLE DB连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Provider=Microsoft.Jet.OLEDB.4.0;"& _
"Data Source=" & Server.MapPath("数据库所在路径")

3.SQL server连接方法:

set adocon=server.createobject("adodb.recordset")
adocon.Open"Driver={SQL Server};Server=(Local);UID=***;PWD=***;"& _
"database=数据库名;"

4.SQL server OLE DB连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"provider=SQLOLEDB.1;Data Source=RITANT4;"& _
"user ID=***;Password=***;"& _
"inital Catalog=数据库名"

5.Oracle 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Driver={microsoft odbc for oracle};server=oraclesever.world;uid=admin;pwd=pass;"

6.Oracle OLE DB 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Provider=OraOLEDB.Oracle;data source=dbname;user id=admin;password=pass;"

7.dBase 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=————;"

8.mySQL 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"

9.Visual Foxpro 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"

10.MS text 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Driver={microsoft text driver(*.txt; *.csv)};dbq=—–;"&_
"extensions=asc,csv,tab,txt;Persist SecurityInfo=false;"

11.MS text OLE DB 连接方法:

set adocon=Server.Createobject("adodb.connection")
adocon.open"Provider=microsof.jet.oledb.4.0;data source=your_path;"&_
"Extended Properties’text;FMT=Delimited’"

<二>。常用的四种SQL命令:

1.查询数据记录(Select)
语法:Select 字段串行 From table Where 字段=内容
例子:想从book表中找出作者为"cancer"的所有记录,SQL语句便如下:
select * from book where author=’cancer’
"*"是取出book表所有的字段,如查询的字段值为数字,则其后的"内容"便无须加上单引号,

如是日期,则在Access中用(#)包括,而在SQL server中则用(’)包括,
如:

select * from book where id=1
select * from book where pub_date=#2002-1-7# (Access)
select * from book where pub_date=’2002-1-7’ (SQL Server)

提示:
日期函数to_date不是标准sql文,不是所有的数据库适用,所以大家在使用的时候要参考数据库具体语法

另外如果是查询传入的变量,则如下:

strau=request.form("author")
strsql="select * from book where author=’"&strau&"’"

如果查询的是数字,则:

intID=request.form("id")
strsql="select * from book where id="&intID

在很多数据库中,如:oracle,上面的语句是可以写成:
strsql="select * from book where id=’"&intID&"’"的。
但是字符型一定不能按照数字格式写,需要注意。

2.添加记录(Insert)
语法:Insert into table(field1,field2,….) Values (value1,value2,….)
例子:添加一作者是"cancer"的记录入book表:
insert into book (bookno,author,bookname) values (’CF001’,’cancer’,’Cancer无组件上传程序’)
同样,如果用到变量就如下:

strno=request.form("bookno")
strau=request.form("author")
strname=request.form("bookname")
strsql="insert into book (bookno,author,bookname) values (’"&strno&"’,’"&strau&"’,’"&strname&"’)"

3.用Recordset对象的Addnew插入数据的方法:
语法:

rs.addnew
rs("field1").value=value1
rs("field2").value=value2

rs.update

4.修改数据记录(Update)
语法:update table set field1=value1,field2=value2,…where fieldx=valuex
例子:update book set author=’babycrazy’ where bookno=’CF001’
如果用到变量就如下:

strno=request.form("bookno")
strau=request.form("author")
strsql="update book set author=’"&strau&"’ where bookno=’"&strno"’"

5.Recordset对象的Update方法:
语法:

rs("field1").value=value1
rs("field2").value=value2

rs.update

注意:使用语法3和语法5的时候,一定要注意字段的类型(尤其是日期型)一致,否则出错的几率非常的高。

例子:

strno=request.form("bookno")
strau=request.form("author")
set adocon=server.createobject("adodb.connection")
adocon.open "Driver={Microsoft Access Driver(*.mdb)};DBQ=" & _
Server.Mappath=("/cancer/cancer.mdb")
strsql="select * from book where bookno=’"&strno&"’"
set rs=server.createobject("adodb.recordset")
rs.open strsql,adconn,1,3
if not rs.eof then ’如果有此记录的话
rs("author").value=strau
rs.update
end if
rs.close
set rs=nothing
adocon.close
set adocon=nothing

6.删除一条记录(Delete)
语法:Delete table where field=value
例子:删除book表中作者是cancer的记录

delete book where author=’cancer’

(注意:如果book表中author字段的值为cancer的记录有多条,将会删除所有author为cancer的记录)

好了,学会了用这些操作,大家在用asp操作数据库的时候,该是没有什么问题了

2007年04月01日

The CreateParameter method creates and returns a Parameter object containing the specified properties like name, type, direction, size, and value.
CreateParameter的作用是:创建或返回一个新的参数对象,它可以是类似于名称、类型、尺寸大小和值这样的属性。

Note: This method does not automatically add the new Parameter to the collection. To add the Parameter to the Parameters Collection, use the Append property.
注意:这个方法不会将新参数添加到集合中。如果你要实现上述功能,可以使用Append属性。

Syntax
语法

Set objparameter=objcommand.CreateParameter(name,type,direction,size,value)

Parameter
参数
Description
描述
name Optional. The name of the Parameter object.
可选参数。指定参数对象的名称
type Optional. One of the DataTypeEnum contatants that specifies the data type for the Parameter object. Default is adEmpty. If you choose a variable-length data type, you will also need to specify the Size parameter or the Size property. If you specify adDecimal or adNumeric data type, you must also set the NumericScale and the Precision properties of the Parameter object.
 可选参数。可设置为DataTypeEnum常量集内的其中一个常量,以指名参数对象的数据类型。默认值是:adEmpty。如果你选择variable-length[变量-长度]数据类型,你必须还要指定Size参数和Size属性。如果你指定了adDecimal或adNumeric数据类型,你还必须要设置NumericScale[数值尺寸]以及参数对象中的Precision[精密度]属性
direction Optional. One of the ParameterDirectionEnum constants that defines the direction of the Parameter object. Default is adParamInput.
可选参数。可设置为ParameterDirectionEnum常量集内的一个常量,以定义参数对象的direction[方向]。默认值为adParamInput
size Optional. Specifies the length of a variable-length data type, if such a type was declared in the Type parameter. Default is zero.
可选参数。指定一个variable-length[变量-长度]数据类型,如果你在Type参数中声明了改类型的话。默认值为0
value Optional. The value of the Parameter object
可选参数。指定参数对象的值


DataTypeEnum Values

Specifies the data type of a Field, Parameter, or Property object
指定一个字段、参数或属性对象的数据类型:

Constant
常量
Value
Description
描述
adEmpty 0 No value
空值
adSmallInt 2 A 2-byte signed integer.
一个2位含正负号的整数
adInteger 3 A 4-byte signed integer.
一个4位含正负号的整数
adSingle 4 A single-precision floating-point value.
一个单精度浮点值
adDouble 5 A double-precision floating-point value.
一个双精度浮点值
adCurrency 6 A currency value
一个货币值
adDate 7 The number of days since December 30, 1899 + the fraction of a day.
日期值
adBSTR 8 A null-terminated character string.
一个null-terminated[不含后缀]的字符/字符串
adIDispatch 9 A pointer to an IDispatch interface on a COM object. Note: Currently not supported by ADO.
IDispatch(位于COM对象)界面指示器。
注意:现在还不被ADO支持
adError 10 A 32-bit error code
一个32位的错误代码
adBoolean 11 A boolean value.
一个逻辑值
adVariant 12 An Automation Variant. Note: Currently not supported by ADO.
一个自动操作的变量
注意:现在还不被ADO支持
adIUnknown 13 A pointer to an IUnknown interface on a COM object. Note: Currently not supported by ADO.
IUnknown(位于COM对象)界面指示器。
注意:现在还不被ADO支持
adDecimal 14 An exact numeric value with a fixed precision and scale.
拥有一个固定精确度和范围的一个精确数值
adTinyInt 16 A 1-byte signed integer.
一个1位含正负号的整数
adUnsignedTinyInt 17 A 1-byte unsigned integer.
一个1位不含正负号的整数
adUnsignedSmallInt 18 A 2-byte unsigned integer.
一个2位不含正负号的整数
adUnsignedInt 19 A 4-byte unsigned integer.
一个4位不含正负号的整数
adBigInt 20 An 8-byte signed integer.
一个8位含正负号的整数
adUnsignedBigInt 21 An 8-byte unsigned integer.
一个8位不含正负号的整数
adFileTime 64 The number of 100-nanosecond intervals since January 1,1601
从1601年1月1日开始计算的以100毫微秒为单位所经过的数量(即经过了多少个100毫微秒)
adGUID 72 A globally unique identifier (GUID)
全局统一标识符(GUID)
adBinary 128 A binary value.
一个二进制值
adChar 129 A string value.
一个字符串值
adWChar 130 A null-terminated Unicode character string.
一个null-terminated(不含后缀)的Unicode[统一的字符编码标准, 采用双字节对字符进行编码]字符/字符串
adNumeric 131 An exact numeric value with a fixed precision and scale.
拥有一个固定精确度和范围的一个精确数值
adUserDefined 132 A user-defined variable.
用户自定义变量
adDBDate 133 A date value (yyyymmdd).
日期值(yyyymmdd)
adDBTime 134 A time value (hhmmss).
时间值(hhmmss)
adDBTimeStamp 135 A date/time stamp (yyyymmddhhmmss plus a fraction in billionths).
一个日期/时间戳(yyyymmddhhmmss加上一个十一分之一的小数)
adChapter 136 A 4-byte chapter value that identifies rows in a child rowset
一个4位的chapter值,它指明了字记录集
adPropVariant 138 An Automation PROPVARIANT.
一个自动操作执行的PROPVARIANT
adVarNumeric 139 A numeric value (Parameter object only).
一个数值(仅支持参数[parameter]对象)
adVarChar 200 A string value (Parameter object only).
一个字符串值(仅支持参数[parameter]对象)
adLongVarChar 201 A long string value.
一个长字符串值
adVarWChar 202 A null-terminated Unicode character string.
一个null-terminated(不含后缀)的Unicode[统一的字符编码标准, 采用双字节对字符进行编码]字符/字符串
adLongVarWChar 203 A long null-terminated Unicode string value.
一个null-terminated(不含后缀)的Unicode[统一的字符编码标准, 采用双字节对字符进行编码] 长字符/字符串
adVarBinary 204 A binary value (Parameter object only).
一个二进制值(仅支持参数[parameter]对象)
adLongVarBinary 205 A long binary value.
一个长二进制值(仅支持参数[parameter]对象)
AdArray 0×2000 A flag value combined with another data type constant. Indicates an array of that other data type.
一个标记值,它是与其他的数据类型常数结合在一起使用的。它指明了包含其它数据类型的数组

ParameterDirectionEnum Values

Specifies whether the Parameter represents an input parameter, an output parameter, both an input and an output parameter, or the return value from a stored procedure.
指定参数是否代表了一个输入参数、一个输出参数或者同时代表了上述二者,或返回已有的程序值。

Constant
常量
Value
Description
描述
adParamUnknown 0 Direction is unknown
未知指示(说明)
adParamInput 1 Input parameter
输入参数
adParamOutput 2 Output parameter
输出参数
adParamInputOutput 3 Both input and output parameter
同时包含输入参数和输出参数
adParamReturnValue 4 Return value
返回值

2006年12月15日

SQL Server中的 @@IDENTITY 是获取数据表中最后一条插入数据的IDENTITY值。比如,表 A 中有个 ID 为自增1的字段,假设此时 ID 的值为100,现在如果我往表A插入一条数据,并在插入后 SELECT @@IDENTITY,则其返回 101,最后一条IDENTITY域(即ID域)的值。

现在问题来了, @@IDENTITY 它总是获取最后一条变更数据的自增字段的值,而忽略了进行变更操作所在的范围约束。比如,我有表 A 和表 B 两个表,现在我在表 A 上定义了一个Insert触发器,当在表 A 中插入一条数据时,自动在表 B 也插入一条数据。此时,大家注意,有两个原子操作:在A中插入一条数据,接着在B中随后插入一条数据。
现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,使用了 SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢?  答案很明显,是谁最后插入就输出谁,那么就是 B 了。于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还会影响到整个系统数据的混乱。
对于这种情况,可以考虑使用SCOPE_IDENTITY()函数;SCOPE_IDENTITY() 也是得到最后一条自增域的值,但是它是仅限在一个操作范围之内,SCOPE_IDENTITY ()只返回插入到当前作用域中的值,而不像 @@IDENTITY 是取全局操作的最后一步操作所产生的自增域的值的。
(注:在SQL Server中,@@identity、SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY 在功能上相似,因为它们都返回插入到 IDENTITY 列中的值。 IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。)
看下面的例子:
USE tempdb
GO
CREATE TABLE TZ (
Z_id int IDENTITY(1,1)PRIMARY KEY,
Z_name varchar(20) NOT NULL)
 
INSERT TZ
VALUES (‘Lisa’)
INSERT TZ
VALUES (‘Mike’)
INSERT TZ
VALUES (‘Carla’)
 
SELECT * FROM TZ
输出结果
Z_id Z_name
1 Lisa
2 Mike
3 Carla
CREATE TABLE TY (
Y_id int IDENTITY(100,5)PRIMARY KEY,
Y_name varchar(20) NULL)
 
INSERT TY (Y_name)
VALUES (‘boathouse’)
INSERT TY (Y_name)
VALUES (‘rocks’)
INSERT TY (Y_name)
VALUES (‘elevator’)
 
SELECT * FROM TY
输出结果
 Y_id Y_name
100  boathouse
105 rocks
110 elevator

 创建触发器

CREATE TRIGGER Ztrig
ON TZ
FOR INSERT AS
BEGIN
INSERT TY VALUES ()

END

 

INSERT TZ VALUES (‘Rosalie’)
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]

GO

输出结果

–Here is the result set.
SCOPE_IDENTITY
4
/*SCOPE_IDENTITY returned the last identity value in the same scope, which was the insert on table TZ*/
 
@@IDENTITY
115
/*@@IDENTITY returned the last identity value inserted to TY by the trigger, which fired due to an earlier insert on*/

2006年12月2日

搬家于CDD个人主页

     OLE DB(OLEDB)是微软的战略性的通向不同的数据源的低级应用程序接口。OLE DB不仅包括微软资助的标准数据接口开放数据库连通性(ODBC)的结构化问题语言(SQL)能力,还具有面向其他非SQL数据类型的通路。  

作为微软的组件对象模型(COM)的一种设计,OLE DB是一组读写数据的方法(在过去可能被称为渠道)。OLD DB中的对象主要包括数据源对象、阶段对象、命令对象和行组对象。使用OLE DB的应用程序会用到如下的请求序列:  初始化OLE–>连接到数据源–>发出命令–>处理结果–>释放数据源对象并停止初始化OLE

      OLE DB标准中定义的新概念—-OLE DB将传统的数据库系统划分为多个逻辑组件,这些组件之间相对独立又相互通信。这种组件模型中的各个部分被冠以不同的名称:数据提供者(Data Provider)。 提供数据存储的软件组件,小到普通的文本文件、大到主机上的复杂数据库,或者电子邮件存储,都是数据提供者的例子。有的文档把这些软件组件的开发商也称为数据提供者。

      我们要开启如Access 数据库中的数据,必须用ADO.NET 透过OLE DB 来开启。ADO.NET 利用OLE DB 来取得数据,这是因为OLE DB 了解如何和许多种数据源作沟通,所以对OLE DB有相当程度的了解是很重要的。OLE DB 为一种开放式的标准,并且设计成COM(Component
Object Model,一种对象的格式。凡是依照COM 的规格所制作出来的组件,皆可以提供功能让其它程序或组件所使用。)组件。OLE DB 最主要是由三个部分组合而成:

Data Providers 数据提供者

      凡是透过OLE DB 将数据提供出来的,就是数据提供者。例如SQL Server 数据库中的数据表,或是附文件名为mdb 的Access 数据库档案等,都是Data Provider。

Data Consumers 数据使用者

      凡是使用OLE DB 提供数据的程序或组件,都是OLE DB 的数据使用者。换句话说,凡是使用ADO 的应用程序或网页都是OLE DB 的数据使用者。

Service Components 服务组件

      数据服务组件可以执行数据提供者以及数据使用者之间数据传递的工作,数据使用者要向数据提供者要求数据时,是透过OLE DB 服务组件的查询处理器执行查询的工作,而查询到的结果则由指针引擎来管理。

       OLE DB 是 Microsoft 的数据访问模型。它使用组件对象模型 (COM) 接口,与 ODBC 不同的是,OLE DB 假定数据源使用的不是 SQL 查询处理器。

      Adaptive Server Anywhere 包括一个名为 ASAProv 的 OLE DB 提供程序。该提供程序可用于当前的 Windows 和 Windows CE 平台。

      您还可以结合使用 [用于 ODBC 的 Microsoft OLE DB 提供程序](MSDASQL) 和 Adaptive Server Anywhere ODBC 驱动程序来访问 Adaptive Server Anywhere。

      使用 Adaptive Server Anywhere OLE DB 提供程序具有以下几个优点:

      ·某些功能(如通过游标更新)不能通过 OLE DB/ODBC Bridge 来使用。

      ·如果您使用 Adaptive Server Anywhere OLE DB 提供程序,则在部署过程中无需 ODBC。

      ·MSDASQL 允许 OLE DB 客户端用于任何 ODBC 驱动程序,但不保证您可以使用每个 ODBC 驱动程序的全部功能。而使用 Adaptive Server Anywhere 提供程序,您可以从 OLE DB 编程环境完全访问 Adaptive Server Anywhere 的全部功能。

一、OLE DB 结构设计问题

      开始编写 OLE DB 应用程序之前应考虑以下问题:

      使用何种编程实现来编写 OLE DB 应用程序?

      Microsoft 提供多种库来解决该问题:OLE DB 模板库、OLE DB 属性以及 OLE DB SDK 中的原始 OLE DB 接口。另外,Microsoft 还提供帮助您编写程序的向导。有关这些实现的更详细的信息,请参见 OLE DB 模板、属性和其他实现。

      是否需要编写自己的提供程序?

      大多数开发人员无需这样。Microsoft 提供多种提供程序。无论用户何时创建一个数据连接,例如,当使用 ATL OLE DB 使用者向导向项目中添加使用者时,“数据链接属性”对话框都将列出系统中所有被注册的可用提供程序。如果其中一个提供程序适合于用户自己的数据存储和数据访问应用程序,最简单的办法就是使用该提供程序。但是,如果用户的数据存储不适合所提供的类别,则必须创建自己的提供程序。有关创建提供程序的信息,请参见 OLE DB 提供程序模板及其子主题。

      需要为自己的使用者提供何种级别的支持?

      一些使用者可能非常简单,另一些可能非常复杂。OLE DB 对象的功能由属性指定。使用 ATL OLE DB 使用者向导创建使用者或者使用数据库提供程序向导创建提供程序时,向导将为用户设置合适的对象属性来提供一组标准功能。但是,如果向导生成的使用者类或提供程序类并不具有您需要的所有支持功能,那么您需要查阅这些类在 OLE DB 模板库中的接口。这些接口包装原始 OLE DB 接口,提供附加实现以使其使用起来更加简单。

      例如,如果您希望更新行集合中的数据,但在使用向导创建使用者时却忘记指定该功能,则可以在创建使用者之后通过对命令对象设置 DBPROP_IRowsetChange 和 DBPROP_UPDATABILITY 属性来指定该功能。这样,当行集合创建之后,它将具有 IRowsetChange 接口。

      您是否有使用其他数据访问技术(ADO、ODBC 或 DAO)的旧版代码?

      由于可能有各样各样的技术组合(例如 ADO 组件和 OLE DB 组件一起使用、将 ODBC 代码迁移至 OLE DB 等等),所以 Visual C++ 文档不能涵盖所有的情形。

二、实战应用——使用OLE DB

1 概述

OLE DB的存在为用户提供了一种统一的方法来访问所有不同种类的数据源。OLE DB可以在不同的数据源中进行转换。利用OLE DB,客户端的开发人员在进行数据访问时只需把精力集中在很少的一些细节上,而不必弄懂大量不同数据库的访问协议。

OLE DB是一套通过COM接口访问数据的ActiveX接口。这个OLE DB接口相当通用,足以提供一种访问数据的统一手段,而不管存储数据所使用的方法如何。同时,OLE DB还允许开发人员继续利用基础数据库技术的优点,而不必为了利用这些优点而把数据移出来。

2 使用ATL使用OLE DB数据使用程序

由于直接使用OLE DB的对象和接口设计数据库应用程序需要书写大量的代码。为了简化程序设计,Visual C++提供了ATL模板用于设计OLE DB数据应用程序和数据提供程序。

利用ATL模板可以很容易地将OLE DB与MFC结合起来,使数据库的参数查询等复杂的编程得到简化。MFC提供的数据库类使OLE DB的编程更具有面向对象的特性。Viual C++所提供用于OLE DB的ATL模板可分为数据提供程序的模板和数据使用程序的模板。

使用ATL模板创建数据应用程序一般有以下几步骤:

创建应用框架

加入ATL产生的模板类

在应用中使用产生的数据访问对象

不用ATL使用OLE DB数据使用程序

利用ATL模板产生数据使用程序较为简单,但适用性不广,不能动态适应数据库的变化。下面我们介绍直接使用MFC OLE DB类来生成数据使用程序。

模板的使用

OLE DB数据使用者模板是由一些模板组成的,包括如下一些模板,下面对一些常用类作一些介绍。

  • 会话类

CDataSource类

CDataSource类与OLE DB的数据源对象相对应。这个类代表了OLE DB数据提供程序和数据源之间的连接。只有当数据源的连接被建立之后,才能产生会话对象,可以调用Open来打开数据源的连接。

CSession类

CSession所创建的对象代表了一个单独的数据库访问的会话。一个用CDataSource类产生的数据源对象可以创建一个或者多个会话,要在数据源对象上产生一个会话对象,需要调用函数Open()来打开。同时,会话对象还可用于创建事务操作。

CEnumeratorAccessor类

CEnumeratorAccessor类是用来访问枚举器查询后所产生的行集中可用数据提供程序的信息的访问器,可提供当前可用的数据提供程序和可见的访问器。

  • 访问器类

CAcessor类

CAccessor类代表与访问器的类型。当用户知道数据库的类型和结构时,可以使用此类。它支持对一个行集采用多个访问器,并且,存放数据的缓冲区是由用户分配的。

CDynamicAccessor类

CDynamicAccessor类用来在程序运行时动态的创建访问器。当系统运行时,可以动态地从行集中获得列的信息,可根据此信息动态地创建访问器。

CManualAccessor类

CManualAccessor类中以在程序运行时将列与变量绑定或者是将参数与变量捆定。

  • 行集类

CRowSet类

CRowSet类封装了行集对象和相应的接口,并且提供了一些方法用于查询、设置数据等。可以用Move()等函数进行记录移动,用GetData()函数读取数据,用Insert()、Delete()、SetData()来更新数据。

CBulkRowset类

CBulkRowset类用于在一次调用中取回多个行句柄或者对多个行进行操作。

CArrayRowset类

CArrayRowset类提供用数组下标进行数据访问。

  • 命令类

CTable类

CTable类用于对数据库的简单访问,用数据源的名称得到行集,从而得到数据。

CCommand类

CCommand类用于支持命令的数据源。可以用Open()函数来执行SQL命令,也可以Prepare()函数先对命令进行准备,对于支持命令的数据源,可以提高程序的灵活性和健壮性。

在stdafx.h头文件里,加入如下代码。

#include

extern CComModule _Module;

#include

#include

#include // if you are using schema templates

在stdafx.cpp文件里,加入如下代码。

#include

CComModule _Module;

决定使用何种类型的存取程序和行集。

获取数据

在打开数据源,会话,行集对象后就可以获取数据了。所获取的数据类型取决于所用的存取程序,可能需要绑定列。按以下步骤。

用正确的命令打开行集对象。

如果使用CManualAccessor,在使用之前与相应列进行绑定。要绑定列,可以用函数GetColumnInfo,如下所示:

// Get the column information

ULONG ulColumns = 0;

DBCOLUMNINFO* pColumnInfo = NULL;

LPOLESTR pStrings = NULL;

if (rs.GetColumnInfo(&ulColumns, &pColumnInfo, &pStrings) != S_OK)

AfxThrowOLEDBException(rs.m_pRowset, IID_IColumnsInfo);

struct MYBIND* pBind = new MYBIND[ulColumns];

rs.CreateAccessor(ulColumns, &pBind[0], sizeof(MYBIND)*ulColumns);

for (ULONG l=0; l

rs.AddBindEntry(l+1, DBTYPE_STR, sizeof(TCHAR)*40, &pBind[l].szValue, NULL, &pBind[l].dwStatus);

rs.Bind();

用while循环来取数据。在循环中,调用MoveNext来测试光标的返回值是否为S_OK,如下所示:

while (rs.MoveNext() == S_OK)

{

// Add code to fetch data here

// If you are not using an auto accessor, call rs.GetData()

}

在while循环内,可以通过不同的存取程序获取数据。

如果使用的是CAccessor类,可以通过使用它们的数据成员进行直接访问。如下所示:

如果使用的是CDynamicAccessor 或CDynamicParameterAccessor 类,可以通过GetValue或GetColumn函数来获取数据。可以用GetType来获取所用数据类型。如下所示:

while (rs.MoveNext() == S_OK)

{

// Use the dynamic accessor functions to retrieve your

// data

ULONG ulColumns = rs.GetColumnCount();

for (ULONG i=0; i

{

rs.GetValue(i);

}

}

如果使用的是CManualAccessor,可以指定自己的数据成员,绑定它们。就可以直接存取。如下所示:

while (rs.MoveNext() == S_OK)

{

// Use the data members you specified in the calls to

// AddBindEntry.

wsprintf("%s", szFoo);

}

决定行集的数据类型

在运行时决定数据类型,要用动态或手工的存取程序。如果用的是手工存取程序,可以用GetColumnInfo函数得到行集的列信息。从这里可以得到数据类型。

3 总结

由于现在有多种数据源,,想要对这些数据进行访问管理的唯一途径就是通过一些同类机制来实现,如OLE DB。高级OLE DB结构分成两部分:客户和提供者。客户使用由提供者生成的数据。

就像其它基于COM的多数结构一样,OLE DB的开发人员需要实现很多的接口,其中大部分是模板文件。

当生成一个客户对象时,可以通过ATL对象向导指向一个数据源而创建一个简单的客户。ATL对象向导将会检查数据源并创建数据库的客户端代理。从那里,可以通过OLE DB客户模板使用标准的浏览函数。

当生成一个提供者时,向导提供了一个很好的开端,它们仅仅是生成了一个简单的提供者来列举某一目录下的文件。然后,提供者模板包含了OLE DB支持的完全补充内容。在这种支持下,用户可以创建OLE DB提供者,来实现行集定位策略、数据的读写以及建立书签。

资料来源:Builder.com.cn

2006年10月16日

搬家于CDD个人主页