リターン コードと出力パラメーターの処理 (ODBC)

SQL Server のストアド プロシージャでは、整数のリターン コードと出力パラメーターを使用できます。 これらのリターン コードと出力パラメーターはサーバーからの最後のパケットで送信されるため、SQLMoreResults によって SQL_NO_DATA が返されるまでアプリケーションでは使用できません。ストアド プロシージャからエラーが返された場合は、SQL_NO_DATA が返されるまで、SQLMoreResults を呼び出して次の結果に進みます。

セキュリティに関する注意セキュリティに関する注意

可能な場合は、Windows 認証を使用します。 Windows 認証が使用できない場合は、実行時に資格情報を入力するようユーザーに求めます。 資格情報をファイルに保存するのは避けてください。 資格情報を保存する必要がある場合は、Win32 Crypto API を使用して暗号化してください。

リターン コードと出力パラメーターを処理するには

  1. ODBC CALL エスケープ シーケンスを使用する SQL ステートメントを作成します。 このステートメントでは、各入力、入出力、出力パラメーター、およびプロシージャの戻り値 (存在する場合) に対してパラメーター マーカーを使用する必要があります。

  2. 入力パラメーター、入出力パラメーター、出力パラメーター、およびプロシージャの戻り値 (存在する場合) それぞれに対して SQLBindParameter を呼び出します。

  3. SQLExecDirect を使用してステートメントを実行します。

  4. 最後の結果セットの処理中に SQLFetch または SQLFetchScroll によって SQL_NO_DATA が返されるまで、あるいは SQLMoreResults によって SQL_NO_DATA が返されるまで、結果セットを処理します。 この時点で、リターン コードと出力パラメーターにバインドされた変数に、返されたデータ値が格納されています。

使用例

このサンプルでは、リターン コードおよび出力パラメーターの処理を示します。 このサンプルは IA64 ではサポートされていません。 このサンプルは、ODBC 3.0 以降のバージョン用に開発されました。

AdventureWorks と呼ばれる ODBC データ ソース (既定のデータベースは AdventureWorks サンプル データベース) が必要です (AdventureWorks サンプル データベースは、Microsoft SQL Server のサンプルとコミュニティのプロジェクトのホーム ページからダウンロードできます)。このデータ ソースには、オペレーティング システムに用意されている ODBC ドライバーが使用されている必要があります (ドライバー名は "SQL Server")。 このサンプルを 64 ビット オペレーティング システムで 32 ビット アプリケーションとしてビルドし、実行する場合、%windir%\SysWOW64\odbcad32.exe の ODBC アドミニストレーターを使用して ODBC データ ソースを作成する必要があります。

このサンプルでは、コンピューターの既定の SQL Server インスタンスに接続します。 名前付きインスタンスに接続するには、ODBC データ ソースの定義を変更し、server\namedinstance 形式でそのインスタンスを指定します。 SQL Server Express は、既定で名前付きインスタンスとしてインストールされます。

1 つ目の (Transact-SQL) コード リストは、このサンプルで使用するストアド プロシージャを作成します。

odbc32.lib を使用して 2 つ目の (C++) コード リストをコンパイルします。 次に、プログラムを実行します。

3 つ目の (Transact-SQL) コード リストは、このサンプルで使用したストアド プロシージャを削除します。

use AdventureWorks
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'TestParm')
   DROP PROCEDURE TestParm
GO

CREATE PROCEDURE TestParm 
@OutParm int OUTPUT 
AS
SELECT Name FROM Purchasing.Vendor
SELECT @OutParm = 88
RETURN 99
go

// compile with: odbc32.lib
#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.
   SWORD sParm1 = 0, sParm2 = 1;
   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);
   }

   // This sample use Integrated Security. Create the SQL Server DSN by using the Windows NT authentication. 
   retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"",SQL_NTS, (UCHAR*)"", SQL_NTS);

   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);
   }

   // Bind the return code to variable sParm1.
   retcode = SQLBindParameter(hstmt1, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 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_SSHORT, SQL_INTEGER, 0, 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 TestParm(?)}", SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLExecDirect Failed\n\n");
      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);

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

use AdventureWorks
DROP PROCEDURE TestParm
GO

関連項目

その他の技術情報

ストアド プロシージャを実行する方法に関するトピック (ODBC)