Megosztás:


Kimeneti paraméterek lekérése AZ SQLGetData használatával

Az ODBC 3.8 előtt egy alkalmazás csak egy kötött kimeneti pufferrel rendelkező lekérdezés kimeneti paramétereit tudta lekérni. Nehéz azonban nagyon nagy puffert lefoglalni, ha a paraméter értéke nagyon nagy (például nagy kép). Az ODBC 3.8 új módszert vezet be a kimeneti paraméterek részekben való lekérésére. Az alkalmazások mostantól többször is meghívhatják a kis pufferrel rendelkező SQLGetData-t egy nagy paraméterérték lekéréséhez. Ez hasonló a nagy oszlopadatok beolvasásához.

Ha a kimeneti vagy a bemeneti/kimeneti paramétert részekben szeretné lekérni, akkor hívja meg az SQLBindParameter függvényt az InputOutputType argumentummal, úgy állítva be, hogy annak értéke legyen SQL_PARAM_OUTPUT_STREAM vagy SQL_PARAM_INPUT_OUTPUT_STREAM. A SQL_PARAM_INPUT_OUTPUT_STREAM az alkalmazás az SQLPutData használatával adatokat adhat meg a paraméterhez, majd az SQLGetData használatával lekérheti a kimeneti paramétert. A bemeneti adatoknak futásidőben rendelkezésre álló (DAE) formában kell lenniük, SQLPutData használatával, ahelyett, hogy előre kiosztott pufferhez kötve legyenek.

Ezt a funkciót használhatják az ODBC 3.8-alkalmazások, vagy újrafordított ODBC 3.x és ODBC 2.x alkalmazások, és ezeknek az alkalmazásoknak rendelkezniük kell egy ODBC 3.8-illesztővel, amely támogatja a kimeneti paraméterek sqlGetData és ODBC 3.8 Driver Manager használatával történő lekérését. Ha tudni szeretné, hogyan engedélyezheti egy régebbi alkalmazásnak az új ODBC-funkciók használatát, tekintse meg a kompatibilitási mátrixot.

Használati példa

Gondolja például egy tárolt eljárás végrehajtását, {CALL sp_f(?,?)}, amelyben mindkét paraméter SQL_PARAM_OUTPUT_STREAM-ként van kötve, és az eljárás nem ad vissza eredményhalmazt (a későbbiekben ebben a témakörben egy összetettebb forgatókönyvet talál):

  1. Minden paraméternél hívja meg az SQLBindParameter függvényt úgy, hogy az InputOutputType beállítást SQL_PARAM_OUTPUT_STREAM-ra, és a ParameterValuePtr-t egy jogkivonatra, például paraméterszámra, adatokra mutató pointerre, vagy egy olyan struktúrára mutató pointerre, amelyet az alkalmazás a bemeneti paraméterek kötésére használ. Ez a példa az ordinális paramétert fogja használni tokenként.

  2. Hajtsa végre a lekérdezést az SQLExecDirect vagy az SQLExecute használatával. SQL_PARAM_DATA_AVAILABLE lesz visszaadva, ami azt jelzi, hogy a lekéréshez streamelt kimeneti paraméterek állnak rendelkezésre.

  3. Hívja meg az SQLParamData-t az elérhető paraméter lekéréséhez. Az SQLParamData SQL_PARAM_DATA_AVAILABLE ad vissza az első elérhető paraméter jogkivonatával, amely az SQLBindParameterben van beállítva (1. lépés). A token abban a pufferben kerül visszaadásra, amelyre a ValuePtrPtr mutat.

  4. Hívja meg az SQLGetData-t az Col_or_Param_Num argumentummal úgy, hogy az a paraméter sorszámát mutassa, az első elérhető paraméter adatainak lekéréséhez. Ha az SQLGetData SQL_SUCCESS_WITH_INFO és SQLState 01004 értéket ad vissza (az adatok csonkolva vannak), és a típus változó hosszúságú mind az ügyfélen, mind a kiszolgálón, több adatot kell lekérni az első elérhető paraméterből. Továbbra is meghívhatja az SQLGetData-t , amíg vissza nem adja SQL_SUCCESS vagy SQL_SUCCESS_WITH_INFO egy másik SQLState-val.

  5. Ismételje meg a 3. és a 4. lépést az aktuális paraméter lekéréséhez.

  6. Hívja meg újra az SQLParamData-t . Ha az SQL_PARAM_DATA_AVAILABLE kivételével bármit visszaad, nincs több streamelt paraméteradat, és a visszatérési kód a következő végrehajtott utasítás visszatérési kódja lesz.

  7. Az SQLMoreResults meghívásával dolgozza fel a következő paraméterkészletet, amíg vissza nem adja SQL_NO_DATA. Az SQLMoreResults ebben a példában SQL_NO_DATA ad vissza, ha a SQL_ATTR_PARAMSET_SIZE utasítás attribútum értéke 1. Ellenkező esetben az SQLMoreResults SQL_PARAM_DATA_AVAILABLE ad vissza, amely azt jelzi, hogy a következő lekérendő paraméterekhez elérhető streamelt kimeneti paraméterek állnak rendelkezésre.

A DAE bemeneti paraméteréhez hasonlóan az SQLBindParameterParaméterValuePtr argumentumában használt token (1. lépés) egy olyan mutató lehet, amely egy alkalmazásadat-struktúrára mutat, amely tartalmazza a paraméter sorszámát és szükség esetén további alkalmazásspecifikus információkat.

A visszaadott streamelt kimenet vagy bemeneti/kimeneti paraméterek sorrendje illesztőprogram-specifikus, és lehet, hogy nem mindig ugyanaz, mint a lekérdezésben megadott sorrend.

Ha az alkalmazás nem hívja meg az SQLGetData-t a 4. lépésben, a paraméter értéke el lesz vetve. Hasonlóképpen, ha az alkalmazás meghívja az SQLParamData-t , mielőtt az SQLGetData beolvassa az összes paraméterértéket, a rendszer elveti az érték fennmaradó részét, és az alkalmazás feldolgozhatja a következő paramétert.

Ha az alkalmazás meghívja az SQLMoreResults metódust az összes streamelt kimeneti paraméter feldolgozása előtt (az SQLParamData továbbra is SQL_PARAM_DATA_AVAILABLE ad vissza), a rendszer minden fennmaradó paramétert elvet. Hasonlóképpen, ha az alkalmazás meghívja az SQLMoreResults parancsot, mielőtt az SQLGetData beolvassa az összes paraméterértéket, a rendszer elveti az érték fennmaradó részét és az összes többi paramétert, és az alkalmazás továbbra is feldolgozhatja a következő paraméterkészletet.

Vegye figyelembe, hogy egy alkalmazás az SQLBindParameterben és az SQLGetData-ban is megadhatja a C adattípust. Az SQLGetData-ban megadott C adattípus felülírja az SQLBindParameterben megadott C adattípust, kivéve, ha az SQLGetData-ban megadott C adattípus SQL_APD_TYPE.

Bár a streamelt kimeneti paraméter hasznosabb, ha a kimeneti paraméter adattípusa BLOB típusú, ez a funkció bármilyen adattípussal használható. A streamelt kimeneti paraméterek által támogatott adattípusok az illesztőprogramban vannak megadva.

Ha SQL_PARAM_INPUT_OUTPUT_STREAM paramétereket kell feldolgozni, az SQLExecute vagy az SQLExecDirect először SQL_NEED_DATA ad vissza. Az alkalmazások meghívhatják az SQLParamData-t és az SQLPutData-t a DAE-paraméteradatok küldéséhez. Amikor az összes DAE bemeneti paraméter feldolgozásra kerül, az SQLParamData SQL_PARAM_DATA_AVAILABLE-t ad vissza, jelezve, hogy a streamelt kimeneti paraméterek rendelkezésre állnak.

Amikor streamelt kimeneti paraméterek és kötött kimeneti paraméterek dolgozhatók fel, az illesztőprogram határozza meg a kimeneti paraméterek feldolgozásának sorrendjét. Ha tehát egy kimeneti paraméter egy pufferhez van kötve (az SQLBindParameterInputOutputType paraméter értéke SQL_PARAM_INPUT_OUTPUT vagy SQL_PARAM_OUTPUT), a puffer csak akkor tölthető fel, ha az SQLParamData SQL_SUCCESS vagy SQL_SUCCESS_WITH_INFO ad vissza. Egy alkalmazásnak csak akkor kell beolvasnia egy kötött puffert, ha az SQLParamData SQL_SUCCESS vagy SQL_SUCCESS_WITH_INFO ad vissza, amely az összes streamelt kimeneti paraméter feldolgozása után történik.

Az adatforrás a streamelt kimeneti paraméter mellett figyelmeztetést és eredményhalmazt is visszaadhat. A figyelmeztetések és eredményhalmazok általában az SQLMoreResults meghívásával külön dolgozhatók fel a streamelt kimeneti paramétertől. A figyelmeztetések és az eredményhalmaz feldolgozása történjen meg a streamelt kimeneti paraméter feldolgozása előtt.

Az alábbi táblázat a kiszolgálónak küldött egyetlen parancs különböző forgatókönyveit és az alkalmazás működését ismerteti.

Scenario Az SQLExecute vagy az SQLExecDirect visszatérési értéke Következő lépések
Az adatok csak streamelt kimeneti paramétereket tartalmaznak SQL_PARAM_DATA_AVAILABLE Az SQLParamData és az SQLGetData használatával kérje le a streamelt kimeneti paramétereket.
Az adatok eredményhalmazt és streamelt kimeneti paramétereket tartalmaznak SQL_SUCCESS Kérje le az eredményhalmazt az SQLBindCol és az SQLGetData használatával.

Az SQLMoreResults meghívása streamelt kimeneti paraméterek feldolgozásának megkezdéséhez. Vissza kell adnia SQL_PARAM_DATA_AVAILABLE.

Az SQLParamData és az SQLGetData használatával kérje le a streamelt kimeneti paramétereket.
Az adatok figyelmeztető üzenetet és streamelt kimeneti paramétereket tartalmaznak SQL_SUCCESS_WITH_INFO Az SQLGetDiagRec és az SQLGetDiagField használatával dolgozza fel a figyelmeztető üzeneteket.

Az SQLMoreResults meghívása streamelt kimeneti paraméterek feldolgozásának megkezdéséhez. Vissza kell adnia SQL_PARAM_DATA_AVAILABLE.

Az SQLParamData és az SQLGetData használatával kérje le a streamelt kimeneti paramétereket.
Az adatok figyelmeztető üzenetet, eredményhalmazt és streamelt kimeneti paramétereket tartalmaznak SQL_SUCCESS_WITH_INFO Az SQLGetDiagRec és az SQLGetDiagField használatával dolgozza fel a figyelmeztető üzeneteket. Ezután hívja meg az SQLMoreResults parancsot az eredményhalmaz feldolgozásának megkezdéséhez.

Eredményhalmaz lekérése SQLBindCol és SQLGetData használatával.

Az SQLMoreResults meghívása streamelt kimeneti paraméterek feldolgozásának megkezdéséhez. Az SQLMoreResults függvénynek SQL_PARAM_DATA_AVAILABLE kell visszaadnia.

Az SQLParamData és az SQLGetData használatával kérje le a streamelt kimeneti paramétereket.
DAE bemeneti paraméterekkel való lekérdezés, például streamelt bemeneti/kimeneti (DAE) paraméter esetén SQL-NEED_DATA Hívja meg az SQLParamData-t és az SQLPutData-t a DAE bemeneti paraméteradatainak küldéséhez.

Az összes DAE bemeneti paraméter feldolgozása után az SQLParamData bármilyen olyan visszatérési kódot visszaadhat, amelyet az SQLExecute és az SQLExecDirect visszaadhat. A táblázatban szereplő esetek ezután alkalmazhatók.

Ha a visszatérési kód SQL_PARAM_DATA_AVAILABLE, streamelt kimeneti paraméterek érhetők el. Az alkalmazásnak újra meg kell hívnia az SQLParamData-t a streamelt kimeneti paraméter jogkivonatának lekéréséhez, a tábla első sorában leírtak szerint.

Ha a visszatérési kód SQL_SUCCESS, akkor vagy van feldolgozandó eredménykészlet, vagy a feldolgozás befejeződött.

Ha a visszatérési kód SQL_SUCCESS_WITH_INFO, a feldolgozandó figyelmeztető üzenetek jelennek meg.

Miután az SQLExecute, az SQLExecDirect vagy az SQLMoreResults SQL_PARAM_DATA_AVAILABLE ad vissza, függvényütemezési hiba lép fel, ha egy alkalmazás olyan függvényt hív meg, amely nem szerepel a következő listában:

  • SQLAllocHandle / SQLAllocHandleStd

  • SQLDataSources / SQLDrivers

  • SQLGetInfo / SQLGetFunctions

  • SQLGetConnectAttr / SQLGetEnvAttr / SQLGetDescField / SQLGetDescRec

  • SQLNumParams

  • SQLDescribeParam

  • SQLNativeSql

  • SQLParamData

  • SQLMoreResults

  • SQLGetDiagField / SQLGetDiagRec

  • SQLCancel

  • SQLCancelHandle (utasításkezelővel)

  • SQLFreeStmt (Option = SQL_CLOSE, SQL_DROP vagy SQL_UNBIND)

  • SQLCloseCursor

  • SQLDisconnect

  • SQLFreeHandle (HandleType = SQL_HANDLE_STMT)

  • SQLGetStmtAttr

Az alkalmazások továbbra is használhatják az SQLSetDescFieldet vagy az SQLSetDescRec-t a kötési információk beállításához. A mezőleképezés nem módosul. A leírón belüli mezők azonban új értékeket adhatnak vissza. Például előfordulhat, hogy az SQL_DESC_PARAMETER_TYPE az SQL_PARAM_INPUT_OUTPUT_STREAM vagy az SQL_PARAM_OUTPUT_STREAM értékeket adja vissza.

Használati forgatókönyv: Kép lekérése részekben eredményhalmazból

Az SQLGetData részekben történő adatlekérésre használható, ha egy tárolt eljárás egy olyan eredményhalmazt ad vissza, amely egy kép metaadatainak egy sorát tartalmazza, és a rendszer a képet egy nagy kimeneti paraméterben adja vissza.

// CREATE PROCEDURE SP_TestOutputPara  
//      @ID_of_picture   as int,  
//      @Picture         as varbinary(max) out  
// AS  
//     output the image data through streamed output parameter  
// GO  
BOOL displayPicture(SQLUINTEGER idOfPicture, SQLHSTMT hstmt) {  
   SQLLEN      lengthOfPicture;    // The actual length of the picture.  
   BYTE        smallBuffer[100];   // A very small buffer.  
   SQLRETURN   retcode, retcode2;  
  
   // Bind the first parameter (input parameter)  
   SQLBindParameter(  
         hstmt,  
         1,                         // The first parameter.   
         SQL_PARAM_INPUT,           // Input parameter: The ID_of_picture.  
         SQL_C_ULONG,               // The C Data Type.  
         SQL_INTEGER,               // The SQL Data Type.  
         0,                         // ColumnSize is ignored for integer.  
         0,                         // DecimalDigits is ignored for integer.  
         &idOfPicture,              // The Address of the buffer for the input parameter.  
         0,                         // BufferLength is ignored for integer.  
         NULL);                     // This is ignored for integer.  
  
   // Bind the streamed output parameter.  
   SQLBindParameter(  
         hstmt,   
         2,                         // The second parameter.  
         SQL_PARAM_OUTPUT_STREAM,   // A streamed output parameter.   
         SQL_C_BINARY,              // The C Data Type.    
         SQL_VARBINARY,             // The SQL Data Type.  
         0,                         // ColumnSize: The maximum size of varbinary(max).  
         0,                         // DecimalDigits is ignored for binary type.  
         (SQLPOINTER)2,             // 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.   
  
   retcode = SQLPrepare(hstmt, L"{call SP_TestOutputPara(?, ?)}", SQL_NTS);  
   if ( retcode == SQL_ERROR )  
      return FALSE;  
  
   retcode = SQLExecute(hstmt);  
   if ( retcode == SQL_ERROR )  
      return FALSE;  
  
   // 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.  
   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,   
               (UWORD) token,          // the value of the token is the ordinal.   
               SQL_C_BINARY,           // The C-type.  
               smallBuffer,            // A small buffer.   
               sizeof(smallBuffer),    // The size of the buffer.  
               &cbLeft);               // How much data we can get.  
         }  
         while ( retcode2 == SQL_SUCCESS_WITH_INFO );  
      }  
   }  
  
   return TRUE;  
}  

Használati forgatókönyv: Nagy objektum küldése és fogadása streamelt bemeneti/kimeneti paraméterként

Az SQLGetData használatával adatokat kérhet le és küldhet el részekben, amikor egy tárolt eljárás egy nagy objektumot ad át bemeneti/kimeneti paraméterként, és az értéket az adatbázisba és onnan streameli. Nem kell az összes adatot a memóriában tárolnia.

// CREATE PROCEDURE SP_TestInOut  
//       @picture as varbinary(max) out  
// AS  
//    output the image data through output parameter   
// go  
  
BOOL displaySimilarPicture(BYTE* image, ULONG lengthOfImage, SQLHSTMT hstmt) {  
   BYTE smallBuffer[100];   // A very small buffer.  
   SQLRETURN retcode, retcode2;  
   SQLLEN statusOfPicture;  
  
   // First bind the parameters, before preparing the statement that binds the output streamed parameter.  
   SQLBindParameter(  
      hstmt,   
      1,                                 // The first parameter.  
      SQL_PARAM_INPUT_OUTPUT_STREAM,     // I/O-streamed parameter: The Picture.  
      SQL_C_BINARY,                      // The C Data Type.  
      SQL_VARBINARY,                     // The SQL Data Type.  
      0,                                 // ColumnSize: The maximum size of varbinary(max).  
      0,                                 // DecimalDigits is ignored.   
      (SQLPOINTER)1,                     // An application defined token.   
      0,                                 // BufferLength is ignored for streamed I/O parameters.  
      &statusOfPicture);                 // The status variable.  
  
   statusOfPicture = SQL_DATA_AT_EXEC;   // Input data in parts (DAE parameter at input).  
  
   retcode = SQLPrepare(hstmt, L"{call SP_TestInOut(?) }", SQL_NTS);  
   if ( retcode == SQL_ERROR )  
      return FALSE;  
  
   // Execute the statement.  
   retcode = SQLExecute(hstmt);  
   if ( retcode == SQL_ERROR )  
      return FALSE;  
  
   if ( retcode == SQL_NEED_DATA ) {  
      // Use SQLParamData to loop through DAE input parameters.  For  
      // each, use SQLPutData to send the data to database in parts.  
  
      // This example uses an I/O parameter with streamed output.  
      // Therefore, the last call to SQLParamData should return  
      // SQL_PARAM_DATA_AVAILABLE to indicate the end of the input phrase   
      // and report that a streamed output parameter is available.  
  
      // Assume retcode is set to the return value of the last call to  
      // SQLParamData, which is equal to SQL_PARAM_DATA_AVAILABLE.  
   }  
  
   // Start processing the streamed output parameters.  
   while ( retcode == SQL_PARAM_DATA_AVAILABLE ) {  
      SQLPOINTER token;   // Output by SQLParamData.  
      SQLLEN cbLeft;     // #bytes remained  
      retcode = SQLParamData(hstmt, &token);  
      if ( retcode == SQL_PARAM_DATA_AVAILABLE ) {  
         do {  
            retcode2 = SQLGetData(   
               hstmt,   
               (UWORD) token,          // the value of the token is the ordinal.   
               SQL_C_BINARY,           // The C-type.  
               smallBuffer,            // A small buffer.   
               sizeof(smallBuffer),    // The size of the buffer.  
               &cbLeft);               // How much data we can get.  
         }  
         while ( retcode2 == SQL_SUCCESS_WITH_INFO );  
      }  
   }   
  
   return TRUE;  
}  

Lásd még:

Kifejezésparaméterek