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.
A paramétertömböket használó alkalmazások az SQL-utasítás paramétereihez kötik a tömböket. Két kötési stílus létezik:
Minden paraméterhez egy tömböt kössön. Minden adatstruktúra (tömb) egyetlen paraméter összes adatát tartalmazza. Ezt oszlopalapú kötésnek nevezik, mert egyetlen paraméterhez egy értékoszlopot köt össze.
Definiáljon egy struktúrát, amely egy teljes paramétercsoport paraméteradatait tárolja, és összefűz egy tömböt ezekből a struktúrákból. Minden adatstruktúra egyetlen SQL-utasítás adatait tartalmazza. Ezt sorszintű kötésnek nevezik, mert egy sor paramétert köt össze.
Amikor az alkalmazás egyetlen változót köt a paraméterekhez, meghívja az SQLBindParametert , hogy a tömböket paraméterekhez kösse. Az egyetlen különbség az, hogy az átadott címek tömbcímek, nem egyváltozós címek. Az alkalmazás beállítja a SQL_ATTR_PARAM_BIND_TYPE utasításattribútumot annak meghatározására, hogy oszlopalapú (alapértelmezett) vagy sorszintű kötést használ-e. Az, hogy oszloponkénti vagy soronkénti kötést használ-e, nagyrészt az alkalmazás preferenciája alapján dől el. Attól függően, hogy a processzor hogyan fér hozzá a memóriához, a sorszintű kötés gyorsabb lehet. A különbség azonban valószínűleg elhanyagolható, kivéve a nagyon nagy számú paramétersort.
Column-Wise kötés
Oszlopalapú kötés használatakor egy alkalmazás egy vagy két tömböt köt minden olyan paraméterhez, amelyhez adatokat kell megadni. Az első tömb tartalmazza az adatértékeket, a második pedig a hossz-/mutatópuffereket. Minden tömb annyi elemet tartalmaz, amennyit a paraméter értéke tartalmaz.
Az oszlopalapú kötés az alapértelmezett. Az alkalmazás a SQL_ATTR_PARAM_BIND_TYPE utasításattribútum beállításával sorszintű kötésről oszlopszintű kötésre is válthat. Az alábbi ábra az oszlopalapú kötés működését mutatja be.
Az alábbi kód például 10 elemű tömböket köt a PartID, a Description és a Price oszlopok paramétereihez, és végrehajt egy utasítást, amely 10 sort szúr be. Oszlopszintű kötést használ.
#define DESC_LEN 51
#define ARRAY_SIZE 10
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (?, ?, ?)";
SQLUINTEGER PartIDArray[ARRAY_SIZE];
SQLCHAR DescArray[ARRAY_SIZE][DESC_LEN];
SQLREAL PriceArray[ARRAY_SIZE];
SQLINTEGER PartIDIndArray[ARRAY_SIZE], DescLenOrIndArray[ARRAY_SIZE],
PriceIndArray[ARRAY_SIZE];
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLULEN ParamsProcessed;
memset(DescLenOrIndArray, 0, sizeof(DescLenOrIndArray));
memset(PartIDIndArray, 0, sizeof(PartIDIndArray));
memset(PriceIndArray, 0, sizeof(PriceIndArray));
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in column-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
PartIDArray, 0, PartIDIndArray);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
DescArray, DESC_LEN, DescLenOrIndArray);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
PriceArray, 0, PriceIndArray);
// Set part ID, description, and price.
for (i = 0; i < ARRAY_SIZE; i++) {
GetNewValues(&PartIDArray[i], DescArray[i], &PriceArray[i]);
PartIDIndArray[i] = 0;
DescLenOrIndArray[i] = SQL_NTS;
PriceIndArray[i] = 0;
}
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
// Check to see which sets of parameters were processed successfully.
for (i = 0; i < ParamsProcessed; i++) {
printf("Parameter Set Status\n");
printf("------------- -------------\n");
switch (ParamStatusArray[i]) {
case SQL_PARAM_SUCCESS:
case SQL_PARAM_SUCCESS_WITH_INFO:
printf("%13d Success\n", i);
break;
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}
}
Row-Wise kötés
Sorszintű kötés használatakor az alkalmazás minden paramétercsoporthoz definiál egy struktúrát. A struktúra minden paraméterhez egy vagy két elemet tartalmaz. Az első elem tartalmazza a paraméter értékét, a második pedig a hossz/mutató pufferét. Az alkalmazás ezután lefoglal egy tömböt ezekből a struktúrákból, amelyek annyi elemet tartalmaznak, amennyit az egyes paraméterek értékei tartalmaznak.
Az alkalmazás a SQL_ATTR_PARAM_BIND_TYPE utasítás attribútummal deklarálja a struktúra méretét az illesztőnek. Az alkalmazás a tömb első szerkezetében köti össze a paraméterek címét. Így az illesztő kiszámíthatja egy adott sor és oszlop adatainak címét a következő módon:
Address = Bound Address + ((Row Number - 1) * Structure Size) + Offset
ahol a sorok száma 1 és a paraméterkészlet mérete között van megadva. Ha meg van adva, az eltolás azon érték, amelyre az SQL_ATTR_PARAM_BIND_OFFSET_PTR utasítás attribútuma mutat. Az alábbi ábra a sorszintű kötés működését mutatja be. A paraméterek bármilyen sorrendben elhelyezhetők a struktúrában, de az egyértelműség érdekében szekvenciális sorrendben jelennek meg.
Az alábbi kód létrehoz egy struktúrát a PartID, a Description és az Price oszlopban tárolandó értékek elemeivel. Ezután lefoglal egy 10 elemből álló tömböt ezekből a struktúrákból, és sorszintű kötéssel a PartID, a Description és az Price oszlop paramétereihez köti. Ezután végrehajt egy utasítást 10 sor beszúrásához.
#define DESC_LEN 51
#define ARRAY_SIZE 10
typedef tagPartStruct {
SQLREAL Price;
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLINTEGER PriceInd;
SQLINTEGER PartIDInd;
SQLINTEGER DescLenOrInd;
} PartStruct;
PartStruct PartArray[ARRAY_SIZE];
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description,
Price) "
"VALUES (?, ?, ?)";
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLULEN ParamsProcessed;
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, sizeof(PartStruct), 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in row-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartArray[0].PartID, 0, &PartArray[0].PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
PartArray[0].Desc, DESC_LEN, &PartArray[0].DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&PartArray[0].Price, 0, &PartArray[0].PriceInd);
// Set part ID, description, and price.
for (i = 0; i < ARRAY_SIZE; i++) {
GetNewValues(&PartArray[i].PartID, PartArray[i].Desc, &PartArray[i].Price);
PartArray[0].PartIDInd = 0;
PartArray[0].DescLenOrInd = SQL_NTS;
PartArray[0].PriceInd = 0;
}
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
// Check to see which sets of parameters were processed successfully.
for (i = 0; i < ParamsProcessed; i++) {
printf("Parameter Set Status\n");
printf("------------- -------------\n");
switch (ParamStatusArray[i]) {
case SQL_PARAM_SUCCESS:
case SQL_PARAM_SUCCESS_WITH_INFO:
printf("%13d Success\n", i);
break;
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}