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

📄 rpc.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/*  * Purpose: Test remote procedure calls * Functions:   */#include "common.h"#include <assert.h>static char software_version[] = "$Id: rpc.c,v 1.8 2007/11/26 06:25:11 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };static const char procedure_sql[] = 		"CREATE PROCEDURE %s \n"			"  @null_input varchar(30) OUTPUT \n"			", @first_type varchar(30) OUTPUT \n"			", @nullout int OUTPUT\n"			", @nrows int OUTPUT \n"			", @c varchar(20)\n"		"AS \n"		"BEGIN \n"			"select @null_input = max(convert(varchar(30), name)) from systypes \n"			"select @first_type = min(convert(varchar(30), name)) from systypes \n"			/* #1 empty result set: */			"select name from sysobjects where 0=1\n"			/* #2 3 rows: */			"select distinct convert(varchar(30), name) as 'type'  from systypes \n"				"where name in ('int', 'char', 'text') \n"			"select @nrows = @@rowcount \n"			/* #3 many rows: */			"select distinct convert(varchar(30), name) as name  from sysobjects where type = 'S' \n"			"return 42 \n"		"END \n";static intinit_proc(const char *name){	static char cmd[4096];	if (name[0] != '#') {		fprintf(stdout, "Dropping procedure %s\n", name);		sprintf(cmd, "if exists (select 1 from sysobjects where name = '%s' and type = 'P') "				"DROP PROCEDURE %s", name, name);		if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {			CheckReturn();			exit(1);		}	}	fprintf(stdout, "Creating procedure %s\n", name);	sprintf(cmd, procedure_sql, name);	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {		if (name[0] == '#')			fprintf(stdout, "Failed to create procedure %s. Wrong permission or not MSSQL.\n", name);		else			fprintf(stdout, "Failed to create procedure %s. Wrong permission.\n", name);		CheckReturn();		exit(1);	}	return 0;}static voidTest(const char *name){	int iresults=0, data_errors=0;	unsigned char sqlstate[6], msg[256];	SQLRETURN erc;	int ipar=0;	HSTMT stmt;	char call_cmd[128];	struct Argument {                 SQLSMALLINT       InputOutputType;  /* fParamType */                SQLSMALLINT       ValueType;        /* fCType */                SQLSMALLINT       ParameterType;    /* fSqlType */                SQLUINTEGER       ColumnSize;       /* cbColDef */                SQLSMALLINT       DecimalDigits;    /* ibScale */                SQLPOINTER        ParameterValuePtr;/* rgbValue */                SQLINTEGER        BufferLength;     /* cbValueMax */                SQLLEN            ind;              /* pcbValue */	};	struct Argument args[] = {		/* InputOutputType 	  ValueType   ParamType    ColumnSize 								    | DecimalDigits 								    |  | ParameterValuePtr 								    |  |  |  BufferLength 								    |  |  |   |	 ind */		{ SQL_PARAM_OUTPUT,       SQL_C_LONG, SQL_INTEGER,  0, 0, 0,  4, 3 }, /* return status */		{ SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 30, 0, 0, 30, SQL_NULL_DATA }, 										      /* @null_input varchar(30) OUTPUT */		{ SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 30, 0, 0, 30, 3 }, /* @first_type varchar(30) OUTPUT */		{ SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG, SQL_INTEGER,  0, 0, 0,  4, 4 }, /* @nullout int OUTPUT\ */		{ SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG, SQL_INTEGER,  0, 0, 0,  4, 4 }, /* @nrows int OUTPUT */		{ SQL_PARAM_INPUT,        SQL_C_CHAR, SQL_VARCHAR, 20, 0, 0, 20, 3 }  /* @c varchar(20) */	};	printf("executing SQLAllocStmt\n");	if (SQLAllocStmt(Connection, &stmt) != SQL_SUCCESS)		ODBC_REPORT_ERROR("Unable to allocate statement");	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {		printf("executing SQLBindParameter for parameter %d\n", 1+ipar);		if( args[ipar].BufferLength > 0 ) {			args[ipar].ParameterValuePtr = (SQLPOINTER) malloc(args[ipar].BufferLength);			assert(args[ipar].ParameterValuePtr != NULL);			memset(args[ipar].ParameterValuePtr, 0, args[ipar].BufferLength);			memset(args[ipar].ParameterValuePtr, 'a', args[ipar].BufferLength - 1);		}		erc = SQLBindParameter	( stmt, 1+ipar					, args[ipar].InputOutputType					, args[ipar].ValueType					, args[ipar].ParameterType					, args[ipar].ColumnSize					, args[ipar].DecimalDigits					, args[ipar].ParameterValuePtr					, args[ipar].BufferLength					, &args[ipar].ind					);		if (erc != SQL_SUCCESS) {			fprintf(stderr, "Failed: SQLBindParameter\n");			exit(1);		}	}			sprintf(call_cmd, "{?=call %s(?,?,?,?,?)}", name );	printf("executing SQLPrepare: %s\n", call_cmd);	if (SQLPrepare(stmt, (SQLCHAR *) call_cmd, SQL_NTS) != SQL_SUCCESS)		ODBC_REPORT_ERROR("Unable to prepare statement");	printf("executing SQLExecute\n");	if (! SQL_SUCCEEDED(SQLExecute(stmt))) {		erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);		ODBC_REPORT_ERROR("Unable to execute SQLExecute\n");			}	do {		static const char dashes[] = "------------------------------", 				  *dashes5   = &dashes[25], 				  *dashes15  = &dashes[15];		int nrows;		SQLSMALLINT  icol, ncols;                SQLCHAR      name[256] = "";                SQLSMALLINT  namelen;                SQLSMALLINT  type;                SQLSMALLINT  scale;                SQLSMALLINT  nullable;				  		printf("executing SQLNumResultCols for result set %d\n", ++iresults);		if((erc = SQLNumResultCols(stmt,  &ncols)) != SQL_SUCCESS) {			ODBC_REPORT_ERROR("Unable to execute SQLNumResultCols\n");		}		printf("executing SQLDescribeCol for %d column%c\n", ncols, (ncols == 1? ' ' : 's'));		printf("%-5s %-15s %5s %5s %5s %8s\n", "col", "name", "type", "size", "scale", "nullable"); 		printf("%-5s %-15s %5s %5s %5s %8s\n", dashes5, dashes15, dashes5, dashes5, dashes5, &dashes[30-8]); 				for (icol=ncols; icol > 0; icol--) {                	SQLULEN size;			erc = SQLDescribeCol( stmt, icol, name, sizeof(name),						    &namelen, &type, &size, &scale, &nullable);			if (erc != SQL_SUCCESS) {				erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);				fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);				ODBC_REPORT_ERROR("Unable to execute SQLDescribeCol\n");			} 						printf("%-5d %-15s %5d %5ld %5d %8c\n", icol, name, type, (long int)size, scale, (nullable? 'Y' : 'N')); 		}		printf("executing SQLFetch...\n");		printf("\t%-30s\n\t%s\n", name, dashes);		for (nrows=0; (erc = SQLFetch(stmt)) == SQL_SUCCESS; nrows++) {			const SQLINTEGER icol = 1;			char buf[60];			SQLLEN len;			erc = SQLGetData( stmt					, icol					, SQL_C_CHAR	/* fCType */					, buf		/* rgbValue */					, sizeof(buf)	/* cbValueMax */	                		, &len		/* pcbValue */						);			printf("\t%-30s\t(%2d bytes)\n", buf, (int) len);		}		if (erc != SQL_NO_DATA_FOUND) {			erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);			fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);			ODBC_REPORT_ERROR("Unable to execute SQLFetch\n");		} else {			printf("done.\n");		}		switch (iresults) {		case 1:			printf("0 rows expected, %d found\n", nrows);			data_errors += (nrows == 0)? 0 : 1;			break;;		case 2:			printf("3 rows expected, %d found\n", nrows);			data_errors += (nrows == 3)? 0 : 1;			break;;		case 3:			printf("at least 15 rows expected, %d found\n", nrows);			data_errors += (nrows > 15)? 0 : 1;			break;;		}		printf("executing SQLMoreResults...\n");	} while ((erc = SQLMoreResults(stmt)) == SQL_SUCCESS);	if (erc != SQL_NO_DATA_FOUND) {		ODBC_REPORT_ERROR("Unable to execute SQLMoreResults\n");	} else {		printf("done.\n");	}	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {		if (args[ipar].InputOutputType == SQL_PARAM_INPUT)			continue;		printf("bound data for parameter %d is %ld bytes: ", 1+ipar, (long int)args[ipar].ind);		switch( args[ipar].ValueType ) {		case SQL_C_LONG:			printf("%d.\n", (int)(*(SQLINTEGER *)args[ipar].ParameterValuePtr));			break;		case SQL_C_CHAR:			printf("'%s'.\n", (char*)args[ipar].ParameterValuePtr);			break;		default:			printf("type unsupported in this test\n");			assert(0);			break;		}	}	printf("executing SQLFreeStmt\n");	if (SQLFreeStmt(stmt, SQL_DROP) != SQL_SUCCESS)		ODBC_REPORT_ERROR("Unable to free statement");	for (ipar = 0; ipar < sizeof(args)/sizeof(args[0]); ++ipar)		if (args[ipar].BufferLength > 0)			free(args[ipar].ParameterValuePtr);	if (data_errors) {		fprintf(stderr, "%d errors found in expected row count\n", data_errors);		exit(1);	}}intmain(int argc, char *argv[]){	const char proc_name[] = "freetds_odbc_rpc_test";	char drop_proc[256] = "DROP PROCEDURE ";		strcat(drop_proc, proc_name);		printf("connecting\n");	Connect();		init_proc(proc_name);	printf("running test\n");	Test(proc_name);		printf("dropping procedure\n");	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) drop_proc, SQL_NTS))) {		printf("Unable to drop procedure\n");		CheckReturn();		exit(1);	}	Disconnect();	printf("Done.\n");	return 0;}

⌨️ 快捷键说明

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