Partager via


Instructions SQL codées en dur

Les applications qui effectuent une tâche fixe contiennent généralement des instructions SQL codées en dur. Par exemple, un système d’entrée de commande peut utiliser l’appel suivant pour répertorier les commandes commerciales ouvertes :

SQLExecDirect(hstmt, "SELECT OrderID FROM Orders WHERE Status = 'OPEN'", SQL_NTS);  

Il existe plusieurs avantages pour les instructions SQL codées en dur : elles peuvent être testées lorsque l’application est écrite ; ils sont plus simples à implémenter que les instructions construites au moment de l’exécution ; et simplifient l’application.

L’utilisation des paramètres d’instruction et la préparation des instructions offrent encore de meilleures façons d’utiliser des instructions SQL codées en dur. Par exemple, supposons que la table Parties contient les colonnes PartID, Description et Price. Une façon d’insérer une nouvelle ligne dans cette table consiste à construire et à exécuter une instruction INSERT :

#define DESC_LEN 51  
#define STATEMENT_LEN 51  
  
SQLUINTEGER   PartID;  
SQLCHAR       Desc[DESC_LEN], Statement[STATEMENT_LEN];  
SQLREAL       Price;  
  
// Set part ID, description, and price.  
GetNewValues(&PartID, Desc, &Price);  
  
// Build INSERT statement.  
sprintf_s(Statement, 100, "INSERT INTO Parts (PartID, Description,  Price) "  
         "VALUES (%d, '%s', %f)", PartID, Desc, Price);  
  
// Execute the statement.  
SQLExecDirect(hstmt, Statement, SQL_NTS);  

Une meilleure façon d’utiliser une instruction codée en dur et paramétrable. Cela présente deux avantages par rapport à une instruction avec des valeurs de données codées en dur. Tout d’abord, il est plus facile de construire une instruction paramétrable, car les valeurs de données peuvent être envoyées dans leurs types natifs, tels que les entiers et les nombres à virgule flottante, plutôt que de les convertir en chaînes. Deuxièmement, une telle instruction peut être utilisée plusieurs fois simplement en modifiant les valeurs de paramètre et en la réexécutant ; il n’est pas nécessaire de le reconstruire.

#define DESC_LEN 51  
  
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description,  Price) "  
         "VALUES (?, ?, ?)";  
SQLUINTEGER   PartID;  
SQLCHAR       Desc[DESC_LEN];  
SQLREAL       Price;  
SQLINTEGER    PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;  
  
// Bind the parameters.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
                  &PartID, 0, &PartIDInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,  
                  Desc, sizeof(Desc), &DescLenOrInd);  
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
  
// Set part ID, description, and price.  
GetNewValues(&PartID, Desc, &Price);  
  
// Execute the statement.  
SQLExecDirect(hstmt, Statement, SQL_NTS);  

En supposant que cette instruction soit exécutée plusieurs fois, elle peut être préparée pour une efficacité encore plus élevée :

#define DESC_LEN 51  
  
SQLCHAR *Statement = "INSERT INTO Parts (PartID, Description,  Price) "  
         "VALUES (?, ?, ?)";  
SQLUINTEGER   PartID;  
SQLCHAR       Desc[DESC_LEN];  
SQLREAL       Price;  
SQLINTEGER    PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;  
  
// Prepare the INSERT statement.  
SQLPrepare(hstmt, Statement, SQL_NTS);  
  
// Bind the parameters.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
                  &PartID, 0, &PartIDInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,  
                  Desc, sizeof(Desc), &DescLenOrInd);  
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
  
// Loop to continually get new values and insert them.  
while (GetNewValues(&PartID, Desc, &Price))  
   SQLExecute(hstmt);  

La façon la plus efficace d’utiliser l’instruction consiste peut-être à construire une procédure contenant l’instruction, comme illustré dans l’exemple de code suivant. Étant donné que la procédure est construite au moment du développement et stockée sur la source de données, elle n’a pas besoin d’être préparée au moment de l’exécution. L’inconvénient de cette méthode est que la syntaxe de création de procédures est spécifique au SGBD et que les procédures doivent être construites séparément pour chaque SGBD sur lequel l’application doit s’exécuter.

#define DESC_LEN 51  
  
SQLUINTEGER   PartID;  
SQLCHAR       Desc[DESC_LEN];  
SQLREAL       Price;  
SQLINTEGER    PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;  
  
// Bind the parameters.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
                  &PartID, 0, &PartIDInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,  
                  Desc, sizeof(Desc), &DescLenOrInd);  
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
  
// Loop to continually get new values and insert them.  
while (GetNewValues(&PartID, Desc, &Price))  
   SQLExecDirect(hstmt, "{call InsertPart(?, ?, ?)}", SQL_NTS);  

Pour plus d’informations sur les paramètres, les instructions préparées et les procédures, consultez Exécution d’une instruction.