免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2535 | 回复: 5
打印 上一主题 下一主题

linux下读取sqlserver2000的方法和程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-02-27 17:21 |只看该作者 |倒序浏览
哎~ 弄了几天,在 菜青虫 朋友的帮助下,终于搞定了,并写了个类~

主要参考了freeTDS中的 tsql.c 文件,朋友们去看那个,比我做的好的多,也就是改了改.

但请不要学我的代码! 我代码很不规范~我的C也很差 ,期望高手能帮我把代码重写一下

请下载安装:freeTDS


  1. /*
  2. author: ukalpa@sohu.com
  3. date  :        2004-02-26
  4. */
  5. -----------------------------------------
  6. //mssql.h


  7. // header
  8. #include <stdio.h>;
  9. #include <string.h>;
  10. #include <stdlib.h>;  
  11. #include <unistd.h>;
  12. #include <locale.h>;
  13. #include <sys/time.h>;
  14. #include <time.h>;
  15. #include <assert.h>;

  16. #include <tds.h>;
  17. #include <tdsconvert.h>;

  18. #define PERLENGTH 512

  19. /* define function */

  20. // 转换成小写
  21. int tolower(int ch)
  22. {
  23.         if (ch >; 64 && ch < 91)
  24.         {
  25.                 return (ch + 32);
  26.         }
  27. }

  28. char *strlwr(char *str)
  29. {
  30.         for (int i = 0; i < strlen(str); i++)
  31.         {
  32.                 tolower(str[i]);
  33.         }
  34.         return str;
  35. }

  36. int tsql_handle_message(TDSCONTEXT * context, TDSSOCKET * tds, TDSMSGINFO * msg)
  37. {       
  38.         if (msg->;msg_number == 0) {
  39.                 fprintf(stderr, "%s\n", msg->;message);
  40.                 return 0;
  41.         }

  42.         if (msg->;msg_number != 5701 && msg->;msg_number != 20018) {
  43.                 fprintf(stderr, "Msg %d, Level %d, State %d, Server %s, Line %d\n%s\n",
  44.                         msg->;msg_number, msg->;msg_level, msg->;msg_state, msg->;server, msg->;line_number, msg->;message);
  45.         }

  46.         return 0;
  47. }

  48. //本版块需要用到的自定义函数
  49. /*
  50. *        函数功能:创建2维数组
  51. *        x : 数组参数名
  52. *        rows : 行数
  53. *        cols : 列数
  54. */
  55. template <class T>;
  56. void Make2DArray(T*** &x, int rows, int cols)
  57. {
  58.         //创建行指针
  59.         x = new T** [rows];
  60.         //为每行分配空间
  61.         for(int i = 0; i < rows; i++)
  62.         {
  63.                 x[i] = new T* [cols];
  64.                 for(int j = 0; j < cols; j++)
  65.                 {
  66.                         x[i][j] = new char [255];
  67.                 }
  68.         }
  69. }

  70. /*
  71. *        函数功能:释放2维数组
  72. *        x : 数组参数名
  73. *        rows : 行数
  74. */
  75. template <class T>;
  76. void Delete2DArray(T*** &x, int rows, int cols)
  77. {
  78.         //释放为每行所分配的空间
  79.         for(int i = 0; i < rows; i++)
  80.         {
  81.                 for(int j = 0; j < cols; j++)
  82.                 {
  83.                         delete [] x[i][j];
  84.                 }
  85.                 delete[] x[i];
  86.         }
  87.         //删除行指针
  88.         delete[] x;
  89.         x = NULL;
  90. }
  91. //结束本版块需要用到的自定义函数

  92. /* end define function */

  93. class mssql{
  94. public:
  95.         mssql(const char *host, int port, const char *user, const char *pass);
  96.         ~mssql();
  97.         bool ms_connect(const char *host, int port, const char *user, const char *pass);        //连接
  98.         void selectdb(const char *db);        //选择数据库
  99.         void errormsg(const char *msg);        //错误信息
  100.         void query(const char *query);        //执行query语句
  101.         void freem();        //释放
  102.         char **fetch_array();
  103.         int numrows();
  104.         int numcols();

  105. private:
  106.         int current;
  107.         int get_rows;
  108.         int get_cols;
  109.         char ***my_res;
  110.         const char *locale;
  111.         char *charset;
  112.         TDSSOCKET *tds;
  113.         TDSLOGIN *login;
  114.         TDSCONTEXT *context;
  115.         TDSCONNECTINFO *connect_info;

  116.         /* used in query () */
  117.        
  118.         int rc, i;
  119.         int ctype;
  120.         unsigned char *src;
  121.         char message[128];
  122.         CONV_RESULT dres;
  123.         TDSCOLINFO *col;
  124.         TDS_INT srclen;
  125.         TDS_INT rowtype;
  126.         TDS_INT resulttype;
  127.         TDS_INT computeid;
  128.         struct timeval start, stop;

  129.         //char **cols_name;        // 列名称
  130.         //char **cols_values;        // 列描述
  131.        
  132.         /* end used in query() */
  133.        
  134. };

  135. mssql::mssql(const char *host, int port, const char *user, const char *pass)
  136. {
  137.         // init
  138.         this->;locale = NULL;
  139.         this->;charset = NULL;
  140.         this->;get_rows = 0;
  141.         this->;get_cols = 0;
  142.         this->;current = 0;

  143.         //this->;cols_name = NULL;
  144.         //this->;cols_values = NULL;

  145.         this->;ms_connect(host, port, user, pass);
  146. }

  147. bool mssql::ms_connect(const char *host, int port, const char *user, const char *pass)
  148. {
  149.         //step 1 : init
  150.         this->;login = tds_alloc_login();        //初始化login结构,分配内存
  151.         this->;context = tds_alloc_context();//初始化context,获得当前信息

  152.         if (this->;context->;locale && !this->;context->;locale->;date_fmt)
  153.         {
  154.                 /* set default in case there`s no locale file */
  155.                 this->;context->;locale->;date_fmt = strdup("%b %e %Y %I:%M%p");
  156.         }
  157.        
  158.         this->;context->;msg_handler = tsql_handle_message;
  159.         this->;context->;err_handler = tsql_handle_message;

  160.         //step 2 : connect mssql
  161.         setlocale(LC_ALL, "");
  162.         this->;locale = setlocale(LC_ALL, NULL);
  163. #if HAVE_LOCALE_CHARSET
  164.         this->;charset = locale_charset();        //charset
  165. #endif
  166. #if HAVE_NL_LANGINFO && defined(CODESET)
  167.         if (!this->;charset)
  168.                 this->;charset = nl_langinfo(CODESET);        //language
  169. #endif

  170.         //
  171.         tds_set_user(this->;login, user);
  172.         tds_set_app(this->;login, "TSQL");
  173.         tds_set_library(this->;login, "TDS_Library");
  174.         tds_set_server(this->;login, host);
  175.         tds_set_port(this->;login, port);
  176.         if (!this->;charset) {
  177.                 this->;charset = "ISO-8859-1";
  178.         }
  179.         tds_set_client_charset(this->;login, this->;charset);
  180.         tds_set_language(this->;login, "us_english");
  181.         tds_set_passwd(this->;login, pass);

  182.         /* Try to open a connection */
  183.         this->;tds = tds_alloc_socket(this->;context, 512);        //初始化socket
  184.         tds_set_parent(this->;tds, NULL);

  185.         this->;connect_info = tds_read_config_info(NULL, this->;login, this->;context->;locale);

  186.         if (!this->;connect_info || tds_connect(this->;tds, this->;connect_info) == TDS_FAIL)
  187.         {
  188.                 tds_free_connect(this->;connect_info);
  189.                 //fprintf(stderr, "There was a problem connecting to the server\n");
  190.                 //exit(1);
  191.                 this->;errormsg("There was a problem connecting to the server\n");
  192.         }
  193.         tds_free_connect(this->;connect_info);
  194. }


  195. mssql::~mssql()
  196. {
  197.         this->;freem();
  198. }

  199. void mssql::errormsg(const char *msg)
  200. {
  201.         printf("Content-Type: text/html \n\n");
  202.         printf("ErrorMsg: %s<br>;\n", msg);
  203.         this->;freem();
  204.         exit(1);
  205. }

  206. //
  207. void mssql::query(const char *query)
  208. {
  209.         //先判断是否get_rows为空,如果未空,则清空资源
  210.         if (this->;get_rows >; 0)
  211.         {
  212.                 Delete2DArray(this->;my_res, this->;get_rows, this->;get_cols);
  213.                 this->;get_rows = 0;
  214.         }

  215.        
  216.         if (NULL == query || 0 == strcmp(query, ""))
  217.         {
  218.                 this->;errormsg("查询语句不能为空");
  219.         }

  220.         char prev[7];
  221.         memset(prev, 0, 7);
  222.         prev[0] = query[0];
  223.         prev[1] = query[1];
  224.         prev[2] = query[2];
  225.         prev[3] = query[3];
  226.         prev[4] = query[4];
  227.         prev[5] = query[5];
  228.         prev[6] = 0;

  229.         strlwr(prev);
  230.         //先分析query语句,如果是select语句
  231.         if (strstr(prev, "select"))
  232.         {
  233.                 //
  234.                 char *tmp_query1, *tmp_query2 = NULL;
  235.                 tmp_query1 = new char [strlen(query) + 1];
  236.                 strcpy(tmp_query1, query);
  237.                
  238.                 strlwr(tmp_query1);        //小写
  239.                
  240.                 tmp_query2 = strstr(tmp_query1, "from");
  241.                 tmp_query2 = (char *)(query + (tmp_query2 - tmp_query1));
  242.                 sprintf(tmp_query1, "select count(*) %s", tmp_query2);

  243.                 this->;rc = tds_submit_query(this->;tds, tmp_query1);

  244.                 if (this->;rc != TDS_SUCCEED)
  245.                 {
  246.                         delete [] tmp_query1;
  247.                         tmp_query1 = NULL;
  248.                         this->;errormsg("query语句执行失败\n");
  249.                 }

  250.                 while ((this->;rc = tds_process_result_tokens(this->;tds, &this->;resulttype, NULL)) == TDS_SUCCEED) {

  251.                         if (this->;resulttype == TDS_ROW_RESULT)
  252.                         {
  253.                                 this->;get_rows = 0;
  254.                                 while ((this->;rc = tds_process_row_tokens(this->;tds, &this->;rowtype, &this->;computeid)) == TDS_SUCCEED) {
  255.                                         this->;get_rows++;

  256.                                         if (!this->;tds->;res_info)
  257.                                                 continue;

  258.                                         for (i = 0; i < this->;tds->;res_info->;num_cols; i++) {
  259.                                                 if (tds_get_null(this->;tds->;res_info->;current_row, i)) {
  260.                                                         continue;
  261.                                                 }
  262.                                                 this->;col = this->;tds->;res_info->;columns[i];
  263.                                                 this->;ctype = tds_get_conversion_type(this->;col->;column_type, this->;col->;column_size);

  264.                                                 this->;src = &(this->;tds->;res_info->;current_row[this->;col->;column_offset]);
  265.                                                 if (is_blob_type(this->;col->;column_type))
  266.                                                         this->;src = (unsigned char *) ((TDSBLOBINFO *) this->;src)->;textvalue;
  267.                                                 this->;srclen = this->;col->;column_cur_size;


  268.                                                 if (tds_convert(this->;tds->;tds_ctx, this->;ctype, (TDS_CHAR *) this->;src, this->;srclen, SYBVARCHAR, &this->;dres) < 0)
  269.                                                         continue;


  270.                                                         //fprintf(stdout, "%s\t", this->;dres.c);
  271.                                                 this->;get_rows = atoi(this->;dres.c);
  272.                                                 free(this->;dres.c);
  273.                                         }
  274.                                 }
  275.                         }
  276.                 }


  277.                 delete [] tmp_query1;
  278.                 tmp_query1 = NULL;
  279.         }

  280.        
  281.         //{
  282.        
  283.         this->;rc = tds_submit_query(this->;tds, query);

  284.         if (this->;rc != TDS_SUCCEED)
  285.         {
  286.                 this->;errormsg("query语句执行失败\n");
  287.         }

  288.         int i = 0, j = 0, t = 0;
  289.         //先将字段名保存到数组中
  290.         while ((this->;rc = tds_process_result_tokens(this->;tds, &this->;resulttype, NULL)) == TDS_SUCCEED) {

  291.                 switch (this->;resulttype) {
  292.                 case TDS_ROWFMT_RESULT:        //打印字段名
  293.                         //
  294.                         this->;get_cols = this->;tds->;res_info->;num_cols;

  295.                         // 开始进行数据读取工作
  296.                         if (this->;get_rows >; 0)
  297.                         {
  298.                                 // 行 + 1 , 0,0 表示列
  299.                                 this->;get_rows++;
  300.                                 Make2DArray(this->;my_res, this->;get_rows, this->;get_cols);
  301.                         }
  302.                        
  303.                         if (this->;tds->;res_info) {
  304.                                 for (i = 0; i < this->;tds->;res_info->;num_cols; i++) {
  305.                                         //fprintf(stdout, "%s\t", this->;tds->;res_info->;columns[i]->;column_name);

  306.                                         t = strlen(this->;my_res[j][i]);

  307.                                         while (t < strlen(this->;tds->;res_info->;columns[i]->;column_name))
  308.                                         {
  309.                                                 t += PERLENGTH;
  310.                                         }

  311.                                         this->;my_res[j][i] = (char *)realloc(this->;my_res[j][i], t * sizeof(char));
  312.                                         if (!this->;my_res[j][i])
  313.                                         {
  314.                                                 this->;errormsg("内存分配失败");
  315.                                         }

  316.                                         memset(this->;my_res[j][i], 0, t);
  317.                                         strcpy(this->;my_res[j][i], this->;tds->;res_info->;columns[i]->;column_name);

  318.                                 }
  319.                         }
  320.                         break;
  321.                 case TDS_ROW_RESULT:

  322.                         while ((this->;rc = tds_process_row_tokens(this->;tds, &this->;rowtype, &this->;computeid)) == TDS_SUCCEED) {
  323.                        
  324.                                 j++;        // go tag
  325.                                 if (!this->;tds->;res_info)
  326.                                         continue;

  327.                                         //fprintf(stdout, "%d, %s\n", this->;tds->;res_info->;null_info_size, this->;tds->;res_info->;current_row);
  328.                                 for (i = 0; i < this->;get_cols; i++)
  329.                                 {
  330.                                         if (tds_get_null(this->;tds->;res_info->;current_row, i))
  331.                                         {
  332.                                                 continue;
  333.                                         }
  334.                                         this->;col = this->;tds->;res_info->;columns[i];
  335.                                         this->;ctype = tds_get_conversion_type(this->;col->;column_type, this->;col->;column_size);

  336.                                         this->;src = &(this->;tds->;res_info->;current_row[col->;column_offset]);
  337.                                         if (is_blob_type(this->;col->;column_type))
  338.                                                 this->;src = (unsigned char *) ((TDSBLOBINFO *) this->;src)->;textvalue;
  339.                                         this->;srclen = this->;col->;column_cur_size;


  340.                                         if (tds_convert(this->;tds->;tds_ctx, this->;ctype, (TDS_CHAR *) this->;src, this->;srclen, SYBVARCHAR, &this->;dres) < 0)
  341.                                                 continue;

  342.                                         t = strlen(this->;my_res[j][i]);

  343.                                         while (t < strlen(this->;tds->;res_info->;columns[i]->;column_name))
  344.                                         {
  345.                                                 t += PERLENGTH;
  346.                                         }

  347.                                         this->;my_res[j][i] = (char *)realloc(this->;my_res[j][i], t * sizeof(char));
  348.                                         if (!this->;my_res[j][i])
  349.                                         {
  350.                                                 this->;errormsg("内存分配失败");
  351.                                         }

  352.                                         memset(this->;my_res[j][i], 0, t);
  353.                                         strcpy(this->;my_res[j][i], this->;dres.c);

  354.                                         free(this->;dres.c);
  355.                                 }
  356.                         }
  357.                         break;
  358.                 case TDS_STATUS_RESULT:
  359.                         printf("(return status = %d)\n", this->;tds->;ret_status);
  360.                         break;
  361.                 default:
  362.                         break;
  363.                 }
  364.         }
  365.        
  366.         //}
  367. }

  368. //释放内存
  369. void mssql::freem()
  370. {
  371.         if (this->;get_rows >; 0)
  372.         {
  373.                 //Delete2DArray(this->;my_res, this->;get_rows, this->;get_cols);
  374.                 this->;get_rows = 0;
  375.         }
  376.         tds_free_socket(this->;tds);
  377.         tds_free_login(this->;login);
  378.         tds_free_context(this->;context);
  379. }

  380. //选择数据库
  381. void mssql::selectdb(const char *db)
  382. {
  383.         if (NULL == db || 0 == strcmp(db, ""))
  384.         {
  385.                 this->;errormsg("数据库未指定为空");
  386.         }
  387.         char tmp_str[100];
  388.         memset(tmp_str, 0, 100);
  389.         sprintf(tmp_str, "use %s", db);
  390.         this->;rc = tds_submit_query(this->;tds, tmp_str);

  391.         if (this->;rc != TDS_SUCCEED)
  392.         {
  393.                 this->;errormsg("数据库无法连接");
  394.         }

  395.         int i = 0;
  396.         tds_process_result_tokens(this->;tds, &this->;resulttype, NULL);
  397.         /*
  398.         while ((this->;rc = tds_process_result_tokens(this->;tds, &this->;resulttype, NULL)) == TDS_SUCCEED)
  399.         {
  400.                 //
  401.                 i++;
  402.                 printf("%d\n", i);
  403.         }
  404.         */
  405. }

  406. //取行
  407. char ** mssql::fetch_array()
  408. {
  409.         if (this->;current >; (this->;get_rows - 2))
  410.         {
  411.                 return NULL;
  412.         }
  413.         else
  414.         {
  415.                 this->;current++;        //偏移
  416.                 return (this->;my_res[this->;current]);
  417.         }
  418. }

  419. //获得行数
  420. int mssql::numrows()
  421. {
  422.         if (this->;get_rows >; 1)
  423.         {
  424.                 return (this->;get_rows - 1);
  425.         }
  426.         else
  427.         {
  428.                 return 0;
  429.         }
  430. }

  431. //获得列数
  432. int mssql::numcols()
  433. {
  434.         return this->;get_cols;
  435. }

复制代码



执行文件:

  1. /*
  2. *        testsql.cpp
  3. *  need freetds support
  4. *  cmd : g++ -o testsql testsql.cpp -ltds -lncurses
  5. *        3x :)
  6. */

  7. #include "mssql.h"

  8. int main(void)
  9. {
  10.         mssql a("127.0.0.1", 1433, "sa", "xxx");
  11.         a.selectdb("avatardb");
  12.         a.query("select * from test");

  13.         char **b;
  14.         int cols = a.numcols();
  15.         int i;

  16.         while (b = a.fetch_array())
  17.         {
  18.                 for (i = 0; i < cols; i++)
  19.                 {
  20.                         printf("%s\t", b[i]);
  21.                 }
  22.                 printf("\n");
  23.         }

  24.         a.query("select * from test2");
  25.         cols = a.numcols();

  26.         while (b = a.fetch_array())
  27.         {
  28.                 for (i = 0; i < cols; i++)
  29.                 {
  30.                         printf("%s\t", b[i]);
  31.                 }
  32.                 printf("\n");
  33.         }
  34.         return 0;
  35. }

复制代码

论坛徽章:
0
2 [报告]
发表于 2004-02-27 17:24 |只看该作者

linux下读取sqlserver2000的方法和程序

类功能不多~主要想快点放出来,给需要的朋友看,应该我刚开始弄的时候,觉得类似的代码太少了

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2004-02-27 17:28 |只看该作者

linux下读取sqlserver2000的方法和程序

给你加了原创,希望楼主精益求精,
写出更好的代码。

论坛徽章:
0
4 [报告]
发表于 2004-02-29 09:12 |只看该作者

linux下读取sqlserver2000的方法和程序

谢谢

论坛徽章:
0
5 [报告]
发表于 2004-02-29 11:05 |只看该作者

linux下读取sqlserver2000的方法和程序

我觉得还不如用微软自己提供的jdbc来做呢

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2004-02-29 11:49 |只看该作者

linux下读取sqlserver2000的方法和程序

楼上所言诧异。

软件是一种态度!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP