Sdílet prostřednictvím


Hard-Coded příkazy SQL

Aplikace, které provádějí pevnou úlohu, obvykle obsahují pevně zakódované příkazy SQL. Například systém zadávání objednávek může použít následující volání k zobrazení seznamu otevřených prodejních objednávek:

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

Existuje několik výhod pro pevně zakódované příkazy SQL: Je možné je otestovat při zápisu aplikace; jsou jednodušší implementovat než příkazy vytvořené za běhu; a zjednodušují aplikaci.

Použití parametrů příkazů a příprava příkazů poskytují ještě lepší způsoby použití pevně zakódovaných příkazů SQL. Předpokládejme například, že tabulka Parts obsahuje sloupce PartID, Description a Price. Jedním ze způsobů, jak vložit nový řádek do této tabulky, je vytvořit a spustit příkaz 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);  

Ještě lepší způsob je použít pevně zakódovaný parametrizovaný příkaz. To má dvě výhody oproti příkazu s pevně zakódovanými datovými hodnotami. Za prvé je jednodušší vytvořit parametrizovaný příkaz, protože datové hodnoty lze odesílat v jejich nativních typech, jako jsou celá čísla a čísla s plovoucí desetinnou čárkou, a ne je převádět na řetězce. Za druhé, takový příkaz lze použít více než jednou jednoduše změnou hodnot parametrů a opětovným provedením; není potřeba ho znovu sestavit.

#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);  

Za předpokladu, že se má tento příkaz spustit více než jednou, je možné ho připravit na ještě větší efektivitu:

#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);  

Možná nejúčinnější způsob, jak použít příkaz, je vytvořit proceduru obsahující příkaz, jak je znázorněno v následujícím příkladu kódu. Vzhledem k tomu, že je procedura vytvořena v době vývoje a uložena ve zdroji dat, nemusí být připravena za běhu. Nevýhodou této metody je, že syntaxe pro vytváření procedur je specifická pro DBMS a procedury musí být sestaveny samostatně pro každý DBMS, na kterém se má aplikace spouštět.

#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);  

Další informace o parametrech, připravených příkazech a postupech naleznete v tématu Provádění příkazu.