⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prepare_query.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns * Copyright (C) 2005  Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdarg.h>#include <stdio.h>#include <assert.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#include <ctype.h>#include "tdsodbc.h"#include "tdsconvert.h"#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: prepare_query.c,v 1.64 2007/04/18 14:29:24 freddy77 Exp $");#define TDS_ISSPACE(c) isspace((unsigned char) (c))static intprepared_rpc(struct _hstmt *stmt, int compute_row){	int nparam = stmt->params ? stmt->params->num_cols : 0;	const char *p = stmt->prepared_pos - 1;	for (;;) {		TDSPARAMINFO *temp_params;		TDSCOLUMN *curcol;		TDS_SERVER_TYPE type;		const char *start;		while (TDS_ISSPACE(*++p));		if (!*p)			return SQL_SUCCESS;		/* we have certainly a parameter */		if (!(temp_params = tds_alloc_param_result(stmt->params))) {			odbc_errs_add(&stmt->errs, "HY001", NULL);			return SQL_ERROR;		}		stmt->params = temp_params;		curcol = temp_params->columns[nparam];		switch (*p) {		case ',':			if (IS_TDS7_PLUS(stmt->dbc->tds_socket)) {				tds_set_param_type(stmt->dbc->tds_socket, curcol, SYBVOID);				curcol->column_size = curcol->column_cur_size = 0;			} else {				/* TODO is there a better type ? */				tds_set_param_type(stmt->dbc->tds_socket, curcol, SYBINTN);				curcol->column_size = curcol->on_server.column_size = 4;				curcol->column_cur_size = -1;			}			if (compute_row)				if (!tds_alloc_param_data(curcol)) {					tds_free_param_result(temp_params);					return SQL_ERROR;				}			--p;			break;		default:			/* add next parameter to list */			start = p;			if (!(p = parse_const_param(p, &type))) {				tds_free_param_result(temp_params);				return SQL_ERROR;			}			tds_set_param_type(stmt->dbc->tds_socket, curcol, type);			switch (type) {			case SYBVARCHAR:				curcol->column_size = p - start;				break;			case SYBVARBINARY:				curcol->column_size = (p - start) / 2 -1;				break;			default:				assert(0);			case SYBINT4:			case SYBFLT8:				curcol->column_cur_size = curcol->column_size;				break;			}			/* TODO support other type other than VARCHAR, do not strip escape in prepare_call */			if (compute_row) {				char *dest;				int len;				CONV_RESULT cr;				if (!tds_alloc_param_data(curcol)) {					tds_free_param_result(temp_params);					return SQL_ERROR;				}				dest = (char *) curcol->column_data;				switch (type) {				case SYBVARCHAR:					if (*start != '\'') {						memcpy(dest, start, p - start);						curcol->column_cur_size = p - start;					} else {						++start;						for (;;) {							if (*start == '\'')								++start;							if (start >= p)								break;							*dest++ = *start++;						}						curcol->column_cur_size =							dest - (char *) curcol->column_data;					}					break;				case SYBVARBINARY:					cr.cb.len = curcol->column_size;					cr.cb.ib = dest;					len = tds_convert(NULL, SYBVARCHAR, start, p - start, TDS_CONVERT_BINARY, &cr);					if (len >= 0 && len <= curcol->column_size)						curcol->column_cur_size = len;					break;				case SYBINT4:					*((TDS_INT *) dest) = strtol(start, NULL, 10);					break;				case SYBFLT8:					*((TDS_FLOAT *) dest) = strtod(start, NULL);					break;				default:					break;				}			}			--p;			break;		case '?':			/* find binded parameter */			if (stmt->param_num > stmt->apd->header.sql_desc_count			    || stmt->param_num > stmt->ipd->header.sql_desc_count) {				tds_free_param_result(temp_params);				/* TODO set error */				return SQL_ERROR;			}			switch (sql2tds				(stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1],				 curcol, compute_row, stmt->apd, stmt->curr_param_row)) {			case SQL_ERROR:				return SQL_ERROR;			case SQL_NEED_DATA:				return SQL_NEED_DATA;			}			++stmt->param_num;			break;		}		++nparam;		while (TDS_ISSPACE(*++p));		if (!*p || *p != ',')			return SQL_SUCCESS;		stmt->prepared_pos = (char *) p + 1;	}}intparse_prepared_query(struct _hstmt *stmt, int compute_row){	/* try setting this parameter */	TDSPARAMINFO *temp_params;	int nparam = stmt->params ? stmt->params->num_cols : 0;	if (stmt->prepared_pos)		return prepared_rpc(stmt, compute_row);	for (; stmt->param_num <= stmt->param_count; ++nparam, ++stmt->param_num) {		/* find binded parameter */		if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) {			/* TODO set error */			return SQL_ERROR;		}		/* add a column to parameters */		if (!(temp_params = tds_alloc_param_result(stmt->params))) {			odbc_errs_add(&stmt->errs, "HY001", NULL);			return SQL_ERROR;		}		stmt->params = temp_params;		switch (sql2tds			(stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1],			 stmt->params->columns[nparam], compute_row, stmt->apd, stmt->curr_param_row)) {		case SQL_ERROR:			return SQL_ERROR;		case SQL_NEED_DATA:			return SQL_NEED_DATA;		}	}	return SQL_SUCCESS;}intstart_parse_prepared_query(struct _hstmt *stmt, int compute_row){	/* TODO should be NULL already ?? */	tds_free_param_results(stmt->params);	stmt->params = NULL;	stmt->param_num = 0;	stmt->param_num = stmt->prepared_query_is_func ? 2 : 1;	return parse_prepared_query(stmt, compute_row);}intcontinue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN StrLen_or_Ind){	struct _drecord *drec_apd, *drec_ipd;	SQLLEN len;	int need_bytes;	TDSCOLUMN *curcol;	TDSBLOB *blob;	if (!stmt->params)		return SQL_ERROR;	if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count)		return SQL_ERROR;	drec_apd = &stmt->apd->records[stmt->param_num - 1];	drec_ipd = &stmt->ipd->records[stmt->param_num - 1];	curcol = stmt->params->columns[stmt->param_num - (stmt->prepared_query_is_func ? 2 : 1)];	blob = NULL;	if (is_blob_type(curcol->column_type))		blob = (TDSBLOB *) curcol->column_data;	assert(curcol->column_cur_size <= curcol->column_size);	need_bytes = curcol->column_size - curcol->column_cur_size;	if (SQL_NTS == StrLen_or_Ind)		len = strlen((char *) DataPtr);	else if (SQL_DEFAULT_PARAM == StrLen_or_Ind || StrLen_or_Ind < 0)		/* FIXME: I don't know what to do */		return SQL_ERROR;	else		len = StrLen_or_Ind;	if (!blob && len > need_bytes)		len = need_bytes;	/* copy to destination */	if (blob) {		TDS_CHAR *p;		if (blob->textvalue)			p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);		else {			assert(curcol->column_cur_size == 0);			p = (TDS_CHAR *) malloc(len);		}		if (!p)			return SQL_ERROR;		blob->textvalue = p;		memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);	} else {		memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len);	}	curcol->column_cur_size += len;	if (blob && curcol->column_cur_size > curcol->column_size)		curcol->column_size = curcol->column_cur_size;	return SQL_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -