C# SQL Databáze - INNER JOIN – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C# SQL Databáze - INNER JOIN – .NET – Fórum – Programujte.comC# SQL Databáze - INNER JOIN – .NET – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Learnt0
Newbie
7. 9. 2021   #1
-
0
-

Potřeboval bych poradit, respektive něco zkontrolovat.

Mám propojenou databázi SQL v C#

Mám tyto 3 tabulky.. viz. příloha

Připojen obrázek.

Připojen obrázek.

Připojen obrázek.

pomocí tabulky OosbaMesto mám propojené tabulky Oosba a Město mezi sebou.

Problém je v tom, že když se snaží udělat INNER JOIN dotaz ve WFA aplikaci, tak mi to vždy hodí tento error a program se ani nespustí a nechápu proč.

Připojen obrázek.

Můj kod i s tím dotazem.. dotaz je načten ve "string query"

        private void Mestecka()
        {
            string query = "SELECT a.Nazev FROM Mesto a " + 
                "INNER JOIN OosbaMesto b ON a.Id = b.MestoId" + 
                "WHERE b.OosbaId = @OosbaId";

            using (connection = new SqlConnection(connectionString))
            using (SqlCommand commnad = new SqlCommand(query, connection))
            using (SqlDataAdapter adapter = new SqlDataAdapter(commnad))
            {
                commnad.Parameters.AddWithValue("@OosbaId", OsobaListBox.SelectedValue);

                DataTable MestoTable = new DataTable();
                adapter.Fill(MestoTable);

                MestoLiistBox.DisplayMember = "Nazev";
                MestoLiistBox.ValueMember = "Id";
                MestoLiistBox.DataSource = MestoTable;
            }
        }

Když ten stejný query zkusím udělat normálně v Microsoft SQL, tak mi to najde co potřebuji jediné co, tak tam na konci nepoužíji: WHERE b.OosbaId = @OosbaId... ale WHERE b.OosbaId = 1 (aby se to rovnalo Id co chci zrovna najít.

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:ad21:1c4e:8357:12a...–
7. 9. 2021   #2
-
0
-

Podíval bych se jakého datového typu je SelectedValue u ListBoxu, tuším, že string. Moc jsem se nedíval, ale tuším, že v tabulkách v databázi id je int.

Zkrátka zkontrolovat a dodržovat datové typy.

hu

Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:6103:4694:b8b3:a622...–
Learnt0
Newbie
7. 9. 2021   #3
-
0
-

#2 hlucheucho
No to ano, Id mám inty, jako string to ani dát nejde.

Takže to mám convertovat na Int32 to OsobaListBox?

Pokud ano, tak jsem to upravil takto a stále stejná chyba.

commnad.Parameters.AddWithValue("@OosbaId", Convert.ToInt32(OsobaListBox.SelectedValue));
Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:a410:caf9:279c:9c9a...–
gna
~ Anonymní uživatel
1485 příspěvků
7. 9. 2021   #4
-
+1
-
Zajímavé

Mezi b.MestoId a WHERE nemáš mezeru.

Nahlásit jako SPAM
IP: 213.211.51.–
Learnt0
Newbie
7. 9. 2021   #5
-
0
-

#4 gna
Děkuji moc toho jsem si vůbec nevšiml a bylo to ono... už mi to vypisuje...

jen jsem myslel, že když pak kliknu na jiné jméno, než je to první, tak mi to vypíše při každém kliku na další jménoi jiné města... ale prostě se to spustí a zůstane tam ten první údaj z prvního jména i když vyberu jiné jméno, tak žádný update... :/ alespoň jsem tak myslel, že funguje SelectedValue po kliku  

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:75ce:89e6:b471:b972...–
gna
~ Anonymní uživatel
1485 příspěvků
7. 9. 2021   #6
-
+1
-
Zajímavé

#5 Learnt
To zni, jako bys čekal, že to nějak definuje vazbu s tím ListBoxem. Ne, to je řada příkazů, které se provedou a hotovo.

Pokud při změně výběru chceš něco provést, tak můžeš definovat funkci, která se při té události spustí.

Podle dokumentace má ListBox události SelectedIndexChanged a SelectedValueChanged. Na to by to mělo jít napíchnout.

Nahlásit jako SPAM
IP: 213.211.51.–
Learnt0
Newbie
9. 9. 2021   #7
-
0
-

#6 gna

Ahoj, tak jsem to vše udělal a doplnil, ten SelectedIndex pomohl děkuji.. Pak jsem si tam přidal několik dalších věcí. Mám hotovo, ale trápí mě jedna taková, jakoby chyba kterou bych chtěl nějak ošetřit.

Pomocí spojovací tabulky "OosbaMesto" screeny k tomu jsou nahoře k těm tabulkám... tak mám funkci na přidání vybrané osoby do vybraného města kam chci osobu přidat, vše funguje... ale chtěl bych nějak ošetřit to, abych nemohl tu jednu osobu, kterou si vyberu přidat do toho města dvakrát. Zkoušel jsem to pomocí klasicky if else

if(!MestoLiistBox.Items.Contains(OsobaListBox.SelectedValue))

ale vůbec to nedělá co má, trochu jsem se v tom zamotal. Nenapadá tě co bych tam měl změnit  ?

Toto je celý kód toho úseku

        private void PridatOsobuButton_Click(object sender, EventArgs e)
        {
            if(!MestoLiistBox.Items.Contains(OsobaListBox.SelectedValue))
            {
                string query = "INSERT INTO OosbaMesto VALUES (@MestoId, @OosbaId)";

                using (connection = new SqlConnection(connectionString))
                using (SqlCommand commnad = new SqlCommand(query, connection))
                {
                    connection.Open();

                    commnad.Parameters.AddWithValue("@MestoId", MestoListBoxAll.SelectedValue);
                    commnad.Parameters.AddWithValue("@OosbaId", OsobaListBox.SelectedValue);

                    commnad.ExecuteScalar();
                }
            }
            else
            {
                MessageBox.Show("Tato osoba se už ve městě nachází");
            }     
        
            AllMestecka();
            Osubky();
        }

Přidávám obráky a v jenom je vidět ta chyba... v "Lidi z Města" mám dvakrát "Alžbeta", kterou jsem si vybral z listboxu "Osoba"...

Připojen obrázek.

Připojen obrázek.

Moc děkuji

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
gna
~ Anonymní uživatel
1485 příspěvků
9. 9. 2021   #8
-
0
-

Nevím, jak funguje ten .Contains (resp. co je tam za objekty a jak implementují .Equals).

Zkusil bych SelectedItem místo SelectedValue.

Nahlásit jako SPAM
IP: 213.211.51.–
Learnt0
Newbie
9. 9. 2021   #9
-
0
-

#8 gna
Tak jsem zjistil, že když to mám takto:

if(!MestoLiistBox.SelectedIndex.Equals(OsobaListBox.SelectedIndex))

Tak to funguje, ale použe tehdy, když mám vybrané stejné indexy v obouch tabulkách.

Jenomže... Nemohu vybrat něco jako "Index" samotný, ale jediná možnost je SelectedIndex, což je mi tak trochu na prd  .

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
gna
~ Anonymní uživatel
1485 příspěvků
9. 9. 2021   #10
-
0
-

A to SelectedItem jsi zkusil?

Nahlásit jako SPAM
IP: 213.211.51.–
Learnt0
Newbie
9. 9. 2021   #11
-
0
-

#10 gna
Zkoušel neúspěšně.. tam je podle mě problém ten začátek... if(MestoLiistBox.SelectedIndex.......

To by chtělo dát něco jako Jakýkoliv index v tom listoboxu a né jen ten co nakliknu..

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
gna
~ Anonymní uživatel
1485 příspěvků
9. 9. 2021   #12
-
0
-

Index tě vůbec nezajímá. Na to už jsi přišel, že je pořadové číslo položky. Jde o to co dát toho .Contains.

PrvniListbox.Items.Contains(DruhyListbox.SelectedItem)

V Items hledat Item by dávalo smysl, ale nevím jak to funguje. Jinak samozřejmě můžeš ty položky projít a porovnat sám, jak chceš.

Nahlásit jako SPAM
IP: 213.211.51.–
gna
~ Anonymní uživatel
1485 příspěvků
9. 9. 2021   #13
-
0
-

Tak jsem se tím trochu prokousal a ty položky asi budou typu DataRow, který nedefinuje .Equals, takže je asi budeš must porovnat sám. Nebo třeba v databázi definovat constraint na unikátnost.

Nahlásit jako SPAM
IP: 213.211.51.–
10. 9. 2021   #14
-
0
-
Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:3d67:9c4e:7200:dddf...–
10. 9. 2021   #15
-
0
-

Pokud jde o to aby v získané sadě záznamů nebyly duplicity, použij seskupování. Pokud mají být záznamy v tabulce unikátní pak:

1. zkusil bych toho dosáhnout pomocí nastavení příslušných sloupců tabulky jako unikátní
2. Pokud se jedná o nějakou kombinaci sloupců, zkusil bych z nich vytvořit řetězec a ten ukládat do dalšího, unikátního sloupce. Jde na to použít autogenerated column nebo
3. Zjistil bych, jestli je mnou vkládaný záznam unikátní tak, že bych zjistil počet kolidujících záznamů pomocí COUNT(). Pokud je unikátní,  COUNT() vrátí 0, vložil bych ho. Prováděl bych to uvnitř transakce nebo before insert triggeru.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Learnt0
Newbie
10. 9. 2021   #16
-
0
-

Tak jsem našel jednodušší způsob pomocí SQL dotazu v programu.

        private void Mestecka()
        {
            string query = "SELECT DISTINCT a.Jmeno FROM Oosba a " +
                "INNER JOIN OosbaMesto b ON a.Id = b.OosbaId " +
                "WHERE b.MestoId = @MestoId";

            using (connection = new SqlConnection(connectionString))
            using (SqlCommand commnad = new SqlCommand(query, connection))
            using (SqlDataAdapter adapter = new SqlDataAdapter(commnad))
            {
                commnad.Parameters.AddWithValue("@MestoId", MestoListBoxAll.SelectedValue);

                DataTable OosbaTable = new DataTable();
                adapter.Fill(OosbaTable);

                MestoLiistBox.DisplayMember = "Jmeno";
                MestoLiistBox.ValueMember = "Id";
                MestoLiistBox.DataSource = OosbaTable;
                
            }
        }

Přidal jsem hned za SELECT ve string query DISTINCT... který funguje, tak že odmaže automaticky duplikovanou hodnotu a.Jmeno v ListBoxu... takže takto to bude asi v pohodě.

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
10. 9. 2021   #17
-
0
-

Select distinct nezabrání duplicitě v tabulce samotné, pouze duplicitu odstraní ve výsledném recordsetu.

Pokud chci, aby do sloupce tabulky nešla vložit duplictní hodnota, nastavím sloupec tabulky jako unikátní v definici tabulky ať při jejím vytváření nebo její změně.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Learnt0
Newbie
10. 9. 2021   #18
-
0
-

#17 hlucheucho
Když ale nastavím celý sloupec jako unikátní hodnotu, tak ta osoba půjde dát jen do jednoho města a konec.

Jde v tom nějak nastavit, aby byli unikátní oba sloupce jen když se spolu ty dvě stejné ID setkají?

Něco jako:

CONSTRAINT VyjimkaOsobaMesto UNIQUE (OosbaId, MestoId) WHEN Combination

To jsem jen tak plácnul, aby bylo vidět (snad) co mám na mysli.

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
10. 9. 2021   #19
-
0
-

Viz bod 2. v #15. Z obsahu obou sloupců udělat řetězec, např. Ostrava  a Jenda složíš dohromady jako "OstravaJenda" a vkládáš do pomocného sloupce tabulky. DB to může dělat sama, hledej autogenerated column. A ten uděláš unikátní. A pak může být vložen jen jeden Jenda v Ostravě. Nebo podle bodu 3 zjistit, kolik existuje záznamů s daty Ostrava a Jenda a pokud neexistuje žádný, tak pak bude právě vložený záznam unikátní.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Learnt0
Newbie
10. 9. 2021   #20
-
0
-

#19 hlucheucho
Tak nakonec jde udělat v SQL kombinace

fungovalo toto a záznamy tam nezůstávají.

 CONSTRAINT [VyjimkaOsobaMesto] UNIQUE NONCLUSTERED ([OosbaId] ASC, [MestoId] ASC),

Tak teď už by to mělo být snad ok  .

S tím sloupcem by to šlo určitě taky, ale toto možná je snažší.

Díky

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
10. 9. 2021   #21
-
0
-

V dotazu? V jakém? Nebo v definici tabulky?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Learnt0
Newbie
11. 9. 2021   #22
-
0
-

Zapomněl jsem zmínit, myslel jsem přímo v definici tabulky.

Nahlásit jako SPAM
IP: 2a00:1028:8396:16f2:10d7:5b70:ee48:b9e3...–
Zjistit počet nových příspěvků

Přidej příspěvek

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 66 hostů

Podobná vlákna

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032021 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý