SQLGetCursorName() - Get cursor name

SQLGetCursorName() returns the name of the cursor that is associated with a statement handle. If you explicitly set a cursor name with SQLSetCursorName(), the name that you specified in a call to SQLSetCursorName() is returned. If you do not explicitly set a name, SQLGetCursorName() returns the implicitly generated name for that cursor.

ODBC specifications for SQLGetCursorName()

Table 1. SQLGetCursorName() specifications
ODBC specification level In X/Open CLI CAE specification? In ISO CLI specification?
1.0 Yes Yes

Syntax

SQLRETURN   SQLGetCursorName (SQLHSTMT          hstmt,
                              SQLCHAR     FAR   *szCursor,
                              SQLSMALLINT       cbCursorMax,
                              SQLSMALLINT FAR   *pcbCursor);

Function arguments

The following table lists the data type, use, and description for each argument in this function.

Table 2. SQLGetCursorName() arguments
Data type Argument Use Description
SQLHSTMT hstmt input Specifies the statement handle on which the cursor you want to identify is open.
SQLCHAR * szCursor output Specifies the buffer in which the cursor name is returned.
SQLSMALLINT cbCursorMax input Specifies the size of the buffer to which the szCursor argument points.
SQLSMALLINT * pcbCursor output Points to the buffer that receives the number of bytes that the cursor name requires.

Usage

SQLGetCursorName() returns the name that you set explicitly on a cursor with SQLSetCursorName(). If you do not set a name for a cursor, you can use this function to retrieve the name that Db2 ODBC internally generates.

SQLGetCursorName() returns the same cursor name (which can be explicit or implicit) on a statement until you drop that statement, or until you set another explicit name for that cursor. Cursor names are always 18 characters or less, and are always unique within a connection.

Cursor names that Db2 ODBC generates internally always begin with SQLCUR or SQL_CUR. For query result sets, Db2 ODBC also reserves SQLCURQRS as a cursor name prefix. (See Restrictions for more details about this naming convention.)

Return codes

After you call SQLGetCursorName(), it returns one of the following values:
  • SQL_SUCCESS
  • SQL_SUCCESS_WITH_INFO
  • SQL_ERROR
  • SQL_INVALID_HANDLE

Diagnostics

The following table lists each SQLSTATE that this function generates, with a description and explanation for each value.

Table 3. SQLGetCursorName() SQLSTATEs
SQLSTATE Description Explanation
01004 Data truncated. The cursor name that is returned in the buffer that the szCursor argument specifies is longer than the value in the cbCursorMax argument. Data in this buffer is truncated to the one byte less than the value that the cbCursorMax argument specifies. The pcbCursor argument contains the length, in bytes, that the full cursor name requires. (SQLGetCursorName() returns SQL_SUCCESS_WITH_INFO for this SQLSTATE.)
08S01 Communication link failure. The communication link between the application and data source fails before the function completes.
58004 Unexpected system failure. Unrecoverable system error.
HY001 Memory allocation failure. Db2 ODBC is not able to allocate the required memory to support the execution or the completion of the function.
HY010 Function sequence error. The function is called during a data-at-execute operation. (That is, the function is called during a procedure that uses the SQLParamData() or SQLPutData() functions.)
HY013 Unexpected memory handling error. Db2 ODBC is not able to access the memory that is required to support execution or completion of the function.
HY015 No cursor name available. No cursor is open on the statement handle that the hstmt argument specifies, and no cursor name is set with SQLSetCursorName().
HY090 Invalid string or buffer length. The value specified for the cbCursorMaxargument is less than 0.
HY092 Option type out of range. The statement handle specified for the hstmt argument is not valid.

Restrictions

ODBC generates cursor names that begin with SQL_CUR. X/Open CLI generates cursor names that begin with either SQLCUR or SQL_CUR.

Db2 ODBC is inconsistent with the ODBC specification for naming cursors. Db2 ODBC generates cursor names that begin with SQLCUR or SQL_CUR, which is consistent with the X/Open CLI standard.

Example

The following example shows an application that uses SQLGetCursorName() to extract the name of a cursor needed that the proceeding update statement requires.
Figure 1. An application that extracts a cursor name
 /******************************************************************/
 /*  Perform a positioned update on a column of a cursor.          */
 /******************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
#include "sqlcli1.h"
int main( )
{
   SQLHENV         hEnv    = SQL_NULL_HENV;
   SQLHDBC         hDbc    = SQL_NULL_HDBC;
   SQLHSTMT        hStmt   = SQL_NULL_HSTMT, hStmt2 = SQL_NULL_HSTMT;
   SQLRETURN       rc      = SQL_SUCCESS, rc2 = SQL_SUCCESS;
   SQLINTEGER      RETCODE = 0;
   char            *pDSN = "STLEC1";
   SWORD           cbCursor;
   SDWORD          cbValue1;
   SDWORD          cbValue2;
   char            employee [30];
   int             salary = 0;
   char            cursor_name [20];
   char            update [200];
   char            *stmt = "SELECT NAME, SALARY FROM EMPLOYEE WHERE
                            SALARY > 100000 FOR UPDATE OF SALARY";
   (void) printf ("**** Entering CLIP04.\n\n");
  /*****************************************************************/
  /* Allocate environment handle                                   */
  /*****************************************************************/
   RETCODE = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
   if (RETCODE != SQL_SUCCESS)
     goto dberror;
  /*****************************************************************/
  /* Allocate connection handle to DSN                             */
  /*****************************************************************/
   RETCODE = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &hDbc);
   if( RETCODE != SQL_SUCCESS )      // Could not get a Connect Handle
     goto dberror;
  /*****************************************************************/
  /* CONNECT TO data source (STLEC1)                               */
  /*****************************************************************/
   RETCODE = SQLConnect(hDbc,        // Connect handle
                        (SQLCHAR *) pDSN, // DSN
                        SQL_NTS,     // DSN is nul-terminated
                        NULL,        // Null UID
                        0   ,
                        NULL,        // Null Auth string
                        0);
   if( RETCODE != SQL_SUCCESS )      // Connect failed
     goto dberror;
  /*****************************************************************/
  /* Allocate statement handles                                    */
  /*****************************************************************/
  rc = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt);
  if (rc != SQL_SUCCESS)
    goto exit;
  rc = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt2);
  if (rc != SQL_SUCCESS)
    goto exit;
  /*****************************************************************/
  /* Execute query to retrieve employee names                      */
  /*****************************************************************/
  rc = SQLExecDirect (hStmt,
                      (SQLCHAR *) stmt,
                      strlen(stmt));
  if (rc != SQL_SUCCESS)
  {
    (void) printf ("**** EMPLOYEE QUERY FAILED.\n");
    goto dberror;
  }
  /*****************************************************************/
  /* Extract cursor name -- required to build UPDATE statement.    */
  /*****************************************************************/
  rc = SQLGetCursorName (hStmt,
                         (SQLCHAR *) cursor_name,
                         sizeof(cursor_name),
                         &cbCursor);
  if (rc != SQL_SUCCESS)
  {
    (void) printf ("**** Cursor name is %s.\n");
    goto dberror;
  }
  (void) printf ("**** Cursor name is 
  rc = SQLBindCol (hStmt,           // bind employee name
                   1,
                   SQL_C_CHAR,
                   employee,
                   sizeof(employee),
                   &cbValue1);
  if (rc != SQL_SUCCESS)
  {
    (void) printf ("**** BIND OF NAME FAILED.\n");
    goto dberror;
  }
  rc = SQLBindCol (hStmt,           // bind employee salary
                   2,
                   SQL_C_LONG,
                   &salary,
                   0,
                   &cbValue2);
  if (rc != SQL_SUCCESS)
  {
    (void) printf ("**** BIND OF SALARY FAILED.\n");
    goto dberror;
  }
  /*****************************************************************/
  /* Answer set is available -- Fetch rows and update salary       */
  /*****************************************************************/
  while (((rc = SQLFetch (hStmt)) == SQL_SUCCESS) &&;
         (rc2 == SQL_SUCCESS))
  {
    int new_salary = salary*1.1;
    (void) printf ("**** Employee Name %s with salary %d. New salary = %d.\n",
                   employee,
                   salary,
                   new_salary);
    sprintf (update,
            "UPDATE EMPLOYEE SET SALARY = %d WHERE CURRENT OF %s",
            new_salary,
            cursor_name);
    (void) printf ("***** Update statement is : 
    rc2 = SQLExecDirect (hStmt2,
                         (SQLCHAR *) update,
                         SQL_NTS);
  }
  if (rc2 != SQL_SUCCESS)
  {
    (void) printf ("**** EMPLOYEE UPDATE FAILED.\n");
    goto dberror;
  }
  /*****************************************************************/
  /* Reexecute query to validate that salary was updated           */
  /*****************************************************************/
  rc = SQLCloseCursor(hStmt);
  rc = SQLExecDirect (hStmt,
                      (SQLCHAR *) stmt,
                      strlen(stmt));
  if (rc != SQL_SUCCESS)
  {
    (void) printf ("**** EMPLOYEE QUERY FAILED.\n");
    goto dberror;
  }
  while ((rc = SQLFetch (hStmt)) == SQL_SUCCESS)
  {
    (void) printf ("**** Employee Name %s has salary %d.\n",
                   employee,
                   salary);
  }
  /*****************************************************************/
  /* Deallocate statement handles                                  */
  /*****************************************************************/
  rc = SQLFreeHandle (SQL_HANDLE_STMT, hStmt);
  rc = SQLFreeHandle (SQL_HANDLE_STMT, hStmt2);
  /*****************************************************************/
  /* DISCONNECT from data source                                   */
  /*****************************************************************/
   RETCODE = SQLDisconnect(hDbc);
   if (RETCODE != SQL_SUCCESS)
     goto dberror;
  /*****************************************************************/
  /* Deallocate connection handle                                  */
  /*****************************************************************/
   RETCODE = SQLFreeHandle (SQL_HANDLE_DBC, hDbc);
   if (RETCODE != SQL_SUCCESS)
     goto dberror;
  /*****************************************************************/
  /* Free environment handle                                       */
  /*****************************************************************/
   RETCODE = SQLFreeHandle (SQL_HANDLE_ENV, hEnv);
   if (RETCODE == SQL_SUCCESS)
     goto exit;
   dberror:
   RETCODE=12;
   exit:
   (void) printf ("**** Exiting  CLIP04.\n\n");
   return RETCODE;
}