免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Visual Stuido.NET扩展存储过程 进入正题前,首先请确认你电脑上已经安装了MicrosoftVS.Net2003和MicrosoftSQLServer2000。一、建立数据库框架用SqlSever新建一个数据库Railway,并在Railway中加入两张表:Rou. -一、建立数据库框架用Sql Sever新建一个数据库Railway,并在Railway中加入两张表:Routes( TrainID(int), AllStations(varchar(2000)和Trains(TrainID(int),TrainName(varchar(10)下划线代表主键,Trains表中两项一起作主键,是为了列车的别名,例如T1特快1特1等等。最后,在Route表中加入如下记录:(0, |北京,0小时|石家庄,2小时|郑州,4小时|武昌,4小时|广州,9小时|)(1, |哈尔滨,0小时|北京,7小时|石家庄,1小时|郑州, 4小时|西安, 6小时|成都, 10小时|)在Trains表中加入:(0, J1)(0, 极快1)(1, J2)(1, 极快2)Route表中第二项的格式是|起点站,0小时|下一站,离上一站的时间|.|终点站,离上一站的时间|二、提出问题:1、寻找北京到郑州的最快路线;2、寻找哈尔滨到广州的最快路线。第一个问题很容易看穿,因为J1和J2都经过北京和郑州,只要比较这两条线路谁更快即可。结果应该是J2胜出,5小时。此问题不用扩展存储过程也很容易解决。第二个问题相对就复杂点。肯定需要中转,但应该选择哪个作为中转站?北京、石家庄还是郑州?这个问题的算法虽然不难,但在普通存储过程里却很难编写。三、用扩展存储过程解决第一个问题在Vs.Net中建立一个扩展存储过程项目,命名为xsTrainQuery,点确定之后,在弹出窗口中设置扩展存储过程名为xs_TrainQuery,完成。现在,Vs.Net自动生成了几个文件,如果你是我这种新手,就先读读Readme.txt,里面对每个文件的作用和加入、运行、删除扩展存储过程xs_TrainQuery的方法有详细解释。让我们把注意力集中到proc.cpp,这个文件的作用是实现xsTrainQuery.cpp中定义的接口,其内容如下:#include / 一些全局常量声明#ifdef _cplusplusextern C #endifRETCODE _declspec(dllexport) xs_TrainQuery(SRV_PROC *srvproc); /声明#ifdef _cplusplusRETCODE _declspec(dllexport) xs_TrainQuery(SRV_PROC *srvproc) /实现/.其中,RETCODE xs_TrainQuery(SRV_PROC*),正是在数据库中运行扩展存储过程xs_TrainQuery后将运行的方法,所以只需要在这一部分中加入适当的代码,就做出了一个扩展存储过程。SRV_PROC是一个结构,在中定义,代表一个数据库客户端连接的句柄,srv.h中几乎所有的方法都要用到这个句柄,但这个句柄背后究竟有什么数据,我们完全不用关心。(忽然想起写硕士毕业论文时觉得CBitmap类不好用所以自己傻乎乎地超级郁闷地做一个Image类的时候)此扩展存储过程调用的格式应该是xs_TrainQuery 起点站名,终点站名,结果 Output,那么解决第一个问题将分为以下几个步骤:1、传入两个车站名的值;2、读入同时含此二车站的所有列车路线;3、寻找最短的路线;4、生成结果并传出之。第一步,让我们解决传值问题。扩展存储过程中的值传入严格来说包括3步:先获得参数的类型、长度等信息,再设置此参数对应的局部变量的类型和长度,最后读入此参数,即先调用srv_paraminfo,再alloc一个合适的内存空间,最后调用srv_paraminfo将入参值存入此内存空间。srv_paraminfo的格式为:int srv_paraminfo(SRV_PROC *srvproc,int n,BYTE *pbType,ULONG *pcbMaxLen,ULONG *pcbActualLen,BYTE *pbData,BOOL *pfNull )其中:n代表是第几个参数,比如xs_TrainQuery 北京, 成都, 中,成都的n值为2,pbType, pcbMaxLen, pcbActualLen分别代表指向此参数的类型、最大长度和实际传入长度的指针,pbData代表指向此参数值的指针,pfNull代表此参数是否为NULL,若是,则运行srv_paraminfo后,*pfNull将被设置为TRUE,当此参数的信息存在时,srv_paraminfo返回SUCCEED,否则返回FAIL.我们现在要读入起点和终点站名,就需要如下代码:BOOL bfNull; / 记录入参是否为空(NULL)PBYTE pbType; / 入参的类型ULONG ulMaxLen = 20; / 入参的最大长度,令为20字节ULONG ulActualLen; / 入参的实际长度PBYTE pbStart; / 起点站名字PBYTE pbEnd; / 终点站名字/ 获得第1个参数,即起点站名的类型、长度等信息if ( srv_paraminfo(srvproc, 1, pbType, &ulMaxLen, &ulActualLen, NULL, &bfNULL) != SUCCEED )/ 一些异常处理代码/ 为起点站入参分配空间pbStart = (PBYTE):malloc(ulActualLen);if ( pbStart = NULL)/ 一些异常处理代码/ 获得第1个参数的值if ( srv_paraminfo(srvproc, 1, pbType, &ulMaxLen, &ulActualLen, pbStart, &bfNULL) != SUCCEED )/ 一些异常处理代码/ 重复上面的三步,但n变为2,pbStart变为pbEnd,读入终点站名第二步,从数据库中取得含二车站名的所有路线在扩展存储过程中连接数据库有两种方法,第一种请参见MS Sql Server ODS示例中的xp_dblib,这里只介绍第二种方法,采用SQL开头的一系列ODBC API.为了使用这些API,首先要在proc.cpp或者stdafx.h中加入#include .一次数据库连接的过程包括以下几个步骤:1、初始化ODBC连接,并分配环境句柄;2、设置环境;3、根据环境句柄分配数据库连接句柄;4、调用SQLDriverConnect连接MS SQL Serve数据源;5、分配和使用语句;6、调用SQLDisconnect断开连接;7、依次释放分配的句柄。直接用例子来说明,现在我们要从数据库中读取含此二车站名的所有路线,可以用下面的代码:SQLHENV hEnv = SQL_NULL_ENV; / 环境句柄SQLHDBC hDbc = SQL_NULL_HDBC; / 连接句柄SQLHSTMT hStmt = SQL_NULL_HSTMT; / 语句句柄 SQLCHAR connStr255 = Driver=SQL Server;SERVER=localhost;UID=你的用户名;PWD=你的密码;DATABASE=Railway;/ 分配环境句柄SQLAllocHandle(SQL_HANDLE_ENV, NULL, &hEnv);/ 设置连接环境,ODBC版本设为3.xSQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);/ 根据环境分配连接句柄SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);/ 建立数据库连接SQLDriverConnect(hDbc, NULL, connStr, SQL_NTS, NULL, 255, NULL, SQL_DRIVER_NOPROMPT);/ 根据连接分配语句句柄SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);/ 定义查询语句query,别忘记#include TCHAR query255 = select Routes.TrainID, AllStations from Routes, Trains where Routes.TrainID=Trains.TrainID and AllStations like %;_tcscat(query, (TCHAR*)pbStart);_tcscat(query, %);_tcscat(query, (TCHAR*)pbEnd);_tcscat(query, %);/ 现在,query=select Routes like %起点站%终点站%,我们运行此查询SQLExecDirect(hStmt, (SQLCHAR*)query, SQL_NTS);/ 获得查询所得的行数UINT uiRowsCount; /结果集中的行数SQLSetStmtAttr(hStmt, SQL_ATTR_ROWS_FETCHED_PTR), (void*)&uiRowsCount, sizeof(SQLINTEGER);/ 初始化结果集数组,包括两个:TrainID和AllStationsint *piTrainID = (int*):malloc(uiRowsCount * sizeof(int);PCHAR *ppcStations = (PCHAR*):malloc(uiRowsCount * sizeof(PCHAR);/ 因为结果集中第一列,即TrainID为整型,长度不变,故可以直接绑定SQLBindCol(hStmt, 1, SQL_INTEGER, (SQLPOINTER)piTrainID, sizeof(int), NULL);/ 取出第二列的数据,因为其长度不定,故必须先获得长度SQLINTEGER lColLen; / 字符串的列,即AllStations长度UINT nRow = 0; / 行标while (SQLFetch(hStmt) = SQL_SUCCESS_WITH_INFO) /取出一行/ 获得长度SQLGetData(hStmt, 2, SQL_CHAR, NULL, 0, &lColLen);/ 根据长度为第二列的数据分配空间ppcStationnRow = :malloc(lColLen);/ 获得数据SQLGetData(hStmt, 2, SQL_CHAR, ppcStationnRow, lColLen, &lColLen);/ 行标随行的Fetch递增+nRow;/ 现在,我们就取出了所有Train
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 环保无害油菜籽订购合同
- 2024的区域代理合同范文
- 工厂房屋租赁合同谈判技巧
- 基金交易服务协议书模板
- 城市婚姻登记处离婚协议样本
- 机动车维修技术培训协议
- 个人承包水利工程协议
- 货车租赁协议书
- 2024广告公司工程合同范本
- 2024深圳市工程施工合同
- 议论文写作技巧
- 教科版五年级科学上册(风的作用) 教学课件
- 二年级下册语文试题 -“诗词大会”题库二 (word版有答案) 人教部编版
- GB/T 7702.20-2008煤质颗粒活性炭试验方法孔容积和比表面积的测定
- 新历史主义文艺思潮
- GB/T 40120-2021农业灌溉设备灌溉用热塑性可折叠软管技术规范和试验方法
- GB/T 3903.2-1994鞋类通用检验方法耐磨试验方法
- GB/T 10801.2-2018绝热用挤塑聚苯乙烯泡沫塑料(XPS)
- 12J5-1 平屋面建筑标准设计图
- 中印边境争端
- 《墨梅》课件(省一等奖)
评论
0/150
提交评论