Výpis z databázy - algoritmus (rekurze?)   zodpovězená otázka

C#, SQL

Dobrý deň.

Mám nižšie uvedenú tabuľku nodesTbl v databaze Sql Ce Compact. Hľadám šikovný algoritmus na výpis všetkých myTag-ov deti, vnúčat, pravnúčat... a priradenie do premenných A(1) až A(n) pre zadaný myTag.

Pre uvedený príklad pre zadaný myTag = 2 by to bolo 2, 3, 4, 7, 8


myTag node parentTag
1     node1     0 
2     node2     0
3     node21    2
4     node211   3
5     node11    1
6     node12    1
7     node22    2
8     node212   3 
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokud by Sql Ce uměl CTE (nevím jestli novější verze ho už náhodou neumí - vyzkoušejte), bylo by to jednoduché:

WITH NodesClosureCTE (parentTag, myTag)
AS
(
	SELECT myTag AS parentTag, myTag
	  FROM nodesTbl
    UNION ALL
	SELECT NodesClosureCTE.parentTag, nodesTbl.myTag
	  FROM nodesTbl INNER JOIN
		   NodesClosureCTE ON NodesClosureCTE.myTag = nodesTbl.parentTag
)
SELECT NodesClosureCTE.myTag, nodesTbl.node
  FROM NodesClosureCTE INNER JOIN
	   nodesTbl ON nodesTbl.myTag = NodesClosureCTE.myTag
 WHERE NodesClosureCTE.parentTag = 2
 ORDER BY NodesClosureCTE.myTag

Výstup:

myTag   node
-----   ----
2	node2
3	node21
4	node211
7	node22
8	node212

Pokud SQL Ce CTE nepodporuje, tak to přímo v SQL nepůjde. Budete to muset řešit až na klientu v C#.

Jedna varianta by mohla být postupně načítat nové child uzly a "closure" budovat v paměti tj.

1) Uzel 2 přidáte do výsledků pokud víte, že existuje. Jinak jeho existenci nejprve ověříte SQL dotazem:

SELECT myTag FROM nodesTbl WHERE myTag = 2

2) Načtete pořízené uzly pro hodnoty uzlů získané v předchozím kroku - nyní na začátku pouze pro uzel 2 - SQL dotazem:

SELECT myTag FROM nodesTbl WHERE parentTag IN (2)

(Vrací 3,7)

Získané hodnoty (3,7) si zapamatujete a také je (nezávisle na "zapamatování") přidáte do výsledků.

3) Opakujete krok 2 pro nově získané hodnoty v předchozím kroku:

SELECT myTag FROM nodesTbl WHERE parentTag IN (3,7)

(Vrací 4,8)

Získané hodnoty (4,8) si opět zapamatujete a přidáte do výsledků.

4) Opět opakujete krok 2 pro nové hodnoty:

SELECT myTag FROM nodesTbl WHERE parentTag IN (4,8)

(Nevrací nic)

Protože tento dotaz již nic nevrátil, algoritmus končí.

Ve výsledku je 2,3,7,4,8

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Máte pravdu pán Holan. SqlCe CTE nemá ani neviem čo to je. Ale tá druhá cesta je super, len sa s tým musím ešte popasovať. Prvé výsledky už mám. Ďakujem veľmi pekne. Príjemný večer!

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tu je výsledný kód.

Ešte raz ďakujem za slovíčko "IN".

 int[] vymazTag = new int[100];
 int vymazIndex = 1;

 vymazTag[0] = 2;                        
 string myNodes = "2";

 znova:
     SqlCeCommand cmdVymazat = new SqlCeCommand("SELECT myTag FROM tblNodes WHERE parentTag IN   (" + myNodes + ")", con); 
                        
     cmdVymazat.Connection.Open();
     SqlCeDataReader rdr = null;

   try
   {
     myNodes = "";
     rdr = cmdVymazat.ExecuteReader(CommandBehavior.CloseConnection);

     while (rdr.Read())
      {
        myTag = rdr.GetInt32(0);                                   
        vymazTag[vymazIndex] = myTag;
        myNodes = myNodes + "," + myTag;
        vymazIndex++;
      }

     if (myNodes.Length > 1)           
      {
        myNodes = myNodes.Substring(1);
        goto znova;
      }
    }
   finally
    {
      rdr.Close();
    }
                        
nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback