Home | Previous Page | Next Page   Creating User-Defined Routines > Managing Memory > Understanding Shared Memory >

Choosing the Memory Duration

Because a C UDR executes in the memory space of the database server, its dynamic memory allocations can increase the memory usage of the database server. For this reason, it is very important that a UDR release its dynamically allocated memory as soon as it no longer needs to access this memory.

To help ensure that unneeded memory is freed, the database server associates a memory duration with memory allocation made from its shared memory. The portion of shared memory that the database server provides for dynamic allocation by C UDRs is organized into several memory pools. Each memory pool is associated with a memory duration, which specifies the lifetime of the memory allocated from the pool. Keeping related memory allocations in one pool helps to reduce memory fragmentation.

Figure 85 shows a schematic representation of the shared memory of the database server, including the memory-duration memory pools.

Figure 85. Memory-Duration Memory Pools in Database Server Shared Memory
begin figure description - This figure is described in the surrounding text. - end figure description

Tip:
For more information about the use and structure of database server memory pools, see your IBM Informix: Administrator's Guide. For more information on how to monitor the amount of shared memory that exists in each of the memory pools, see Monitoring Shared Memory.

When the database server calls a UDR, it creates a memory context. This context records all of the allocations that the UDR makes before the routine returns. The UDR might run for some time, calling other UDRs or DataBlade API functions. The database server automatically reclaims shared memory based on its memory duration. When a particular memory duration expires, the database server marks the associated memory pool for deallocation.

The DataBlade API provides the following regular and advanced groups of memory durations for dynamically allocated memory in C UDRs:

Warning:
The advanced memory durations can adversely affect your UDR if you use them incorrectly. Use them only when no regular DataBlade API memory duration can perform the task you need.

Public Memory Durations

The DataBlade API memory-management functions support several public memory durations. A UDR can use a public memory duration for most dynamic allocations of memory. The DataBlade API provides the public memory durations that Table 92 shows.

Table 92. Public Memory Durations
Public Memory Duration Memory-Duration Constant Description
For the duration of one iteration of the UDR PER_ROUTINE, PER_FUNCTION The database server frees the memory after the UDR returns.
For the duration of the current SQL subquery PER_COMMAND The database server frees memory when an SQL command terminates.
For the duration of the current SQL statement PER_STATEMENT (Deprecated) The database server frees memory when an SQL statement terminates.
For the duration of the execution of the current SQL statement PER_STMT_EXEC The database server frees memory when the execution of an SQL statement is complete.
For the duration of the current prepared SQL statement PER_STMT_PREP The database server frees memory when a prepared SQL statement terminates.

The PER_ROUTINE and PER_COMMAND memory durations are the most common for C UDRs. The memory-duration constants in Table 92 are of type MI_MEMORY_DURATION, which the memdur.h header file defines. All memory-duration constants in Table 92 are also declared in the memdur.h header file.

PER_ROUTINE Memory Duration

A PER_ROUTINE memory pool is associated with each UDR invocation. A routine invocation is one single execution of a UDR within a routine instance.

Tip:
The two memory-duration constants PER_ROUTINE and PER_FUNCTION are synonyms for the same memory duration. PER_ROUTINE is the more current name.

When a C UDR allocates PER_ROUTINE memory, this memory is available to code within that single routine invocation of that UDR. The database server reclaims any PER_ROUTINE memory in the memory context when a single invocation of a UDR completes. This memory is actually freed on entry to the next routine invocation. The database server does not reclaim any memory in the memory context with a higher duration than PER_ROUTINE.

In a C UDR, the PER_ROUTINE memory duration is useful for information required for a single UDR invocation. A UDR cannot allocate memory, save a pointer to this memory in static space, and expect the pointer to be valid for the next routine invocation. To save information across invocations, use the user-state pointer of the MI_FPARAM structure. For more information, see Saving a User State.

Several DataBlade API constructor functions allocate their DataBlade API data type structure with a PER_ROUTINE memory duration. Table 93 shows the DataBlade API data type structures that have a memory duration of PER_ROUTINE.

Table 93. DataBlade API Data Type Structures with a PER_ROUTINE Memory Duration
DataBlade API Data Type Structure DataBlade API Constructor Function DataBlade API
Destructor Function
UDR arguments that are
passed by reference
Routine manager
(when it invokes a UDR)
Routine manager
(when it exits a UDR)
UDR return value that is
passed by value
UDR with its declaration of its return value Routine manager
(when it exits a UDR)
UDR return value that is
passed by reference
UDR with call to mi_alloc( ), mi_dalloc( ), or mi_zalloc( ) Routine manager
(when it exits a UDR)

The current memory duration is initialized to this default memory duration. The default memory duration is PER_ROUTINE. For more information, see Managing the Memory Duration.

PER_COMMAND Memory Duration

A PER_COMMAND memory pool is associated with each SQL command. An SQL command is a subquery, which is a separate SQL statement initiated as part of the current SQL statement. The most common kind of subquery is a SELECT statement in the WHERE clause of a SELECT.

When a C UDR allocates PER_COMMAND memory, this memory is available to all routine instances that execute in the same SQL command. For example, the following SELECT statement contains two SQL commands:

SELECT a_func(x) FROM table1
   WHERE i <= 
      (SELECT y FROM table2 WHERE a_func(x) <= 17);

The SELECT operation on table1 is the main query and is one SQL command. The SELECT operation on table2 is a subquery of the main query and is therefore a separate SQL command. All invocations of the a_func( ) function in the main query can share any PER_COMMAND memory that this instance of a_func( ) allocates; however, the invocations of a_func( ) in the subquery have their own PER_COMMAND memory pool. These invocations would not share their memory pool with the invocations of a_func( ) in the main query.

Other examples of subqueries follow:

A separate SQL command is not created for simple WHERE clauses. For example, the following query contains only one SQL command:

SELECT a_func(x) FROM table1 WHERE a_func(y) > 6;

Both instances of a_func( ) use the same PER_COMMAND memory pool for their PER_COMMAND allocations. Therefore, any PER_COMMAND memory that the a_func( ) function allocates can be shared by all invocations of the a_func( ) function in the select list as well as the invocations of a_func( ) in the WHERE clause. If an SQL statement does not contain any subqueries, PER_COMMAND memory lasts for the duration of the SQL statement; that is, the PER_COMMAND and PER_STMT_EXEC memory durations are the same.

Tip:
You can obtain the name of the SQL command that invoked the current UDR with the mi_current_command_name( ) function.

The database server reclaims any PER_COMMAND memory in the memory context as follows:

The only exception to this rule is if this SQL statement is a cursor statement (DECLARE, OPEN, FETCH, UPDATE...WHERE CURRENT OF or DELETE...WHERE CURRENT OF, CLOSE), in which case the database server frees the PER_COMMAND memory when the cursor closes.

The PER_COMMAND memory duration is useful for accumulating calculations, in iterator functions, and for initialization of expensive resources. The most common way for UDR invocations within a routine instance to share information is to store this information in the user state of its MI_FPARAM structure. The routine manager allocates an MI_FPARAM structure for each C UDR instance. This MI_FPARAM structure has a PER_COMMAND memory duration. Therefore, to retain user state across a routine instance, a UDR can allocate PER_COMMAND memory and store its address in the MI_FPARAM structure. The UDR does not need to take special steps to preserve the address of this user-state memory. Each UDR invocation can use the mi_fp_funcstate( ) function to obtain the address from the MI_FPARAM structure.

For example, if a UDR calculates a total, PER_ROUTINE memory would not be adequate to hold this total because the memory would be freed after a single routine invocation. PER_COMMAND memory would be available for the entire routine instance, regardless of the number of invocations involved. For more information on the user state in MI_FPARAM, see Saving a User State.

Several DataBlade API constructor functions allocate their DataBlade API data type structure with a PER_COMMAND memory duration. Table 94 shows the DataBlade API data type structures that have a memory duration of PER_COMMAND.

Table 94. DataBlade API Data Type Structures with a PER_COMMAND Memory Duration
DataBlade API Data
Type Structure
DataBlade API
Constructor Function
DataBlade API
Destructor Function
Function descriptor
(MI_FUNC_DESC)
mi_cast_get( ),
mi_func_desc_by_typeid( ),
mi_routine_get( ),
mi_routine_get_by_typeid( ),
mi_td_cast_get( )
mi_routine_end( )
MI_FPARAM structure Routine manager
(when it invokes a UDR)
Routine manager
(when it exits a UDR)
MI_FPARAM structure
(user-defined)
mi_fparam_allocate( ),
mi_fparam_copy( )
mi_fparam_free( )

Switching the current memory duration before one of the constructor functions in Table 94 does not change the PER_COMMAND memory duration of the allocated DataBlade API data type structure. These data type structures are freed by their destructor function or when the current SQL command completes. To retain access to some of these DataBlade API data type structures after the command completes, you must save them at the per-session level.

Tip:
The DataBlade API supports the ability to save information at a per-session level. This ability, however, is an advanced feature of the DataBlade API. For more information, see Obtaining a Session-Duration Connection Descriptor.
PER_STATEMENT Memory Duration

A PER_STATEMENT memory pool can be associated with each SQL statement, until execution of the statement is complete and for a prepared statement, until the statement terminates. The statement includes any SQL commands that the SQL statement initiates.

Important:
The PER_STATEMENT memory duration is supported for compatibility with existing UDRs. In new code, you should use either the PER_STMT_EXEC or PER_STMT_PREP memory duration. These more precise memory durations replace PER_STATEMENT, which is deprecated.

When a C UDR allocates memory with the PER_STATEMENT memory duration, this memory is available to all routine instances that execute in the same SQL statement.

PER_STMT_EXEC Memory Duration

A PER_STMT_EXEC memory pool is associated with the execution of each SQL statement. A statement is the entire SQL statement plus any SQL commands that the SQL statement initiates, as follows:

When a C UDR allocates memory with the PER_STMT_EXEC memory duration, this memory is available to all routine instances that execute in the same SQL statement. For example, suppose that the following SELECT statement invokes the a_func2( ) user-defined function:

SELECT a_func2(x) FROM table1 WHERE y > 7;

Suppose also that the a_func2( ) function calls mi_exec( ) to execute a SELECT that also invokes a_func2( ), as follows:

mi_integer a_func2(arg)
   mi_integer arg;
{
   ...
   mi_exec(
      "select a_func2(y) from table2 where b_func(y) > 7;", ...)

The SELECT query in the call to mi_exec( ) is a separate SQL command from the main SELECT query. All invocations of the a_func2( ) function in the mi_exec( ) SELECT statement can share any PER_STMT_EXEC memory that this instance of a_func2( ) allocates. They can also share any PER_STMT_EXEC memory that the b_func( ) function (in the WHERE clause) allocates.

The invocations of a_func2( ) in the SELECT on table1 have their own PER_STMT_EXEC memory pool. They would not share it with invocations of a_func2( ) in the mi_exec( ) call.

The database server reclaims any PER_STMT_EXEC memory in the current memory context as follows:

At the completion of execution of a statement, the database server does not reclaim any memory in the memory context with a duration higher than PER_STMT_EXEC. The database server reclaims any PER_STMT_EXEC memory when the SQL statement completes execution, as follows:

Examples of Using PER_STMT_EXEC Memory Duration

For example, suppose the a_func( ) user-defined function allocates PER_STMT_EXEC memory. The code fragment in Figure 86 shows a UDR that calls a_func( ) in a noncursor statement that executes twice.

Figure 86. PER_STMT_EXEC Memory in a Noncursor Statement
mi_integer udr_with_prepared_stmt( )
{
   ...
   stmt3 = mi_prepare(conn, 
      "insert into tab3 values (a_func(87));", NULL);

   /* 1st execution of prepared INSERT */
   mi_exec_prepared_statement(stmt3, ...); 

   /* Code that needs to access PER_STMT_EXEC memory is here */
   ...

   /* 2nd execution of prepared INSERT */
   mi_exec_prepared_statement(stmt3, ...); 
   ...
   return stat;
}

PER_STMT_EXEC memory that a_func( ) allocates in the first call to mi_exec_prepared_statement( ) is released just before the second execution of the prepared INSERT statement begins. Any code after the first mi_exec_prepared_statement( ) call that needs to access this memory can do so. The PER_STMT_EXEC memory that a_func( ) allocates in the second call to mi_exec_prepared_statement( ) remains allocated until the database server returns to the client application the status of the SQL statement that has called the udr_with_prepared_stmt( ) UDR.

The code fragment in Figure 87 shows use of a_func( ) in a cursor statement.

Figure 87. PER_STMT_EXEC Memory in a Cursor Statement
mi_integer get_orders(start_with_cust, end_with_cust)
   mi_integer start_with_cust;
   mi_integer end_with_cust;
{
   mi_string *cmd = 
      "select order_num, a_func(order_num) from orders \
       where customer_num = ?;";
   MI_STATEMENT *stmt;
   mi_integer i;
...
if ( (stmt = mi_prepare(conn, cmd, NULL)) == NULL )
   mi_db_error_raise(NULL, MI_EXCEPTION, 
      "mi_prepare( ) failed");

if ( start_with_cust > end_with_cust )
   mi_db_error_raise(NULL, MI_EXCEPTION, 
      "Arguments invalid.");

for ( i = start_with_cust; i <= end_with_cust; i++)
   {
   values[0] = i;
   types[0] = "integer";
   lengths[0] = 0;
   nulls[0] = MI_FALSE;

   /* Open the read-only cursor to hold the query rows */
   if ( mi_open_prepared_statement(stmt, MI_SEND_READ,
         MI_TRUE, 1, values, lengths, nulls, types, 
         "cust_select", retlen, rettypes) 
         != MI_OK )
      mi_db_error_raise(NULL, MI_EXCEPTION,
         "mi_open_prepared_statement( ) failed");
   /* Fetch the retrieved rows into the cursor */
   if ( mi_fetch_statement(stmt, MI_CURSOR_NEXT, 0, 3) 
         != MI_OK )
      mi_db_error_raise(NULL, MI_EXCEPTION, 
         "mi_fetch_statement( ) failed");

   if ( mi_get_result(conn) != MI_ROWS )
      mi_db_error_raise(NULL, MI_EXCEPTION,
   "mi_get_result( ) failed or found non-query statement");

   /* Retrieve the query rows from the cursor */
   if ( !(get_data(conn)) )
      mi_db_error_raise(NULL, MI_EXCEPTION, 
         "get_data( ) failed");

   /* Close the cursor */
   if ( mi_close_statement(stmt) == MI_ERROR )
      mi_db_error_raise(NULL, MI_EXCEPTION,
         "mi_close_statement( ) failed");

   /* Code that needs to access PER_STMT_EXEC memory is here. */
   ...

   } /* end for */

/* Release resources */
if ( mi_drop_prepared_statement(stmt) == MI_ERROR )
   mi_db_error_raise(NULL, MI_EXCEPTION, 
      "mi_drop_prepared_statement( ) failed");
if ( mi_close(conn) == MI_ERROR )
   mi_db_error_raise(NULL, MI_EXCEPTION,
      "mi_close( ) failed");
}

PER_STMT_EXEC memory that a_func( ) allocated is released just before the cursor is reopened. Therefore, any code after the mi_close_statement( ) function that needs to access this memory can do so. However, once the cursor is reopened, code can no longer access this same PER_STMT_EXEC memory. The PER_STMT_EXEC memory that a_func( ) allocates in the previous (or only) open of the cursor remains allocated until the database server returns to the client application the status of the SQL statement that has called the get_orders( ) UDR.

Uses of PER_STMT_EXEC Memory Duration

The PER_STMT_EXEC memory duration is useful for communications between UDRs, parallel execution, user-defined aggregates, and named memory, and for memory allocations within an end-of-statement callback (if you have information to pass to the callback).

Important:
Any memory with a duration higher than PER_COMMAND could have multiple threads access it. Consider whether you need to handle concurrency issues for any PER_STMT_EXEC memory you allocate. For more information, see Handling Concurrency Issues.

Several DataBlade API constructor functions allocate their DataBlade API data type structure with a PER_STMT_EXEC memory duration. Table 95 lists DataBlade API data type structures that have a memory duration of PER_STMT_EXEC.

Table 95. DataBlade API Data Type Structures with a PER_STMT_EXEC Memory Duration
DataBlade API Data
Type Structure
DataBlade API
Constructor Function
DataBlade API
Destructor Function
Connection descriptor
(MI_CONNECTION)
mi_open( ) mi_close( )
Save-set structure
(MI_SAVE_SET)
mi_save_set_create( ) mi_save_set_destroy( )

Switching the current memory duration before one of the constructor functions in Table 95 does not change the PER_STMT_EXEC memory duration of the allocated DataBlade API structure. These data type structures are freed by their destructor function or when execution of the current SQL statement completes. To retain access to some of these DataBlade API data type structures after the statement completes, you must save them at the per-session level.

Tip:
The DataBlade API supports the ability to save information at a per-session level. This ability, however, is an advanced feature of the DataBlade API. For more information, see Obtaining a Session-Duration Connection Descriptor.
PER_STMT_PREP Memory Duration

A PER_STMT_PREP memory pool is associated with each prepared SQL statement. A prepared statement is an SQL statement that is parsed and ready for execution. The following table summarizes ways to create and drop a prepared statement.

Method To Create a Prepared Statement To Drop a Prepared Statement
Client application (SQL) PREPARE FREE
C UDR
(DataBlade API)
mi_prepare( ) mi_drop_prepared_statement( )

When a C UDR allocates PER_STMT_PREP memory, this memory is available to all routine instances that execute before the current prepared statement is dropped. Unlike PER_STMT_EXEC memory, PER_STMT_PREP memory does not get freed upon re-execution of the prepared statement; that is, it remains allocated if the cursor is closed and reopened. For example, in Figure 87, any PER_STMT_PREP memory that a_func( ) allocated is not released when the cursor is reopened. Therefore, any code that needs to access this memory once the cursor is reopened can do so. The PER_STMT_PREP memory that a_func( ) allocates remains allocated until the mi_drop_prepared_statement( ) drops the stmt prepared statement.

When the prepared SQL statement is dropped, the database server reclaims any PER_STMT_PREP memory in the memory context. It does not reclaim any memory in the memory context with a duration higher than PER_STMT_PREP.

No DataBlade API constructor function allocates its data type structure with a memory duration of PER_STMT_PREP.

Advanced Memory Durations

The DataBlade API memory-management functions also support several advanced memory durations, which Table 96 shows.

Table 96. Advanced Memory Durations
Advanced Memory Duration Memory-Duration Constant Description
For the duration of the current transaction PER_TRANSACTION The database server frees the memory after the current transaction ends (commit or rollback).
For the duration of the current session PER_SESSION The database server frees memory at the end of the current session.
For the duration of the database server execution PER_SYSTEM The database server frees memory when it is brought down.
Warning:
The memory durations in Table 96 are advanced and can adversely affect your UDR if you use them incorrectly. Use them only when no regular DataBlade API memory duration can perform the task you need.

As with the public memory-duration constants, the advanced memory-duration constants in Table 96 are of type MI_MEMORY_DURATION. However, these constants are declared in the minmdur.h header file, not the memdur.h header file. The minmmem.h header file automatically includes the minmdur.h header file. The mi.h header file, however, does not automatically include minmmem.h. To access advanced memory durations, you must include minmmem.h in any DataBlade API routine that uses these memory durations.

Important:
Any memory with a duration higher than PER_COMMAND could have multiple threads access it. Therefore, consider whether you need to handle concurrency issues for any PER_TRANSACTION, PER_SESSION, or PER_SYSTEM memory you allocate. For more information, see Handling Concurrency Issues.
PER_TRANSACTION Memory Duration

A PER_TRANSACTION memory pool can be associated with either of the following:

When a C UDR allocates PER_TRANSACTION memory, this memory is available to all routine instances that execute before the current transaction closes. The database server reclaims any PER_TRANSACTION shared memory in the memory context in either of the following situations:

Tip:
An EXECUTE PROCEDURE statement does not create an implicit transaction. If EXECUTE PROCEDURE is not already part of an explicit transaction, the UDR that it calls can use a BEGIN WORK and COMMIT WORK (or ROLLBACK WORK) to specify a transaction. For more information, see Transaction Management.

At this time, the database server does not reclaim any memory in the memory context with a duration higher than PER_TRANSACTION.

The PER_TRANSACTION memory duration is useful for the following tasks:

Allocate PER_TRANSACTION memory as named memory because this memory requires locking. To access it, a C UDR must know the name of the memory and it must be within the scope of the transaction. Such a UDR can explicitly free this memory with the mi_named_free( ) function. However, consider PER_TRANSACTION memory as permanent to the current transaction. For more information, see Managing Named Memory.

No DataBlade API constructor function allocates its data type structure with a memory duration of PER_TRANSACTION.

PER_SESSION Memory Duration

A PER_SESSION memory pool is associated with each session. A session begins when a client connects to the database server, and it ends when the connection terminates. When a C UDR allocates PER_SESSION memory, this memory is available to all routine instances that execute before the current session ends. When the current session ends, the database server reclaims any PER_SESSION shared memory in the memory context. It does not reclaim any memory in the memory context with a duration higher than PER_SESSION.

The PER_SESSION memory duration is useful for the following tasks:

Allocate PER_SESSION memory as named memory because this memory requires locking. To access it, a C UDR must know the name of the memory and it must be within the scope of the session. Such a UDR can explicitly free this memory with the mi_named_free( ) function. However, consider PER_SESSION memory as permanent to the session. For more information, see Managing Named Memory.

Several DataBlade API constructor functions allocate their DataBlade API data type structures with a PER_SESSION memory duration. Table 97 shows the DataBlade API data type structures that have a memory duration of PER_SESSION.

Table 97. DataBlade API Data Type Structures with a PER_SESSION Memory Duration
DataBlade API Data
Type Structure
DataBlade API
Constructor Function
DataBlade API
Destructor Function
Session-duration
connection descriptor
(MI_CONNECTION)
mi_get_session_connection( ) End of session
Session-duration
function descriptor
(MI_FUNC_DESC)
mi_cast_get( ),
mi_func_desc_by_typeid( ),
mi_routine_get( ),
mi_routine_get_by_typeid( ),
mi_td_cast_get( )

(when these functions receive a session-duration connection descriptor as an argument)

End of session
File descriptor mi_file_open( ) mi_file_close( )
Transient smart large object mi_lo_copy( ),
mi_lo_create( ),
mi_lo_expand( ),
mi_lo_from_file( ),
mi_lo_from_string( )

(but do not insert the LO handle into a column of the database)

mi_lo_release( ),
mi_lo_delete_immediate( )

Switching the current memory duration before one of the constructor functions in Table 97 does not change the PER_SESSION memory duration of the allocated DataBlade API structure. These data type structures are freed by their destructor function or when the current session ends.

PER_SYSTEM Memory Duration

A PER_SYSTEM memory pool is associated with the database server instance. A database server instance begins when the oninit utility (or its equivalent) initializes the database server, and it ends when the database server is brought down. When a C UDR allocates PER_SYSTEM memory, this memory is available to all routine instances that execute before the database server instance is shut down. As the database server shuts down, it frees any PER_SYSTEM shared memory.

The PER_SYSTEM memory duration is useful for system-wide caching and resource initialization. Allocate PER_SYSTEM memory as named memory because this memory requires locking. To access it, a C UDR must know the name of the memory. The UDR can explicitly free this memory with the mi_named_free( ) function. However, consider PER_SYSTEM memory as permanent to the database server. For more information, see Managing Named Memory.

Warning:
The PER_SYSTEM memory duration takes up memory that the database server might use for other tasks. Restrict your use of memory with the PER_SYSTEM memory duration. For most uses, memory can be successfully allocated with shorter memory durations.

No DataBlade API constructor function allocates its data type structure with a memory duration of PER_SYSTEM.

Memory-Duration Considerations

When a UDR needs to allocate memory dynamically, it must take the following actions:

Choosing Memory Duration

When the UDR allocates memory, it must ensure that this memory has a appropriate memory duration. Choose a memory duration on the basis of which UDR instances need to share the information stored in the memory. Make sure you choose a memory duration that is appropriate to the use of the allocated memory. An inappropriate memory duration can cause the following problems:

Whenever possible, use the following public memory-management features of the DataBlade API:

Warning:
Keep track of the scope and memory duration of the memory that you allocate with the DataBlade API memory-management functions. Incorrect memory duration can create serious memory corruption.
Saving the Memory Address

In addition to ensuring that the allocated memory has an appropriate memory duration, you must ensure that the UDR can obtain the address of this memory when it needs to access the information within the memory. For example, if you allocate PER_COMMAND memory within a UDR but only store its address in a local variable, this address is deallocated when the UDR completes.

Important:
The deallocation of the memory address but not the associated memory is one of the most common causes of memory leaks. Make sure that the duration of the memory address is compatible with that of its memory.

The following table summarizes common ways to save a memory address.

Memory Duration Where To Store Memory Address Scope of Address
PER_ROUTINE Does not need to be handled because the memory and its address are only valid within a single routine invocation. Current invocation of UDR
PER_COMMAND Store the memory address in the user state of the MI_FPARAM structure.

You can take special steps (such as named memory) to store the memory address so that it can be accessed by other UDRs:

  • Named memory
  • Session-duration connection
All invocations of the UDR within the current SQL command

All UDRs that know the name of the named-memory block

All UDRs that have access to the session-duration connection descriptor

PER_STMT_EXEC If the SQL statement does not contain any subqueries, you can store the memory address in the user state of the MI_FPARAM structure.

If the SQL statement contains subqueries, you must take special steps (such as named memory) to store the memory address so that it can be accessed by other instances of the same UDR or by other UDRs.

All invocations of the UDR within the current SQL statement
Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]