I'd very much appreciate if someone could point me in the right direction.
I can not retrieve string as output parameter from SQL Server Express 2005 stored procedure.

Stored proc DDL is following:

Code:
CREATE PROCEDURE storedProcedure
(@inParam VARCHAR(MAX), 
 @outParam VARCHAR(MAX) OUTPUT) AS 
BEGIN 
 SET @outParam = @inParam; 
END;
ODBC code

Code:
SQLExecDirect(hstmt1, (UCHAR*)"{call storedProcedure(?,?)}", SQL_NTS);
fails with this error:

Code:
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid parameter 
2 (''):  Data type 0x23 is a deprecated large object, or LOB, 
but is marked as output parameter.  
Deprecated types are not supported as output parameters.  
Use current large object types instead.
And here is the full code (derived from a sample at CodePlex):
Code:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>

#define MAXBUFLEN 255

SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;     
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;

void Cleanup() {
   if (hstmt1 != SQL_NULL_HSTMT)
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);

   if (hdbc1 != SQL_NULL_HDBC) {
      SQLDisconnect(hdbc1);
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   }

   if (henv != SQL_NULL_HENV)
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

int main() {
   RETCODE retcode;
   // SQLBindParameter variables.
   SQLCHAR* sParm1 = (SQLCHAR*) "123";
   SQLCHAR sParm2[10] = {0};
   SQLLEN cbParm1 = SQL_NTS;
   SQLLEN cbParm2 = SQL_NTS;

   // Allocate the ODBC environment and save handle.
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(Env) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Notify ODBC that this is an ODBC 3.0 app.
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
      Cleanup();
      return(9);    
   }

   // Allocate ODBC connection handle and connect.
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Connect. 
   SQLCHAR connectOutput[512] = {0};
   SQLSMALLINT result;
   retcode = SQLDriverConnect(hdbc1, 
	   NULL,
	   (UCHAR*) "DRIVER=SQL Server;"
		"UID=test;"
		"PWD=test;"
		"DATABASE=test;"
		"SERVER=localhost;",
		(SQLSMALLINT) SQL_NTS
		, connectOutput
		, sizeof(connectOutput)
		, &result
		, SQL_DRIVER_NOPROMPT);

   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLConnect() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Allocate statement handle.
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLAllocHandle(hstmt1) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Create the stored procedure. 
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"CREATE PROCEDURE storedProcedure(@inParam VARCHAR(MAX), @outParam VARCHAR(MAX) OUTPUT) AS "
		"BEGIN "
		"SET @outParam = @inParam; "
		"END;", SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLExecDirect Failed\n\n");
      Cleanup();
      return(9);
   }

   // Bind the return code to variable sParm1.
   retcode = SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 3, 0, sParm1, 0, &cbParm1);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLBindParameter(sParm1) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Bind the output parameter to variable sParm2.
   retcode = SQLBindParameter(hstmt1, 2, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 10, 0, sParm2, 0, &cbParm2);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLBindParameter(sParm2) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Execute the command. 
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"{call storedProcedure(?,?)}", SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
	   SQLSMALLINT count = 0;
	   SQLSMALLINT messageLength = 0;
	   SQLCHAR sqlState[SQL_SQLSTATE_SIZE + 1];
	   SQLCHAR message[SQL_MAX_MESSAGE_LENGTH];
	   SQLINTEGER   nativeError;

	   while(SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, 
			hstmt1, 
			++count, 
			sqlState, 
			&nativeError, 
			message, 
			sizeof(message), 
			&messageLength)))
	   {
			printf("%s\n\n", message);
	   }
      Cleanup();
      return(9);
   }

   // Show parameters are not filled.
   printf("Before result sets cleared: RetCode = %d, OutParm = %d.\n", sParm1, sParm2);

   // Clear any result sets generated.
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA )
      ;

   // Show parameters are now filled.
   printf("After result sets drained: RetCode = %d, OutParm = %d.\n", sParm1, sParm2);

   // Drop the procedure. 
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"DROP PROCEDURE storedProcedure;", SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLExecDirect Failed\n\n");
      Cleanup();
      return(9);
   }

   // Clean up. 
   SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
   SQLDisconnect(hdbc1);
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
Thank you,

Alex