Zabránění vložení duplicitního záznamu do databáze   zodpovězená otázka

ASP.NET WebForms, Databáze

Zdravím, potřeboval bych poradit s konkrétním problémem.

V aplikaci mám skupiny, a do skupin přidávám jednotlivé členy. Ale nevím, jak zabránit tomu, aby nebyl jeden uživatel ve skupině víckrát.

V databázi mám tabulku GROUPS, USERS a GROUPMEMBERS. Když se uživatel přidává do skupiny, do tabulky GROUPMEMBERS se uloží hodnoty GroupMemberId (primární klíč), GroupId a UserName.

Budu rád za jakoukoliv odpověď.

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

Od toho slouží právě Primární Klíče,jakmile se pak pokusíte vložit záznam,který koliduje s již existujícím,co se týče sloupců označených jako PK,tak Vám DB server vrátí chybu a záznam se samozřejmě nevloží

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

Ano, ale já potřebuji kontrolovat takto: uživatel může být v tabulce vícekrát, ale ne ve stejné skupině. Když jsem dal primární klíč na sloupec UserName, nemohl jsem ho do tabulky vložit ani do jiné skupiny.

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

Udělejte jako PK kombinaci klíču UserId,GroupID

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

Ale v tabulce jde přece použít jenom jeden PK, pokud vím.

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

Netuším,kde jste to slyšel,ale pokud já vím a co já používám,tak jde:

CREATE TABLE xx (
...
...
PRIMARY KEY(Column1,Column2,..)
);

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

Ano, máte pravdu. Nevěděl jsem to. Děkuji Vám za odpověď, takhle to vyvolá chybovou stránku, jak má.

Teď se ještě zeptám, jak mám tuto chybu zachytit. V jaké události v kódu?

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

Nevím jestli je to ve webových aplikacích jinak, ale nejspíš stejně. Žádná událost nenastane, je potřeba zachytit a ošetřit konkrétní vyjímku a tu potom nějak prezentovat uživateli. Pokud k vyjímce dojde, odvolat transakci, pokud ne, potvrdit transakci (za předpokladu, že databázové operace máte v transakcích).

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

Aha

Můžete mi prosím ukázat, jak to použít v kódu?

Je mi jasné, že tam bude podmínka: pokud nastane tato chyba, zobraz chybovou hlášku.

Ale protože v oblasti programování nejsem zdatný, tak bohužel nevím jak se tato konkrétní chyba nazývá a jak to použít v kódu.

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

Klasicky Try...Catch...Finally. Chytat se bude SqlException.

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

Ještě se naposled poprosím o radu.

Ošetřuju to v události OnInserting komponenty SqlDataSource. Hledal jsem si na internetu kód, jak to ošetřit, ale ani v jednom případě mi to vyvolanou chybu neošetřilo.

Protected Sub SqlDataSource3_Inserting(sender As Object, e As SqlDataSourceCommandEventArgs)
        Try
        Catch ex As SqlException
           
        End Try
 End Sub
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ještě se naposled poprosím o radu.

Ošetřuju to v události OnInserting komponenty SqlDataSource. Hledal jsem si na internetu kód, jak to ošetřit, ale ani v jednom případě mi to vyvolanou chybu neošetřilo.

Protected Sub SqlDataSource3_Inserting(sender As Object, e As SqlDataSourceCommandEventArgs)
        Try
        Catch ex As SqlException
           
        End Try
 End Sub
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ještě se naposled poprosím o radu.

Ošetřuju to v události OnInserting komponenty SqlDataSource. Hledal jsem si na internetu kód, jak to ošetřit, ale ani v jednom případě mi to vyvolanou chybu neošetřilo.

Protected Sub SqlDataSource3_Inserting(sender As Object, e As SqlDataSourceCommandEventArgs)
        Try
        Catch ex As SqlException
           
        End Try
 End Sub

Můžete mi prosím napsat, co mám napsat do tohoto kódu?

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

Naučte se základy,bez nich se neobejdete.

Těžko tuto chybu nějak ošetříte,vy můžete jen reagovat na její vyvolání - např. zobrazit chybu,uložit chybu do log souboru,prostě co chcete a potřebujete.

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

Vytvářet a následně zachycovat vzniklé chyby? To je blbost. Vyřešte to přímo na SQL serveru a vracejte si například nějaký status ano/ne. Například uloženou procedurou.

nahlásit spamnahlásit spam -5 / 5 odpovědětodpovědět

Netuším,co je na tom za blbost - leda v případě,že by byla potřeba odchytávat velká množina různých chyb. Ale v tomto případě stačí reagovat na úzký okruh možných chyb. Obecně můžete zachytit SqlException a tu interpretovat,nebo si v rámci ladění odchyťte chybu při vložení duplicitního záznamu a exception pak implementujte ve svém projektu

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

Kdo říká vytvářet?! Stačí zachytit jedinou konkrétní vyjímku na předpokládaném místě výskytu. Vaše řešení je blbost, protože např. nebude k dispozici chybová zpráva, takže se dozvíte pouze že ne, ale proč už ne.

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

Tomu říkáte správné řešení? Stačí přece udělat jednoduchý dotaz do databáze, který vrátí hodnotu zda záznam vložit nebo nevložit. Triviální věc, vím všechno a bez výjimek.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

To je samo o sobě špatně,budete mít poté business vrstvu závislou i na databázové vrstvě,tím pádem jakákoliv změna,bude znamenat změnu na několika místech.Dalším faktorem proti,dle mého,je,že takto by se ošetřil pouze jeden stav(jedna možná SqlException),ale co když nastane jiná? Vy byste snad nechal aplikaci "spadnout" kvůli tomu,že se Vám nechce implementovat standardní OOP postupy? Pak si představte situaci,kdy takovýchto "kontrol" potřebujete udělat několik desítek(stovek,tisíců,..),to budete mít na DBS tolik procedur? Vím,že se tazatel ptal na jednu určitou věc,ale přijde při nejmenším nefér,poradit mu tak,že se vydá pouze špatným směrem. Takto si už od začátku osvojí "standardní" programátorské postupy. Důvodů je samozřejmě mnohem a mnohem více.

Samozřejmě neříkám,že je exaktně nutné podobné situace řešit v rámci aplikace,záleží na situaci. V tomto případě se však přikláním k aplikačnímu řešení

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
 Protected Sub SqlDataSource3_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs)
        If e.Exception IsNot Nothing Then
            Response.Redirect(ResolveClientUrl("~/Default.aspx"))
            
            e.ExceptionHandled = True
        End If
End Sub

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

Tohle ale není řešení. Pouze při stavu,kdy není vrácena chyba přesměrujete uživatele na požadovanou stránku.Ale co,když se vloží duplicitní záznam? Je potřeba ošetřit tuto část,jak jsem alespon ze zadání pochopil.Výše uvedený kód nic z toho neřeší

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

Použijte kečovací blok v místě, kde se vkládají data do databáze.

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