ODBC drivers >

JDBC drivers >

Bridges, gateways >

Other >

All products

Connect JDBC to any ODBC driver

Connect JDBC to Microsoft Access

Cross-platform or cross-architecture access to any ODBC driver

ODBC access to any JDBC driver

Connect dbExpress applications to any ODBC driver

Connect XML applications to any ODBC driver

Access mutiple ODBC data sources from one SQL statement

Create custom ODBC drivers

Bespoke data access requirements

In the pipeline

Support

Resources

Quick start

Licensing

Knowledge Base

User Guides

Company

About Us

Careers & Partners

Download ODBC Drivers for

Oracle, SQL Server, Salesforce, MongoDB, Access, Derby, InterBase, DB2, & more.

Learn More
/**********************************************************************
* FILENAME : CallSPOutputParameterStreaming
*
* DESCRIPTION :
* ODBC 3.8 introduces a new way to retrieve procedure
* output parameters in parts. An application can now call
* SQLGetData with a small buffer multiple times to retrieve
* a large parameter value. This approach reduces the
* application's memory footprint.
*
* This is is a SQL Server specific example. To run it, you need:
*
* - Version 1.7.12+ of the SQL Server ODBC driver
*
* - Create a SQL Server ODBC driver data source that connects to a database in
* which you have created the following procedure and table:
*
* use mydb
*
* CREATE PROCEDURE [dbo].[SP_OutputParameterStreaming] @Param1 VARBINARY(max) OUTPUT
*
* AS
*
* BEGIN
*
* -- SET NOCOUNT ON added to prevent extra result sets from
*
* -- interfering with SELECT statements.
*
* SET NOCOUNT ON;
*
* SELECT @Param1 = [Document] FROM [mydb].[dbo].[TableImage] where [TableImage].[id] = 1
*
* END
*
* CREATE TABLE TableImage(id integer identity, Document varbinary(max))
* INSERT INTO TableImage(Document) SELECT * FROM OPENROWSET(BULK N'photo.jpg', SINGLE_BLOB) AS I
*
* - Compile the example against the unixODBC Driver Manager included with the
* SQL Server ODBC driver rather than one included with your system:
*
* $ LANG=C cc -I/usr/local/easysoft/unixODBC/include -L/usr/local/easysoft/unixODBC/lib \
* -lodbc CallSPOutputParameterStreaming.c -o CallSPOutputParameterStreaming
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include "util.c"
int main () {
 SQLHENV henv = SQL_NULL_HENV;
 SQLHDBC hdbc = SQL_NULL_HDBC;
 SQLHSTMT hstmt = SQL_NULL_HSTMT;
 SQLRETURN retcode, retcode2;
 SQLLEN lengthofpicture; // The actual length of the picture
 BYTE smallbuffer[100]; // A very small buffer
 CHAR filename[14] = "photo.jpg";
 FILE *pfile;
 // Allocate an environment handle
 retcode=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
 CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)",
 henv, SQL_HANDLE_ENV);
 // Notify ODBC that this is an ODBC 3.8 app
 retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
 (SQLPOINTER) SQL_OV_ODBC3_80, 0);
 CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_HANDLE_ENV)",
 henv, SQL_HANDLE_ENV);
 // Allocate ODBC connection handle and connect
 retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
 CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
 hdbc, SQL_HANDLE_DBC);
 // Connect to data source
 retcode = SQLDriverConnect(hdbc, NULL, "DSN=DATASOURCE;", SQL_NTS,
 NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
 CHECK_ERROR(retcode, "SQLDriverConnect(DATASOURCE)",
 hdbc, SQL_HANDLE_DBC);
 // Allocate a statement handle
 retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
 CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
 // Bind the streamed output parameter
 retcode = SQLBindParameter(
 hstmt,
 1,
 SQL_PARAM_OUTPUT_STREAM, // A streamed output parameter
 SQL_C_BINARY,
 SQL_VARBINARY,
 0, // ColumnSize: The maximum size of varbinary(max)
 0, // DecimalDigits is ignored for binary type
 (SQLPOINTER)1, // ParameterValuePtr: An application-defined
 // token (this will be returned from SQLParamData)
 // In this example, we used the ordinal
 // of the parameter
 0, // BufferLength is ignored for streamed output parameters
 &lengthofpicture); // StrLen_or_IndPtr: The status variable returned
 CHECK_ERROR(retcode, "SQLBindParameter()",
 hstmt, SQL_HANDLE_STMT);
 retcode = SQLPrepare(hstmt, "{call SP_OutputParameterStreaming(?)}", SQL_NTS);
 retcode = SQLExecute(hstmt);
 pfile = fopen(filename, "w+b");
 if ( !pfile ) {
 printf( "failed to open '%s' for w+b\n", filename );
 exit( -1 );
 }
 // Assume that the retrieved picture exists. Use SQLBindCol or SQLGetData to retrieve the result-set.
 // Process the result set and move to the streamed output parameters
 if ( retcode != SQL_PARAM_DATA_AVAILABLE )
 retcode = SQLMoreResults( hstmt );
 // SQLGetData retrieves and displays the picture in parts.
 // The streamed output parameter is available.
 while (retcode == SQL_PARAM_DATA_AVAILABLE) {
 SQLPOINTER token; // Output by SQLParamData
 SQLLEN cbleft; // #bytes remained
 retcode = SQLParamData(hstmt, &token); // Returned token is 2 (according to the binding)
 if ( retcode == SQL_PARAM_DATA_AVAILABLE ) {
 // A do-while loop retrieves the picture in parts
 do {
 retcode2 = SQLGetData(
 hstmt,
 1, // The value of the token is the ordinal
 SQL_C_BINARY,
 smallbuffer, // A small buffer
 sizeof(smallbuffer),
	 &cbleft); // How much data we can get
	 if (cbleft > sizeof(smallbuffer)) // Full buffer
 {
 fwrite(smallbuffer, sizeof(char), sizeof(smallbuffer), pfile);
 }
	 else // Partial buffer on last SQLGetData
 {
 fwrite(smallbuffer, sizeof(char), cbleft, pfile);
 }
 }
 while ( retcode2 == SQL_SUCCESS_WITH_INFO );
 }
 }
 // Close the file
 fflush(pfile);
 fclose(pfile);
exit:
 printf ("\nComplete.\n");
 // Statement
 if (hstmt != SQL_NULL_HSTMT)
 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
 // Connection
 if (hdbc != SQL_NULL_HDBC) {
 SQLDisconnect(hdbc);
 SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
 }
 // Environment
 if (henv != SQL_NULL_HENV)
 SQLFreeHandle(SQL_HANDLE_ENV, henv);
 return 0;
}

See Also

Download ODBC Drivers for

Oracle, SQL Server, Salesforce, MongoDB, Access, Derby, InterBase, DB2, & more.

Learn More
Share:

AltStyle によって変換されたページ (->オリジナル) /