Skip to the content.

Databáze v C#

GitHub projekt: https://github.com/JindrichDvorak/SQLiteCs-Project.git

Vytvořte metodu PrintDataTable(), která přijme výstup funkce Query(), tedy object typu QueryResult a přehledně jej vykreslí do konzole jako tabulku (nemusí být ohraničená).

    static void PrintDataTable(QueryResult queryResult)
    {
        // Fixed col width for easy formating
        int colW = 20;
        string separator = "|";
        string padding = " ";
        
        string output = separator;


        for (int i = 0; i < queryResult.ColumnCount; i++)
        {
            string th = queryResult.ColumnNames[i] + ": " + queryResult.ColumnDataTypes[i].Name;
            output += PadBoth(th, colW); // ukradnuto z https://stackoverflow.com/questions/17590528/pad-left-pad-right-pad-center-string#17590723
            output += separator;
        }

        int headerLen = output.Length;
        output += "\n";
        // Append horizontal line to separate header
        for (int i = 0; i < headerLen; i++)
        {
            output += "—"; // em–dash (jenom vím jak to napsat na klávesnici, nejsem AI)
        }

        output += "\n";
        
        foreach (var row in queryResult.Rows)
        {
            output += "|";
            foreach (var item in row)
            {
                string itemSafe = item != null ? item.ToString() : nameof(item);
                string td = PadBoth(itemSafe, colW);
                output += td;
                output += separator;
            }

            output += "\n";
        }
        
        Console.WriteLine(output);
    }

Vytvořte metodu PrintQueryResult(), která bude mít stejný výstup jako PrintDataTable(), ale místo objektu typu QueryResult přijímá SQL příkaz ve formě stringu.

V již existující databázi csfd.db (jediná tabulka obsahující 100 nejlépe hodnocených filmů podle ČSFD) určete čistě pomocí SQL „příkazů“ (vypsáním výsledků do konzole):

Database db = new Database("csfd.db");

PrintDataTable(db.Query("SELECT * FROM movies WHERE country LIKE 'Česko%'")); // Technicky vzato Česko jsou tam jenom Pelíšky, ale oni nechtějí jenom Pelíšky, ale i Československo :D
PrintDataTable(db.Query("SELECT *, COUNT(1) FROM movies WHERE country LIKE 'Česko%' ORDER BY rating")); // Pelíšky
PrintDataTable(db.Query("SELECT *, COUNT(1) FROM (SELECT * FROM movies WHERE country LIKE 'Česko%' ORDER BY rating ASC)")); // Byl jednou jeden král... a ano, tohle je divnej postup
PrintDataTable(db.Query("SELECT title, year FROM movies WHERE actors LIKE '%Christian Bale%'")); 
/*
* Temný rytíř	2008
Le Mans '66	2019
Dokonalý trik	2006
*/

Založte novou databázi, ve které následně pomocí SQL „příkazů“ vytvoříte dvě navzájem propojené tabulky (název tabulky: 1. sloupec; … ; N-tý sloupec):

nova.NonQuery(“PRAGMA foreign_keys = ON;”);

nova.NonQuery(“”” CREATE TABLE IF NOT EXISTS autor ( id INTEGER PRIMARY KEY AUTOINCREMENT, jmeno TEXT NOT NULL, rok_narozeni INTEGER ); “””);

nova.NonQuery(“”” CREATE TABLE IF NOT EXISTS kniha ( id INTEGER PRIMARY KEY AUTOINCREMENT, nazev TEXT NOT NULL, id_autor INTEGER NOT NULL, rok_vydani INTEGER, zanr TEXT, FOREIGN KEY (id_autor) REFERENCES autor (id) ON DELETE CASCADE ON UPDATE CASCADE ); “””);


Do nově vzniklé databáze vložte alespoň tři autory, přičemž každému autorovi
přidejte alespoň dvě knihy (můžete se inspirovat seznamem v PDFku).


```csharp
nova.NonQuery("""
                INSERT INTO autor (jmeno, rok_narozeni) VALUES ('J. R. R. Tolkien', 1892);
                INSERT INTO autor (jmeno, rok_narozeni) VALUES ('Daniel Abraham', 1969);
                INSERT INTO autor (jmeno, rok_narozeni) VALUES ('Brandon Sanderson', 1975);
                """);
                
// Zjisti si ID autorů sám :D. Jsem línej to opakovat konstantně
if (idTolkien != -1)
{
    nova.NonQuery($"""
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("The Hobbit")}', {idTolkien}, 1937, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("LotR: The Fellowship of the Ring")}', {idTolkien}, 1954, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("LotR: The Two Towers")}', {idTolkien}, 1954, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("LotR: The Return of the King")}', {idTolkien}, 1955, 'fantasy');
                    """);
}

if (idAbraham != -1)
{
    nova.NonQuery($"""
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Leviathan Wakes")}', {idAbraham}, 2011, 'sci-fi');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Caliban's War")}', {idAbraham}, 2012, 'sci-fi');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Abaddon's Gate")}', {idAbraham}, 2013, 'sci-fi');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Cibola Burn")}', {idAbraham}, 2014, 'sci-fi');
                    """);
}

if (idSanderson != -1)
{
    nova.NonQuery($"""
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("The Way of Kings")}', {idSanderson}, 2010, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Words of Radiance")}', {idSanderson}, 2014, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Oathbringer")}', {idSanderson}, 2017, 'fantasy');
                    INSERT INTO kniha (nazev, id_autor, rok_vydani, zanr) VALUES ('{("Rythm of War")}', {idSanderson}, 2020, 'fantasy');
                    """);
}

V této databázi následně určete čistě pomocí SQL „příkazů“ (vypsáním výsledků do konzole):

// Vypiš všechny údaje z obou tabulek (autor + jeho knihy)
PrintDataTable(nova.Query("""
SELECT a.jmeno AS Autor, k.id AS KnihaId, k.nazev AS Nazev, k.rok_vydani AS RokVydani, k.zanr AS Zanr
FROM autor a
LEFT JOIN kniha k ON k.id_autor = a.id
ORDER BY a.jmeno, k.rok_vydani;
"""));
        
// Vypiš jméno autora a počet knih náležících danému autorovi
PrintDataTable(nova.Query("""
SELECT a.jmeno AS Autor, COUNT(k.id) AS PocetKnih
FROM autor a
LEFT JOIN kniha k ON k.id_autor = a.id
GROUP BY a.id, a.jmeno
ORDER BY a.jmeno;
"""));
        
// Vypiš jméno autora; rok vydání jeho nejstaršího díla; rok vydání jeho nejnovějšího díla
PrintDataTable(nova.Query("""
SELECT a.jmeno AS Autor, MIN(k.rok_vydani) AS NejstarsiRok, MAX(k.rok_vydani) AS NejnovyjsiRok
FROM autor a
LEFT JOIN kniha k ON k.id_autor = a.id
GROUP BY a.id, a.jmeno
ORDER BY a.jmeno;
"""));