1 Star 0 Fork 2

jingnx/freetds-samples

forked from 金泉/freetds-samples 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
mssql_common.c 14.29 KB
一键复制 编辑 原始数据 按行查看 历史
jinquan 提交于 2019-11-05 03:56 . add new mssqltool
#include "mssql_common.h"
void DATABASE_LINK_CONSTRUCT(struct __database_link* dblink, char* SQL_SERVER_IP, int SQL_SERVER_PORT,
char* user, char* pass,
char* db )
{
//char s_port[25];
//itoa(SQL_SERVER_PORT, s_port, 10); //here 10 means decimal
strcpy(dblink->SQL_SERVER_IP, SQL_SERVER_IP);
sprintf(dblink->SQL_SERVER_PORT, "%d", SQL_SERVER_PORT);
sprintf(dblink->SQL_SERVER, "%s:%d", SQL_SERVER_IP, SQL_SERVER_PORT);
strcpy(dblink->user, user);
strcpy(dblink->pass, pass);
strcpy(dblink->db, db);
}
int MSSQL_CONN_OPEN(MSSQL_CONN* conn, struct __database_link* dblink)
{
conn->dblink = dblink;
//建立到MSSQL数据库的连接------------------------
dbinit(); //使用dbinit()函数, 进行freetds操作之前的初始化操作
LOGINREC *loginrec = dblogin(); //建立一个到数据库的连接的句柄
DBSETLUSER(loginrec, conn->dblink->user); //向句柄中添加连接数据库的用户
DBSETLPWD(loginrec, conn->dblink->pass); //向数据库连接句柄中添加密码
conn->dbprocess = dbopen(loginrec, conn->dblink->SQL_SERVER); //连接数据库,并返回数据库连接结果的句柄
if(conn->dbprocess == FAIL) //如果连接失败
{
fprintf(stderr, "Connect Fail\n"); //在标准错误中输出信息
//exit(EXIT_FAILURE); //进程异常退出
return 1;
}
else //如果连接成功
{
//printf("Connect success\n");
}
if(dbuse(conn->dbprocess, conn->dblink->db) == FAIL) //使用某个数据库,如果使用失败
{
dbclose(conn->dbprocess); //关闭数据库连接句柄, 并且回收相关资源
//exit(EXIT_FAILURE); //进程异常退出
return 2;
}
return 0;
}
void MSSQL_CONN_RSTSET_CLEAN(RSTSET* rstset)
{
int i,j;
for(i = 0; i < rstset->nROW; i++)
for(j = 0; j < rstset->nCOL; j++)
{
if(rstset->SET[i*rstset->nCOL+j] != NULL)
free(rstset->SET[i*rstset->nCOL+j]);
/*
if(rstset->TYPE[i*rstset->nCOL+j] != NULL)
free(rstset->TYPE[i*rstset->nCOL+j]);
if(rstset->SIZE[i*rstset->nCOL+j] != NULL)
free(rstset->SIZE[i*rstset->nCOL+j]);
*/
}
if(rstset->TYPE != NULL)
free(rstset->TYPE);
if(rstset->SIZE != NULL)
free(rstset->SIZE);
if(rstset->SET != NULL)
free(rstset->SET);
}
void mssql_rstset_print(RSTSET* rstset)
{
int i,j;
for(i = 0; i < rstset->nROW; i++){
for(j = 0; j < rstset->nCOL; j++)
{
if(rstset->SET[i*rstset->nCOL+j] != NULL)
fprintf(stdout, "%*s", 20, rstset->SET[i*rstset->nCOL+j]);
}
printf("\n");
}
}
int mssql_select(MSSQL_CONN* conn)
{
RETCODE erc;
while((erc = dbresults(conn->dbprocess)) != NO_MORE_RESULTS) {
int ncols; int row_code;
struct col { //保存列的所有信息
char *name; //列名字
char *buffer; //存放列数据指针
int type, size, status;
} *columns, *pcol;
if(erc == FAIL) {
fprintf(stderr, "TDS/> dbresults failed.\n");
return -1; //exit(1);
}
ncols = dbnumcols(conn->dbprocess);//返回执行结果的列数目
if((columns = calloc(ncols, sizeof(struct col))) == NULL) {
perror(NULL);
fprintf(stderr, "SYS/> Column Sets space allocated failed.\n");
return -2; //exit(1);
}
conn->result.SET = (char**)malloc(sizeof(char*) * ncols);
int RSTiROW = 0;
conn->result.nCOL = ncols;
/* read metadata and bind. */
for(pcol = columns; pcol - columns < ncols; pcol++) {
int c = pcol - columns + 1;
pcol->name = dbcolname(conn->dbprocess, c); //返回指定列的列名
pcol->type = dbcoltype(conn->dbprocess, c); //printf("column type: %d\n", pcol->type);
pcol->size = dbcollen(conn->dbprocess, c);
//printf("%*s(%d)", 20, pcol->name, pcol->size); //显示列名称及字段长度
if((pcol->buffer = calloc(1, pcol->size)) == NULL) { //创建列字段数据缓冲区
perror(NULL);
fprintf(stderr, "SYS/> Shared Column field buffer allocated failed.\n");
return -3; //exit(1);
}
/* Parameters
* dbproc contains all information needed by db-lib to manage communications with the server.
* column Nth column, starting at 1.
* vartype datatype of the host variable that will receive the data
* varlen size of host variable pointed to varaddr
* varaddr address of host variable
*/
if((erc = dbbind(conn->dbprocess, c, NTBSTRINGBIND, pcol->size, (BYTE*)pcol->buffer)) == FAIL) {
fprintf(stderr, "TDS/> Shared Column field buffer dbbind(%d) failed\n", c);
return -4; //exit(1);
}
/* Return values
* 0 column bound successfully
* -1 column is NULL.
* >0 true length of data, had column not been truncated due to insufficient space in the columns bound host variable .
*/
if(( erc = dbnullbind(conn->dbprocess, c, &pcol->status)) == FAIL) {
fprintf(stderr, "TDS/> Shared Column field status-word dbnullbind(%d) failed\n", c);
return -5; //exit(1);
}
//列名称保存到结果集
conn->result.SET[RSTiROW*ncols + c -1] = (char*)malloc(sizeof(char)*pcol->size);
sprintf(conn->result.SET[RSTiROW*ncols + c -1], "%s(%d)", pcol->name, pcol->size);
//printf("%s\n", conn->result.SET[RSTiROW*ncols + c -1]);
}
//第一行(列名称)结束,行索引加1
RSTiROW = RSTiROW + 1;
/* 获取每一行所有数据字段指针占用的空间
* 注意:使用正确的数据类型做单位长度
*/
int RST_ROW_SIZE = ncols * sizeof(char*);
//printf("\n");
/* 打印/读取 每行数据 */
int c; char **NEW_RSTSET; int NEW_RSTSET_ROW;
while((row_code = dbnextrow(conn->dbprocess)) != NO_MORE_ROWS) {//读取行数据
switch(row_code) {
case REG_ROW:
//printf("Current RSTiROW: %d\tRSTSET size: %d\n", RSTiROW, (RST_ROW_SIZE)*(RSTiROW) );
//空间扩展后的所有数据行数量
NEW_RSTSET_ROW = RSTiROW+1;
//扩展新数据行存储空间
NEW_RSTSET = (char**)realloc(conn->result.SET, (RST_ROW_SIZE)*NEW_RSTSET_ROW );
if(NEW_RSTSET != NULL){
conn->result.SET = NEW_RSTSET;
}else{
fprintf(stderr, "SYS/> Result Set memory space reallocated failed.\n");
return -7;
}
//逐列写入到结果集缓冲区
for(pcol=columns, c = 0; pcol - columns < ncols; pcol++, c++) {
char *buffer = pcol->status == -1 ? "null" : pcol->buffer;
//printf("%*s ", 20, buffer);
conn->result.SET[RSTiROW*ncols + c] = (char*)malloc(sizeof(char)*pcol->size);
sprintf(conn->result.SET[RSTiROW*ncols + c], "%s", buffer);
}
//行统计索引加1
RSTiROW = RSTiROW + 1;
printf("\n");
break;
case BUF_FULL:
break;
case FAIL:
fprintf(stderr, "dbresults failed\n");
return -6; //exit(1);
break;
default:
printf("data for computeid %d ignored\n", row_code);
}
}
conn->result.nROW = RSTiROW;
/* free metadata and data buffers */
for(pcol=columns; pcol - columns < ncols; pcol++) {
free(pcol->buffer);
}
free(columns);
if(DBCOUNT(conn->dbprocess) > -1) {/* 得到SQL语句影响的行数 */
//fprintf(stderr, "%d rows affected\n", DBCOUNT(conn.dbprocess));
return DBCOUNT(conn->dbprocess);
}
}
}
int mssql_query_column_name(MSSQL_CONN *conn, char* table)
{
RETCODE erc;
char mssqlbuf[1024]; memset(mssqlbuf, 0x00, sizeof(mssqlbuf));
sprintf(mssqlbuf, "SELECT * from %s;", table);
dbcmd(conn->dbprocess, mssqlbuf); //sql text 保存到数据库连接句柄的缓存中
if(dbsqlexec(conn->dbprocess) == FAIL){
return -1;
}else{
while((erc = dbresults(conn->dbprocess)) != NO_MORE_RESULTS) {
int ncols; int row_code;
struct col { //保存列的所有信息
char *name; //列名字
char *buffer; //存放列数据指针
int type, size, status;
} *columns, *pcol;
if(erc == FAIL) {
return 0; // row > 1, function exit normally.
}
ncols = dbnumcols(conn->dbprocess);//返回执行结果的列数目
if((columns = calloc(ncols, sizeof(struct col))) == NULL) {
perror(NULL);
fprintf(stderr, "SYS/> Column Sets space allocated failed.\n");
return -2; //exit(1);
}
conn->result.SET = (char**)malloc(sizeof(char*) * ncols);
conn->result.TYPE = (int*)malloc(sizeof(int) * ncols);
conn->result.SIZE = (int*)malloc(sizeof(int) * ncols);
int RSTiROW = 0;
conn->result.nCOL = ncols; conn->result.nROW = 1; // column名称 仅此一行
/* read metadata and bind. */
for(pcol = columns; pcol - columns < ncols; pcol++) {
int c = pcol - columns + 1;
pcol->name = dbcolname(conn->dbprocess, c); //返回指定列的列名
pcol->type = dbcoltype(conn->dbprocess, c); //printf("column type: %d\n", pcol->type);
pcol->size = dbcollen(conn->dbprocess, c);
//printf("%*s(%d)", 20, pcol->name, pcol->size); //显示列名称及字段长度
if((pcol->buffer = calloc(1, pcol->size)) == NULL) { //创建列字段数据缓冲区
perror(NULL);
fprintf(stderr, "SYS/> Shared Column field buffer allocated failed.\n");
return -3; //exit(1);
}
/* Parameters
* dbproc contains all information needed by db-lib to manage communications with the server.
* column Nth column, starting at 1.
* vartype datatype of the host variable that will receive the data
* varlen size of host variable pointed to varaddr
* varaddr address of host variable
*/
if((erc = dbbind(conn->dbprocess, c, NTBSTRINGBIND, pcol->size, (BYTE*)pcol->buffer)) == FAIL) {
fprintf(stderr, "TDS/> Shared Column field buffer dbbind(%d) failed\n", c);
return -4; //exit(1);
}
/* Return values
* 0 column bound successfully
* -1 column is NULL.
* >0 true length of data, had column not been truncated due to insufficient space in the columns bound host variable .
*/
if(( erc = dbnullbind(conn->dbprocess, c, &pcol->status)) == FAIL) {
fprintf(stderr, "TDS/> Shared Column field status-word dbnullbind(%d) failed\n", c);
return -5; //exit(1);
}
//列名称保存到结果集
conn->result.SET[RSTiROW*ncols + c -1] = (char*)malloc(sizeof(char)*pcol->size);
//sprintf(conn->result.SET[RSTiROW*ncols + c -1], "%s(%d)", pcol->name, pcol->size);
sprintf(conn->result.SET[RSTiROW*ncols + c -1], "%s", pcol->name);
conn->result.TYPE[RSTiROW*ncols + c -1] = pcol->type;
conn->result.SIZE[RSTiROW*ncols + c -1] = pcol->size;
//printf("%s\t", conn->result.SET[RSTiROW*ncols + c -1]);
}printf("\n");
/* free metadata and data buffers */
for(pcol=columns; pcol - columns < ncols; pcol++) {
free(pcol->buffer);
}
free(columns);
}
}
}
#if 0
void sqltext_insert_construct(char* sqltext, char* tablename, struct __result_set* columninfo, ... )
{
int i; char temp[1024];
sprintf(sqltext, "INSERT INTO %s (", tabname);
for(i = 0; i < columninfo->nCOL; i++){
strcat(sqltext, columninfo->SET[i]);
if(i != columninfo->nCOL-1)
strcat(sqltext, ", ")
}strcat(sqltext, ") VALUES (");
for(i = 0; i < columninfo->nCOL; i++){
if( (columninfo->SIZE[i] == MSSQL2014_AVAIL_COL_SIZE_bit && columninfo->TYPE[i] == MSSQL2014_AVAIL_COL_TYPE_bit) ||
(columninfo->SIZE[i] == MSSQL2014_AVAIL_COL_SIZE_smallint && columninfo->TYPE[i] == MSSQL2014_AVAIL_COL_TYPE_smallint) ||
(columninfo->SIZE[i] == MSSQL2014_AVAIL_COL_SIZE_tinyint && columninfo->TYPE[i] == MSSQL2014_AVAIL_COL_TYPE_tinyint) ){
sprintf(temp, MSSQL2014_AVAIL_COL_C_TYPE_tinyint, )
strcat(sqltext, temp);
}
else if( (columninfo->SIZE[i] == MSSQL2014_AVAIL_COL_SIZE_int && columninfo->TYPE[i] == MSSQL2014_AVAIL_COL_TYPE_int) ){
sprintf(temp, MSSQL2014_AVAIL_COL_C_TYPE_int, )
strcat(sqltext, temp);
}
}
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/jingnx/freetds-samples.git
git@gitee.com:jingnx/freetds-samples.git
jingnx
freetds-samples
freetds-samples
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385