C# - COMPUTE záradék használata a SELECT-ben

forráskód letöltése
A Transact SQL SELECT utasításában lehetőségünk van a COMPUTE záradék használatára, mely igen hasznosnak bizonyulhat nagyon sok lekérdezés esetében. Ha megpróbálunk egy ilyen lekérdezést futtatni programunkból, akkor viszont egy ”COMPUTE BY statements not supported” hibaüzenetet kapunk. Ennek ellenére azonban nem kell lemondanunk a COMPUTE használatáról, szerencsére van megoldás...
A mellékelt példa futtatása előtt a Form1.cs forráskód 123. sorában lévő connStr változó értékét módosítsa úgy, hogy a Northwind példaadatbázis elérhetővé váljon.
A feladat megvalósításához annyiban kell eltérnünk a hagyományostól, hogy most az OleDb osztályokat kell felhasználnunk és nem az Sql osztályokat. Ennek oka, hogy az SqlCommand nem támogatja jelenleg a COMPUTE záradékot, míg az OleDbCommand igen.
Megnyitjuk tehát az adatbázist az OleDbConnection osztály felhasználásával.
    private void button1_Click(object sender, System.EventArgs e)
    {
      OleDbConnection connection = new OleDbConnection(connStr);
      connection.Open();  
Ezt követően megfogalmazunk egy olyan SELECT lekérdezést, mely visszaadja a Products táblából a ProductName, UnitPrice oszlopokat, rendezve a ProductName értékeire. Mivel a lekérdezéshez hozzátesszük a COMPUTE záradékot, így eredményül nem egy, hanem két adathalmazt kapunk, melyre tekinthetünk úgy mint két különböző típusú és tartalmú DataTable. A COMPUTE záradékban a SUM(UnitPrice) utasítást adjuk meg, melynek eredménye az lesz, hogy a SELECT eredményében szereplő UnitPrice értékei összegezve lesznek. Ezt az egy lekérdezést tulajdonképpen két különböző lekérdezéssel is megvalósíthatnánk, de a COMPUTE előnye itt nyilvánvaló: csak egy lekérdezést kell futtatni.
      OleDbCommand c = new OleDbCommand("SELECT ProductName, UnitPrice FROM Products ORDER BY ProductName COMPUTE SUM(UnitPrice)", connection);
Most futtathatjuk a lekérdezést, melynek eredményeképp egy OleDbDataReader osztályt kapunk, aminek segítségével kiolvashatjuk az eredmény táblákat.
      OleDbDataReader dr = c.ExecuteReader();
Végigmegyünk egy ciklussal az OleDbDataReader-ben lévő adatokon és megjelenítjük azokat egy ListBox-ba.
      while ( dr.Read() )
      {
        s = dr.GetString(0);
        i = dr.GetValue(1);
        listBox1.Items.Add(s +  ": " + i.ToString());
      }
A listázás végén a NextResult függvény hívással váltunk a következő adathalmazra.
      dr.NextResult();
Mivel fenti SELECT-ből adódik, hogy a második eredmény táblának csak egy sora van és azon belül is csak egy oszlop, így nincs szükségünk ciklusra, hanem egyszerűen csak a Read után kiolvassuk a tárolt adatot, mely a UnitPrice oszlop értékeinek összegét adja.
      if (dr.Read())
      {
        label1.Text = "sum: " + dr.GetValue(0).ToString();
      }
      connection.Close();
    }