Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
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):
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.
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.
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.
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.
Ismételje meg a 3. és a 4. lépést az aktuális paraméter lekéréséhez.
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.
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;
}