知识大全 Visual Stuido.NET扩展存储过程

Posted 长度

篇首语:虎瘦雄心在,人穷志不短。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Visual Stuido.NET扩展存储过程相关的知识,希望对你有一定的参考价值。

Visual Stuido.NET扩展存储过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   一 建立数据库框架    用Sql Sever新建一个数据库Railway 并在Railway中加入两张表     Routes  ( TrainID(int) AllStations(varchar( ))  )    和    Trains  (  TrainID(int)   TrainName(varchar( ))  )    下划线代表主键 Trains表中两项一起作主键 是为了列车的别名 例如T =特快 =特 等等     最后 在Route表中加入如下记录     ( |北京 小时|石家庄 小时|郑州 小时|武昌 小时|广州 小时| )  ( |哈尔滨 小时|北京 小时|石家庄 小时|郑州 小时|西安 小时|成都 小时| )    在Trains表中加入:    ( J )  ( 极快 )  ( J )  ( 极快 )    Route表中第二项的格式是 |起点站 小时|下一站 离上一站的时间| |终点站 离上一站的时间|      二 提出问题      寻找北京到郑州的最快路线    寻找哈尔滨到广州的最快路线     第一个问题很容易看穿 因为J 和J 都经过北京和郑州 只要比较这两条线路谁更快即可 结果应该是J 胜出 小时 此问题不用扩展存储过程也很容易解决     第二个问题相对就复杂点 肯定需要中转 但应该选择哪个作为中转站?北京 石家庄还是郑州?这个问题的算法虽然不难 但在普通存储过程里却很难编写      三 用扩展存储过程解决第一个问题    在Vs Net中建立一个扩展存储过程项目 命名为xsTrainQuery 点确定之后 在弹出窗口中设置扩展存储过程名为xs_TrainQuery 完成     现在 Vs Net自动生成了几个文件 如果你是我这种新手 就先读读Readme txt 里面对每个文件的作用和加入 运行 删除扩展存储过程xs_TrainQuery的方法有详细解释     让我们把注意力集中到proc cpp 这个文件的作用是实现xsTrainQuery cpp中定义的接口 其内容如下     #include    // 一些全局常量声明    #ifdef __cplusplus  extern C   #endif  RETCODE __declspec(dllexport) xs_TrainQuery(SRV_PROC *srvproc); //声明  #ifdef __cplusplus    RETCODE __declspec(dllexport) xs_TrainQuery(SRV_PROC *srvproc) //实现    //       其中 RETCODE xs_TrainQuery(SRV_PROC*) 正是在数据库中运行扩展存储过程xs_TrainQuery后将运行的方法 所以只需要在这一部分中加入适当的代码 就做出了一个扩展存储过程     SRV_PROC是一个结构 在中定义 代表一个数据库客户端连接的句柄 srv h中几乎所有的方法都要用到这个句柄 但这个句柄背后究竟有什么数据 我们完全不用关心 (忽然想起写硕士毕业论文时觉得CBitmap类不好用所以自己傻乎乎地超级郁闷地做一个Image类的时候……)    此扩展存储过程调用的格式应该是xs_TrainQuery [起点站名 终点站名 结果 Output] 那么解决第一个问题将分为以下几个步骤      传入两个车站名的值    读入同时含此二车站的所有列车路线    寻找最短的路线    生成结果并传出之     第一步 让我们解决传值问题     扩展存储过程中的值传入严格来说包括 步 先获得参数的类型 长度等信息 再设置此参数对应的局部变量的类型和长度 最后读入此参数 即先调用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值为   pbType pcbMaxLen pcbActualLen分别代表指向此参数的类型 最大长度和实际传入长度的指针   pbData代表指向此参数值的指针   pfNull代表此参数是否为NULL 若是 则运行srv_paraminfo后 *pfNull将被设置为TRUE 当此参数的信息存在时 srv_paraminfo返回SUCCEED 否则返回FAIL     我们现在要读入起点和终点站名 就需要如下代码       BOOL bfNull; // 记录入参是否为空(NULL)  PBYTE pbType; // 入参的类型  ULONG ulMaxLen = ; // 入参的最大长度 令为 字节  ULONG ulActualLen; // 入参的实际长度  PBYTE pbStart; // 起点站名字  PBYTE pbEnd; // 终点站名字  // 获得第 个参数 即起点站名的类型 长度等信息  if ( srv_paraminfo(srvproc pbType &ulMaxLen &ulActualLen NULL &bfNULL) !=  SUCCEED )    // 一些异常处理代码    // 为起点站入参分配空间  pbStart = (PBYTE)::malloc(ulActualLen);  if ( pbStart == NULL)    // 一些异常处理代码    // 获得第 个参数的值  if ( srv_paraminfo(srvproc pbType &ulMaxLen &ulActualLen pbStart &bfNULL)  != SUCCEED )    // 一些异常处理代码    // 重复上面的三步 但n变为 pbStart变为pbEnd 读入终点站名      第二步 从数据库中取得含二车站名的所有路线    在扩展存储过程中连接数据库有两种方法 第一种请参见MS Sql Server ODS示例中的xp_dblib 这里只介绍第二种方法 采用SQL开头的一系列ODBC API     为了使用这些API 首先要在proc cpp或者stdafx h中加入#include     一次数据库连接的过程包括以下几个步骤      初始化ODBC连接 并分配环境句柄      设置环境      根据环境句柄分配数据库连接句柄      调用SQLDriverConnect连接MS SQL Serve数据源      分配和使用语句      调用SQLDisconnect断开连接      依次释放分配的句柄     直接用例子来说明 现在我们要从数据库中读取含此二车站名的所有路线 可以用下面的代码       SQLHENV hEnv = SQL_NULL_ENV; // 环境句柄  SQLHDBC hDbc = SQL_NULL_HDBC; // 连接句柄  SQLHSTMT hStmt = SQL_NULL_HSTMT; // 语句句柄  SQLCHAR connStr[ ] = Driver=SQL Server;SERVER=localhost;UID=你的用户名;PWD=你的密码;DATABASE=Railway; ;  // 分配环境句柄  SQLAllocHandle(SQL_HANDLE_ENV NULL &hEnv);  // 设置连接环境 ODBC版本设为 x  SQLSetEnvAttr(hEnv SQL_ATTR_ODBC_VERSION (SQLPOINTER)SQL_OV_ODBC SQL_IS_INTEGER);  // 根据环境分配连接句柄  SQLAllocHandle(SQL_HANDLE_DBC hEnv &hDbc);  // 建立数据库连接  SQLDriverConnect(hDbc NULL connStr SQL_NTS NULL NULL SQL_DRIVER_NOPROMPT);  // 根据连接分配语句句柄  SQLAllocHandle(SQL_HANDLE_STMT hDbc &hStmt);    // 定义查询语句query 别忘记#include   TCHAR query[ ] = 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和AllStations  int *piTrainID = (int*)::malloc(uiRowsCount * sizeof(int));  PCHAR *ppcStations = (PCHAR*)::malloc(uiRowsCount * sizeof(PCHAR));    // 因为结果集中第一列 即TrainID为整型 长度不变 故可以直接绑定  SQLBindCol(hStmt SQL_INTEGER (SQLPOINTER)piTrainID sizeof(int) NULL);    // 取出第二列的数据 因为其长度不定 故必须先获得长度  SQLINTEGER lColLen; // 字符串的列 即AllStations长度  UINT nRow = ; // 行标    while (SQLFetch(hStmt) == SQL_SUCCESS_WITH_INFO) //取出一行    // 获得长度  SQLGetData(hStmt SQL_CHAR NULL &lColLen);  // 根据长度为第二列的数据分配空间  ppcStation[nRow] = ::malloc(lColLen);  // 获得数据  SQLGetData(hStmt SQL_CHAR ppcStation[nRow] lColLen &lColLen);  // 行标随行的Fetch递增  ++nRow;    // 现在 我们就取出了所有TrainID和AllStations  // 关闭数据库连接 释放资源  SQLFreeHandle(SQL_HANDLE_STMT hStmt);  SQLDisConnect(hDbc);  SQLFreeHandle(SQL_HANDLE_DBC hDbc);  SQLFreeHandle(SQL_HANDLE_ENV hEnv); cha138/Article/program/net/201311/12221

相关参考

知识大全 关于SQL访问注册表的扩展存储过程

关于SQL访问注册表的扩展存储过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  SQLServ

知识大全 关于ASP.NET2.0编写扩展存储过程

关于ASP.NET2.0编写扩展存储过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 用JBuilder实现类似Visual Studio的宏扩展功能

用JBuilder实现类似VisualStudio的宏扩展功能  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 后台运行一个主存储过程,主存储过程通过管道同前端过程通信的例子

  beginmaxpro为提交主存储过程起动的程序  maxpro为主存储过程  readmaxpro为主存佳话  使用ORACLE中的DBMS_PIPE管道能力注意要明文给于用户EXECUTEAN

知识大全 如何通过hibernate调用存储过程

用hibernate操作数据库可以通过获取的session值调用connection()方法获取connection从而调用存储过程java调用存储过程什么是存储过程?存储过程是指保存在数据库并在数据

知识大全 如何调试oracle存储过程

  PL/SQL中为我们提供了调试存储过程的功能可以帮助你完成存储过程的预编译与测试  点击要调试的存储过程右键选择TEST  如果需要查看变量当然调试都需要在右键菜单中选择Adddebuginfor

知识大全 PHPOracle存储过程

PHPOracle存储过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  存储过程是实际位于Or

知识大全 java调用oracle存储过程

  一无返回值的存储过程  存储过程为  CREATEORREPLACEPROCEDURETESTA(PARAINVARCHARPARAIN VARCHAR) 

知识大全 分页SQLServer存储过程

分页SQLServer存储过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  /*用存储过程实现

知识大全 oracle存储过程创建表分区实例

  用存储过程创建数据表:创建时注意必须添加authidcurrent_user如果创建的表已存在存储过程继续执行但如不不加此关键语句存储过程将出现异常这个语句相当于赋权限例创建语句如下  复制代码代