Update zaznamu rodicovskej tabulky pri zmene podriadenej tabulky   otázka

ASP.NET WebForms, SQL, Databáze

Ahoj všetci,

potrebujem poradit s takym cudnym spravanim SQL procedury.

Mam dve tabulky master a detail. (Pre jeden zaznam master tabulky je viac zaznamov detail tabulky prepojene cez Id master tabulky)

Na tej istej stranke mam formview (napojeny na sql datasource master tabulky) kde sa da editovat jeden zaznam filtrovany cez QueryStringField="Cislo" master tabulky aj gridview (napojeny na sql datasource detail tabulky) kde sa daju editovat (pridat, editovat, zmazat) vsetky zaznamy podradenej tabulky taktiez filtrovane cez QueryStringField="Cislo".

Potrebujem vzdy pri akejkolvek zmene podradenej tabulky zapisat do nadradenej tabulky kto a kedy to zmenil.

Robim to jednoducho tak ze ulozenym proceduram pre insert, update a delete pre podradenu tabulku na MS SQL serveri podsuniem hodnoty zakladneho Id záznamu master z QueryStringField="Cislo" a usera a atualny datetime.

   protected void FormView2_ItemInserting(object sender, FormViewInsertEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.Values["PrislusnikId"] = Request.QueryString["Cislo"];
        e.Values["ZmenDna"] = DateTime.Now;
        e.Values["Zmenil"] = user.UserName;

    }
    protected void GridView2_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.NewValues["PrislusnikId"] = Request.QueryString["Cislo"];
        e.NewValues["ZmenDna"] = DateTime.Now;
        e.NewValues["Zmenil"] = user.UserName;
    }
    protected void GridView2_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.Values["PrislusnikId"] = Request.QueryString["Cislo"];
        e.Values["ZmenDna"] = DateTime.Now;
        e.Values["Zmenil"] = user.UserName;
    }

Vsade to normalne funguje len pri mazani zaznamu to z nepochopilneho dovodu ani nezmaze zaznam podradenej tabulky ani neupdatne master tabulku.

Prikladam aj kod ulozenej procedury pre delete podradeného záznamu.

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ZmazOdbPrisl] 
	@PrislusnikId int,
	@OdbPrislId int,
	@Zmenil nvarchar(50),
	@ZmenDna datetime
AS
BEGIN
	DELETE FROM [OdbPrislusnika] WHERE [OdbPrislId] = @OdbPrislId

	UPDATE Prislusnici SET	Zmenil= @Zmenil, ZmenDna=@ZmenDna
		WHERE PrislusniciId = @PrislusnikId		

END

Dakujem za pomoc.

Ak treba mozem poslat aj kod SQL datasoure ale je vskutku jednoduchy a myslim ze je ok.

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

Dobrý den, doufám že jsem to dobře pochopil. Máte 2 tabulky které jsou spolu v relaci. V první jsou halvní údaje a ve druhé detail (analogie seznam výrobců - jejich produkty) přičemž každý detail váže pouze k jednomu záznamu v první tabulce, ale každý záznam v první tabulce může mít více detailů.

A Váš problém spočívá v tom, že když se pokusíte změnit nebo smazat záznam v první tabulce, tak se akce neprovede...

Pokud tomu je tak, pes by možná mohl být zakopaný právě ve způsobu nastavení relace mezi tabulkama (ujistit se můžete tak, že odchytíte chybu kterou Vám SQL server vrací při spuštění výše uvedených procedur). Když se podíváte do nastavení relace na položku INSERT And UPDATE specification defaultně tam jsou nastaveny hodnoty No Action To proto aby se nemohlo stát že vymažete záznamy v první tabulce, ale v té druhé zůstanou osamocené. Nebudou mít s ničím relaci a zůstanou tam "viset ve vzduchoprázdnu". Vsadím se že pokud zkusíte updatnout nebo smazat položku z první tabulky která nemá na sebe ve druhé tabulce navázaný žádný záznam, vše proběhne korektně. Vyřešit to můžete nastavením výše zmíněné vlastnosti INSERT And UPDATE specification na Cascade (zvlášť pro delete a zvlášť pro update). To bude mít za následek to, že se změny z první tabulky projeví i ve druhé (popř. v dalších pokud by relace šla více do hloubky, ale to není tento případ). Ale pozor, funguje to i u delete, tzn. pokud smažete záznam z první tabulky který má na sebe něco navázáno z druhé tabulky, automaticky dojde i ke smazání všech těchto navázaných záznamů. Na to je potřeba myslet pokud si například potřebujete udržovat nějakou historii apod.

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

Vdaka za reakciu,

moja chyba bola ze som asi zabudol popisat ze tabulky nie sú v databaze relacne spojene. Su prepojene len pomyselne.

Z tabulky master nikdy sa nikdy nebudu mazat zaznamy, len pribudaju, a aj to len nejakym importom . TAkže na tejto tabulke robim len UPDATE. A to funguje OK. Robim len to že ked zmenim niečo v druhej (podradenej) tabulke tak si chcem zapisat do master tabulky pre konkretny zaznam nejake veci, ako som pisal vyssie.

Pri UPDATE a INSERTE to nieje problem. Ale ked robim DELETE zaznamu podradenenej tabulky tak to akoby vobec neurobilo nič.

Daju sa nejako debudovať aj SQL ulozene procedury aby som videl ake parametre boli predane ulozenej procedure a videl co to naozaj urobi?

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

Určitě dají, pokud používáte SQL sever management studio, tak tam bývá řada užitečných nástrojů. Ten který by Vás mohl zajímat je tuším profiler. Zobrazuje dotazy které jsou posílány na server a ukáže Vám i dotaz uvnitř stored procedury s přiřazenýma parametrama.

Ale i přímo v management studiu můžete zkusit spustit stored proceduru s danými parametry a uvidíte jestli procedura v pořádku proběhe, nebo vrátí nějakou chybu.

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

No ono tá sql pocedura je OK aj normálne funguje.

Ale asi to bude jednoduchšie takto.

toto je uložená SQL procedúra

DELETE maže záznam v podradenej tabulke UPDATE upraví hodnoty v master tabulke

...
PROCEDURE [dbo].[ZmazOdbPrisl] 
	-- parameters for the stored procedure here
	@PrislusnikId int,
	@OdbPrislId int,
	@Zmenil nvarchar(50),
	@ZmenDna datetime
AS
BEGIN
	DELETE FROM [OdbPrislusnika] WHERE [OdbPrislId] = @OdbPrislId

	UPDATE Prislusnici SET	Zmenil= @Zmenil, ZmenDna=@ZmenDna
		WHERE PrislusniciId = @PrislusnikId		

END

ktorá je použitá v tomto SQLdatasourse

<moje:RedirectingSqlDataSource ID="sourceOdbornP" runat="server" ConnectionString="<%$ ConnectionStrings:PersonalConnectionString %>" 
 DeleteCommand="ZmazOdbPrisl" DeleteCommandType="StoredProcedure"  
....... >
<DeleteParameters>
 <asp:Parameter Name="PrislusnikId" Type="Int32" />
                <asp:Parameter Name="OdbPrislId" Type="Int32" />
                <asp:Parameter Name="Zmenil" Type="String" />
                <asp:Parameter Name="ZmenDna" Type="DateTime" />
            </DeleteParameters>
....
</moje:RedirectingSqlDataSource>    

Pre jednoduchost som sem dal len sporný delete command. Ostatné ako Select, insert a update sem netreba ani ich parameters lebo funguju OK.

A teraz mam gridview

<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="OdbPrislId" DataSourceID="sourceOdbornP" CellPadding="4" ForeColor="#333333" GridLines="None"        Width="930px" onrowdatabound="GridView2_RowDataBound"         onrowupdating="GridView2_RowUpdating" >
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
 <Columns>
 ...
 

a ešte funkcie ktoré do parametrov procedúr vložia hodnoty nadradeného ID, meno usera a dátum zmeny

    protected void FormView2_ItemInserting(object sender, FormViewInsertEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.Values["PrislusnikId"] = Request.QueryString["Cislo"];
        e.Values["ZmenDna"] = DateTime.Now;
        e.Values["Zmenil"] = user.UserName;

    }
    protected void GridView2_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.NewValues["PrislusnikId"] = Request.QueryString["Cislo"];
        e.NewValues["ZmenDna"] = DateTime.Now;
        e.NewValues["Zmenil"] = user.UserName;
    }
    protected void GridView2_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        MembershipUser user = Membership.GetUser();
        e.Values["PrislusnikId"] = Request.QueryString["Cislo"];
        e.Values["ZmenDna"] = DateTime.Now;
        e.Values["Zmenil"] = user.UserName;
    }

Zatial to funguje normálne dokonca aj sa zmaže z podradenej tabulky záznam. (len sa nezmení v zázname master tabulky meno usera a aktualny čas).

A teraz akonáhle do Gridview2 doplním

...
onrowdeleting="GridView2_RowDeleting" 
...

aby mi to to do tých parametrov získalo meno usera a aktualny čas tak to zblbne. Ani sa nezaže záznam ani neupdatne master tabulka.

Naozas dik Honzo ze zabijaš som mnou čas, ale dufam že sa mi konečne podarilo vysvetliť problém.

Ja viem je to tažké ked sa niečo vytrhne z kontextu a potom to má človek pochopiť.

Dakujem vopred za pomoc.

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

Ozaj zabudol že ten FormView2_ItemInserting za vola z formviewu pod gridom ale to je asi zrejmé.

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

Existuje Profiler aj v Express verzii SQL 2005 ?

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