[ unisoft @ 12.01.2010. 17:27 ] @
Moze li neko da mi objasni sta se desava u if petlji,mislim na boldirano.
Prvi red mi je jasan ali drugi red kada pozivamo isti proc u kome se nalazimo po meni se cini da se treci red nikada nece izvrsiti ali oce e kada ??? Nikako ne mogu da ukapiram sta se u ova 3 reda desava.Prvi razumem ali nije mi jasno kada se 3 red izvrsava ako se u 2poziva isti proc - meni ovo lici na beskonacnu petlju ???

e da i nikako mi nije jasno kako mi dodeljujemo vrednost @OutWorking kada nigde nema na primer : @OutWorkinng = 2 + 1 ....


Code:
ALTER PROC [dbo].[spTriangular]
    @ValueIn int,
    @ValueOut int OUTPUT
AS
    DECLARE @InWorking int
    DECLARE @OutWorking int
    
    IF @ValueIn != 1
        BEGIN
            [b]SELECT @InWorking = @ValueIn - 1                        -- 1 red
            EXEC spTriangular @InWorking, @OutWorking OUTPUT    -- 2 red
            SELECT @ValueOut = @ValueIn + @OutWorking[/b]        --3 red
        END
    ELSE
        BEGIN
            SELECT @ValueOut = 1
        END
    RETURN


ovaj PROC radi sledece za broj 5 kada izracuna dodeli tu vrednost @ValueOut i u com prozoru @ValueOut ispisuje rezutat.

ako je pri pozivanju PROC-a prosledjena vrednost 5 ovaj proc racuna sledece.

@ValueOut = 5 + 4 + 3 + 2 + 1


Kada u If petlji koristimo BEGIN i END postizemo da se kodovi izmedju izvrsavaju kao jedan blok . E mene bas ovo muci jel citajuci knjige o SQL-u nisam naso dovoljno dobro objasnje , tj primeri su mi malo nejasni pa nisam dobro ovaj deo razumeo. Jel mi sa BEGIN i END postizemo to da posto u 2 redu pozivamo isti PROC prvo se zavrse ostali iskazi(redovi) pa tek se poziva ponovo isti PROC ...

ako je tako zar ne bi trebalo da prvo ide 1 red , 3red , 2red...

Pogledajte sliku ...


[Ovu poruku je menjao unisoft dana 12.01.2010. u 18:38 GMT+1]
[ Fedya @ 12.01.2010. 17:50 ] @
Nije beskonacna petlja, nego vrlo jednostavan primer rekurzije ( http://en.wikipedia.org/wiki/Recursion ). Broj koji se racuna ce se polako smanjivati dok se ne ispuni uslov ( IF @ValueIn != 1 )

znaci otpirlike ovako:

prosledimo 5
proverimo da li je != 1 - jeste
postavimo za novu ulaznu vrednost 5 - 1 = 4
izvrsimo istu proceduru sa brojem 4
saberemo ulaznu i izlaznu vrednost

i tako u krug do jedinice. Mozda nisam dobro objasnio, pogledaj wiki link bice ti jasno.
[ unisoft @ 12.01.2010. 17:56 ] @
Znam ja sta je REKURZIJA.Imam 21god i naslusao sam se ihah matematike.To ovde nije problem nego mene muce sledeca 3 reda koda ...


Code:

            [b]SELECT @InWorking = @ValueIn - 1                        -- 1 red
            EXEC spTriangular @InWorking, @OutWorking OUTPUT    -- 2 red
            SELECT @ValueOut = @ValueIn + @OutWorking[/b]        --3 red



meni nikako nije jasno sledece : posto udjemo u if petlju prvo se vrednost za proveru smanji za 1 ( ako je prosledjen broj 3 ostaje nam samo jos 1 ulazak u TRUE IF petlje - posle ELSE ) ,kada je se zavrsio 1 red koda , izvrsava se 2 red .

Kod mene ovde nastaje problem.Ne mogu da razumem u kom trenutku se izvrsava treci red jer mi sa 2 redom postizemo izvrsavanje PROC ispocetka ... ovo mu dodje nesta kao GO TO ... jer sa trenutnim vrednostima SAM SEBE PONOVO POZIVA.


nadam se da razumes sta me muci ...
[ Fedya @ 12.01.2010. 18:15 ] @
Ako bi prosledio broj tri islo bi otprilike ovako:

1. linija sa brojem 3
2. linija sa brojem 3
1. linija sa brojem 2
2. linija sa brojem 2
1. linija sa brojem 1
2. linija sa brojem 1
- sada je if ispunjen i vracamo 1 i onda se izvrsavaju trece linije prethodnih poziva
3. linija sa brojem 2
3. linija sa brojem 3

tako da ce treca linija uraditi sabiranje 3 + 2 + 1


(EDIT: Pogresio sam inicijalno sam napisao sa se trece linije izvrsavaju u redu 3, 2, 1 ali u stvari je 1, 2, 3
[ unisoft @ 12.01.2010. 18:48 ] @
Izvini ali ja opet ne razumem ...
Code:

  1.red      ALTER PROC [dbo].[spTriangular]
  2.red         @ValueIn int,
  3.red         @ValueOut int OUTPUT
  4.red      AS
  5.red          DECLARE @InWorking int
  6.red          DECLARE @OutWorking int
  7.red    
  8.red    IF @ValueIn != 1
  9.red        BEGIN
10.red            SELECT @InWorking = @ValueIn - 1                        
11.red            EXEC spTriangular @InWorking, @OutWorking OUTPUT    
12.red            SELECT @ValueOut = @ValueIn + @OutWorking      
13.red        END
14.red    ELSE
15.red        BEGIN
16.red           SELECT @ValueOut = 1
17.red        END
18.red    RETURN

Posto ovaj skript izvrsimo - sacuvamo pozivamo ga na sledeci nacin

EXEC spTriangular 5 ili EXECUTE spTriangular 5

e da krenemo

~1 korak ~
1 red do 7 reda se izvrse bez problema i to mi je jasno.

~2 korak~
8red .
Pri pozivu proca mi smo parametru @ValueIn dodeli vrednost 5 ( EXEC spTriangular 5).Proverava se je li ova vrednost jednaka 1,ako nije izvrsi TRUE deo IF-ELSE petlje.Posto 5 nije jednako 1 ulazimo u TRUE

9.red BEGIN
10.red SELECT @InWorking = @ValueIn - 1
11.red EXEC spTriangular @InWorking, @OutWorking OUTPUT
12.red SELECT @ValueOut = @ValueIn + @OutWorking
13.red END

~3 korak~
sada se izvrsava 10.red.Kada predjemo na 11.red parametru @InWorking se dodeljuje vrednost 4.

~4korak~
sada iz pocetka se sve ovo desava.Stigli smo do

11.red EXEC spTriangular @InWorking, @OutWorking OUTPUT

e sada se meni cini da sa ovim se vracamo ponovo na 1.red i tako dalje sve dok @InWorkin ne bude ima vrednost 1.

U svemu ovome kada se izvrsava 12.red !!!OVO MI NIJE JASNO!!!


Zamoli bih te ako mozes da mi bolje objasnis sta se ovde desava.U drugim programskim jezicima poput VBA,VB,C,C++ ove stvari razumem ali ovo programiranje u SQL ( samo ovaj problem ) me muci a inace sama IF-ELSE petlja i druge petlje u SQL su mi jasne kako rade ali me ...








[ Fedya @ 12.01.2010. 19:04 ] @
Znaci idemo od linije 1 do 11 za inicijalnu vrednost pa se prvi poziv procedure stavlja na stack i procedura se poziva prvi put. Zamisli da se izvrsavanje pauziralo u ovom trenutku

zatim linije od 1 do 11 za inicijalnu - 1 i drugi poziv se stavlja na cekanje - pa tako u krug do trenutka kad ulazna vrednost bude 1

kada najzad dodjemo do tacke da je ulazna vrednost = 1 IF uslov se ne zadovoljava i
tada skacemo na liniju 16 i jednostavno vracamo broj 1 ( SELECT @ValueOut = 1 ) znaci sada smo prestali da pozivamo proceduru ponovo, rekurzija se zavrsila.

tada posle (return 1) se vracamo gde smo stali, a to je linija 11 sa ulaznom vrednocu = 1, radimo sabiranje u liniji 12 (SELECT @ValueOut = @ValueIn + @OutWorking) skacemo na return i vracamo broj 2
sada se nastavlja izvrsanje pretposlednjeg poziva ali ide od linije 12 sada sa brojem 2 radimo sabiranje i vracamo 1 + 2 = 3 i tako u krug dok se i poslednji poziv (iliti, prvi poziv - to je onaj sa ulaznom vrednocu koju si prosledio) sa stacka ne izvrsi (svaki put se radi linija 12 i linija 18)


Izvini sto uzasno lose objasnjavam, nikad nisam bio neki nastavnik ;) Ako i dalje ne razumes, mozda se javi neko ko moze bolje od mene da objasni ili jednostavno stavi 'print' na svaku liniju koda i izvrsi proceduru sa brojem 3, sa trojkom je najlakse razumeti.

Takodje jos dve stvari
- IF block nije petlja, petlja kao i ona u saobracaju podrazumeva da se vrtis u krug. znaci FOR, WHILE i slicno su petlje, IF nije
- Rekurzija koju ovde vidimo ce se jednako izvrsiti u bilo kom jeziku ne samo u SQL, probaj kod da prevedes na C#, javu, C++ bilo sta, isto ce se ponasati, a mozda ce ti biti lakse da razumes.
[ Fedya @ 12.01.2010. 19:18 ] @
Znaci ponovo za broj 3:

@InValue = 3 izvrsavaju se linije 1 - 11 tada se radi rekurzija pa idemo
@InValue = 2 linije 1-11 ponovo rekurzija
@InValue = 1 ovde se izvrsavaju samo linije 16 i 18 znaci suvo vracanje broja 1 i nastavljamo stack
@InValue = 2 linija 12 pa 18 posto je prethodni poziv vratio 1 a @inValue = 2 mi radimo sabiranje i vracamo 2 + 1 = 3
@InValue = 3 linija 12 pa 18 posto je prethodni poziv vratio 3 a @InValue = 3 posle sabiranja vracamo 6

i nema vise poziva na stacku, krajnja vrednost je 6.
[ unisoft @ 12.01.2010. 20:39 ] @
Brate moj da te ne lazem.Meni ovo ne ulazi u glavu,pa sta tu mogu.Morace izgleda znanje da prenoci.Lepo sam ovo tvoje PRINTAO na jedan papir i procitao sam barem,min 10 puta i gledao moje i ne kapiram.Veoma dobro znam sta je rekurzija i ovo u drugim programskim jezicima veoma lako programiram ne bi mi trebalo vise od 20sec da napisem program.

Sigurno je problem u tome zato sto se prvi put srecem sa SQL PROGRAMIRANJEM i mozda me ovo BEGIN END zbunjuje.Videcemo kada predjem jos koje poglavlje sta ce se desavati ... mozda mi kasnije postane jasnije.


kada se zavrsi rekurzija, za broj 5

prvi put u 10.redu @InWorking ima vrednost 4 ( 5 - 1) zatim sledi 11.red
EXEC spTriangular 4 ,sledi 1.red (od 1.reda dolazimo ponovo do 1,2,3...10.reda)

drugi put u 10redu @InWorking ima vrednost 3 ( 4 - 1)
EXEC spTriangular 3 ,sledi 1.red (od 1.reda dolazimo ponovo do 1,2,3...10.reda)

treci put u 10redu @InWorking ima vrednost 2 ( 3 - 1)
EXEC spTriangular 2 ,sledi 1.red (od 1.reda dolazimo ponovo do 1,2,3...10.reda)


cetvrti put u 10redu @InWorking ima vrednost 1 ( 2 - 1)
EXEC spTriangular1 KRECEMO OD PRVOG REDA
SADA NAM NIJE ISPUNJEN USLOV TRUE IDEMO NA ELSE -if petlje 16.red

SELECT @ValueOut = 1 posle ovoga idemo na 12.red

peti put u 12.redu SELECT @ValueOut = @ValueIn + @OutWorking
ima vrednost 1 = 5 + sta je sada @OutWorking

!!! E OVDE ZAKOCIM I NE RAZUMEM STA SE DALJE DESAVA GDE GRESIM U RAZMISLJANJU !!!!


U svakom slucaju hvala tebi na utrosenom vremenu :) .





[Ovu poruku je menjao unisoft dana 12.01.2010. u 21:50 GMT+1]
[ sule99 @ 13.01.2010. 10:31 ] @
Ovo je vrlo jednostavno i Fedya ti je to jako lijepo objasnio.
Mislim da je problem sljedeči kod tebe. Kada se izvršavanje koda dođe do 11. reda, ne izlazi se iz IF bloka, nego se unutar njega poziva ta procedura, unutar te novopozvane procedure se opet poziva ista procedura i tako sve dok ne dođemo do broja 1 (isto je kao da si pisao isti kod unutar IF bloka, pa stavio opet jedan IF unutar njega, pa još jedan i tako u nedogled, znači dok se zadnji ne izvrši nemože se predzanji...).

Kada dođemo do broja jedan, program se normalno nastavlja i izlazi prvo iz zadnjeg If bloka u koji je ušao, pa onda ide linija 12 i tako dok ne izađe iz svih IF blokova. Vrlo jednostavno za razumjeti ako se baviš programiranjem.

samo pročitaj još par puta šta je Fedya napisao, sve je super jasno objašnjeno.
[ unisoft @ 13.01.2010. 18:38 ] @
Citat:

Ovo je vrlo jednostavno i Fedya ti je to jako lijepo objasnio.
Mislim da je problem sljedeči kod tebe. Kada se izvršavanje koda dođe do 11. reda, ne izlazi se iz IF bloka, nego se unutar njega poziva ta procedura, unutar te novopozvane procedure se opet poziva ista procedura i tako sve dok ne dođemo do broja 1 (isto je kao da si pisao isti kod unutar IF bloka, pa stavio opet jedan IF unutar njega, pa još jedan i tako u nedogled, znači dok se zadnji ne izvrši nemože se predzanji...).

Kada dođemo do broja jedan, program se normalno nastavlja i izlazi prvo iz zadnjeg If bloka u koji je ušao, pa onda ide linija 12 i tako dok ne izađe iz svih IF blokova. Vrlo jednostavno za razumjeti ako se baviš programiranjem.


Brate moj moram da ti se zahvalim ovo objasnjenje mi je nedostajalo.Sada potpuno razumem sta se desava.Posto si mi reko da unutar IF TRUE pozivamo poonovo istu proceduru ,pravi se novi if unutar njega i 12.red koda se izvrsava unazad ,od najnizg if do naviseg ( sabira ).


Ne bih se sa tobom slozio da JE LAKO ZA RAZUMETI KO SE BAVI PROGRAMIRANJEM .Ja se bavim vec oko 3godine.Znam srednje Csrednje,C++ ucim < ,VBsrednje,VBAsrednje,SQL ucim i ovo me je tako zbunilo.Moze biti zbog toga zato sto sam tek procitao jednu knjigu za SQL,u stvari ostala su mi jos 3 poglavlja da procitam i zavrsavam sa tom knjigom.
Da je napisano sa WHILE petljom ja bi ovo razumeo ali nikako mi nije bilo jasno kako on vise puta sabira a ovo je samo IF .... a IF ELSE nije petlja .


~ imam samo jos jedno pitanje kako dodeljujemo vrednost promenljivoj @OutWorking , nigde u kodu nema na primer @OutWorking = 2 ili sl. Da nije sa RETURN ali posto nema parametara on vraca vrednost IMENU PROCA a ne @OutWorking , sa cime dodeljujemo vrednost ovoj promenljivoj ~

[Ovu poruku je menjao unisoft dana 13.01.2010. u 21:03 GMT+1]
[ unisoft @ 13.01.2010. 18:57 ] @
Da sa ovim stavimo tacku na ovu temu.Posto si mi ti odgovorio SULE99 mnogo mi je jasnije na ovom primeru e sada ako bih naleto na neki primer sa istim problemom da ne bih opet bio u ovoj situaciji da rezimiramo ...

Za broj 3: jel se ovo desava
Code:

ALTER PROC [dbo].[spTriangular]
    @ValueIn int,
    @ValueOut int OUTPUT
AS
    DECLARE @InWorking int
    DECLARE @OutWorking int
    
    IF @ValueIn != 1
        BEGIN
        SELECT @InWorking = @ValueIn - 1     
     IF @ValueIn != 1
                BEGIN
                   SELECT @InWorking = @ValueIn - 1   
                IF @ValueIn != 1
                BEGIN
                    SELECT @InWorking = @ValueIn - 1           
                    SELECT @ValueOut = @ValueIn + @OutWorking     
                END
        ELSE
                BEGIN
                    SELECT @ValueOut = 1
                END
        RETURN        
                    SELECT @ValueOut = @ValueIn + @OutWorking     
                 END
        ELSE
                      BEGIN
                     SELECT @ValueOut = 1
                      END
              RETURN      
        SELECT @ValueOut = @ValueIn + @OutWorking     
        END
    ELSE
            BEGIN
               SELECT @ValueOut = 1
               END
    RETURN



Ako sam pogresio ispravi me !!!.
[ sule99 @ 14.01.2010. 09:35 ] @
evo sada to sve s komentarima i izbačenim viškom koda... koliko vidim da si shvatio i super zbog toga, nadam se da će ti i kod biti jasan zajedno s komentarima. a sto se tiče one varijable @OutWorking deklarira se kroz ključnu riječ OUTPUT i RETURN pa poprima vrijednosti iz funkcije koju pozivaš i koja vraća neke vrijednosti...
Pozz

Code:
ALTER PROC [dbo].[spTriangular]
    @ValueIn int,
    @ValueOut int OUTPUT
AS
    DECLARE @InWorking int
    DECLARE @OutWorking int
    
    IF @ValueIn != 1
        BEGIN
            [b]SELECT @InWorking = @ValueIn - 1                        -- 1 red
            EXEC spTriangular @InWorking, @OutWorking OUTPUT    -- 2 red
            SELECT @ValueOut = @ValueIn + @OutWorking[/b]        --3 red
        END
    ELSE
        BEGIN
            SELECT @ValueOut = 1
        END
    RETURN




--predajemo broj 3 kao ulazni parametar (valueIn = 3)

ALTER PROC [dbo].[spTriangular]
    @ValueIn int,
    @ValueOut int OUTPUT
AS
    DECLARE @InWorking int
    DECLARE @OutWorking int
    
    IF @ValueIn != 1    --a jeste ispunjeno (=3)
        BEGIN
        SELECT @InWorking = @ValueIn - 1 (InWorking je sada = 2)

--tu ti se sada opet pokreće procedura od početka, sa deklaracijom varijabli
--i predaje se u ovom slučaju broj 2(znači sad da ne tipkam i kopiram, tu još
--ide dio s deklaracijom varijabli s početka koda)
      
         IF @ValueIn != 1   --a jeste ispunjeno (=2)
            BEGIN
                    SELECT @InWorking = @ValueIn - 1

--pošto je ulazni parametar 2 opet se izvršava procedura, i tu opet ide još
--deklaracija varijabli i predaje se sada broj 1

--pošto sada if uvjet nije ispunjen skačemo na else blok
   
        ELSE
                BEGIN
                    SELECT @ValueOut = 1 
                END
        RETURN

--sada s ovom vrijednosti se vračamo u if gjde je ulazni parametar bio =2 i nastavljamo s
--linijom koda u IF bloku koja slijedi nakon pozivanja funkcija
         
                    SELECT @ValueOut = @ValueIn + @OutWorking     
                 END
              RETURN

--i sada opet se s ovom vrijednosti vračamo na liniju koda koja ide nakon pozivanja funkcije
--u prvom IF bloku kad smo imali ulazni parametar =3       
        SELECT @ValueOut = @ValueIn + @OutWorking     
        END  
    RETURN

--i onda kad se to izvršava po ovome redu kako sam napisao računa se 1+2+3



[ sule99 @ 14.01.2010. 10:07 ] @
a ovo je cijeli kod (izbačene samo deklaracije na počecima funkcija)



Code:
ALTER PROC [dbo].[spTriangular]
    @ValueIn int,
    @ValueOut int OUTPUT
AS
    DECLARE @InWorking int
    DECLARE @OutWorking int
    
    IF @ValueIn != 1
        BEGIN
        SELECT @InWorking = @ValueIn - 1
        IF @ValueIn != 1
                BEGIN
                SELECT @InWorking = @ValueIn - 1
                IF @ValueIn != 1
                           BEGIN
                        SELECT @InWorking = @ValueIn - 1                       
                                EXEC spTriangular @InWorking, @OutWorking OUTPUT    
                                SELECT @ValueOut = @ValueIn + @OutWorking       
                        END
                    ELSE
                            BEGIN
                                SELECT @ValueOut = 1
                        END
                    RETURN

                        SELECT @ValueOut = @ValueIn + @OutWorking       
                END
            ELSE
                BEGIN
                        SELECT @ValueOut = 1
                END
            RETURN
            
                SELECT @ValueOut = @ValueIn + @OutWorking       
        END
    ELSE
        BEGIN
            SELECT @ValueOut = 1
        END
    RETURN
[ unisoft @ 14.01.2010. 10:13 ] @
Ne znam sta da kazem ... Hvala vam puno ... Sada potpuno razumem sta se desava u kodu .Ja sam bas na ovo mislio sam nisam se lepo izrazio,nisam lepo napisao kod (u mom zadnjem odg. ).

Siguran sam da je jos neku upao u slicnu dilemu kao ja sta se u ovom kodu desava pa ne bi bilo lose da smislimo bolji naziv za ovo TEMU i da ga promenimo .Radi pretrage foruma.

HVALA VAM JOS JEDNOM !!!