Problem z procedurka
_nabuchodonozor - 16-09-2007 00:00
Problem z procedurka
Pisalem juz wczesniej ale zalezy mi bardzo wiec robie nowy topic. Oto proc jaka napisalem: -- dodaje nowe seanse a takze uaktualniam tytuly. Ilosc seansow zalezy od @iloscWierszy przy czym gdy choc jeden z dodawanych wierszy juz znajduje sie w bazie -- transakcja zostaje wycofana i zaden z wierszy nie zostanie dodany CREATE PROCEDURE DodajSeans @dzienEmisji datetime, @godzinaEmisji nvarchar(5), @dostepnoscMiejsc nvarchar(375), @cenaBiletuUlg money, @cenaBiletuNorm money, @tytul nvarchar(50), @idSali int, @iloscWierszy int AS begin tran
declare @i int set @i = 0
declare @idTytulu int set @idTytulu = (select idTytulu from tytuly where tytul like @tytul)
declare @wykonano bit set @wykonano = 0
while(@i<=@iloscWierszy) begin insert into seanse values(@idTytulu, @idSali, @cenaBiletuNorm, @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji ) set @dzienEmisji = @dzienEmisji +1 set @i = @i +1 if(@i>@iloscWierszy) set @wykonano = 1 end if(@wykonano=1) begin update tytuly set wyswietlany = 'TAK' where tytul like @tytul commit tran end else if(@wykonano = 0) rollback tran GO
Tak jak w komentarzu na poczatku proc, chce aby gdy cos sie nie powiedzie wszystkie zmiany zostaly wycofane. Niestety nie dzieje sie tak, te same wiersze nie sa wstawiane(program rzuca wyjatek) ale niestety nowe tak, a chcialbym tego uniknac. Wydaje mi sie ze przy pierwszym napotkanym konflikcie musze juz przerwac transakcje ale nie wiem jak wylapac to ze taki wiersz juz istnieje. Pomozcie
KK
Grzegorz Danowski - 16-09-2007 00:00
"_nabuchodonozor" <kkocemba@wsb-nlu.edu.pl> wrote in message news:1189856943.116393.311250@o80g2000hse.googlegr oups.com... > Pisalem juz wczesniej ale zalezy mi bardzo wiec robie nowy topic. > Oto proc jaka napisalem: > -- dodaje nowe seanse a takze uaktualniam tytuly. Ilosc seansow zalezy > od @iloscWierszy przy czym gdy choc jeden z dodawanych wierszy juz > znajduje sie w bazie > -- transakcja zostaje wycofana i zaden z wierszy nie zostanie dodany > CREATE PROCEDURE DodajSeans > @dzienEmisji datetime, .... > while(@i<=@iloscWierszy) > begin > insert into seanse values(@idTytulu, @idSali, @cenaBiletuNorm, > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji ) > set @dzienEmisji = @dzienEmisji +1 > set @i = @i +1 .... > Tak jak w komentarzu na poczatku proc, chce aby gdy cos sie nie > powiedzie wszystkie zmiany zostaly wycofane. Niestety nie dzieje sie > tak, te same wiersze nie sa wstawiane(program rzuca wyjatek) ale > niestety nowe tak, a chcialbym tego uniknac. Wydaje mi sie ze przy > pierwszym napotkanym konflikcie musze juz przerwac transakcje ale nie > wiem jak wylapac to ze taki wiersz juz istnieje. Pomozcie
Proponuję zmienić koncepcję na bardziej sql-ową (a mniej proceduralną): 1. utworzyć pomocniczą tabelę z kolejnymi numerkami, np.:
SELECT TOP 8000 Number = IDENTITY(int, 1, 1) INTO Numbers FROM sys.all_columns t1, sys.all_columns t2 Go
Alter Table Numbers Add Constraint Pk_Numbers Primary Key (Number)
Oczywiście tabela Numbers może przydać Ci się w innych zapytaniach. Dzięki niej możesz w prostszy sposób dodawać kolejne dni do tabeli z seansami, coś w deseń:
CREATE PROCEDURE DodajSeans @dzienEmisji datetime, @godzinaEmisji nvarchar(5), @dostepnoscMiejsc nvarchar(375), @cenaBiletuUlg money, @cenaBiletuNorm money, @tytul nvarchar(50), @idSali int, @iloscWierszy int AS
Declare @idTytulu int Select @idTytulu = idTytulu From tytuly Where tytul Like @tytul
Insert Into seanse Select @idTytulu, @idSali, @cenaBiletuNorm, @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji + Number - 1 From Numbers Where Number <= @iloscWierszy
Update tytuly Set wyswietlany = 'TAK' Where tytul Like @tytul Go
Takie rozwiązanie jest dużo wydajniejsze, poza tym będzie działać tak jak oczekujesz nawet bez używania transakcji, bo AFAIK wszystkie rekordy będziesz dodawał jednorazowo. IMHO jest też bardziej czytelne. --
Pozdrawiam Grzegorz http://gdanowski.blogspot.com/
_nabuchodonozor - 16-09-2007 00:00
On 15 Wrz, 14:15, "Grzegorz Danowski" <gdn__na@serwerze__poczta.onet.pl> wrote: > "_nabuchodonozor" <kkoce...@wsb-nlu.edu.pl> wrote in message > > news:1189856943.116393.311250@o80g2000hse.googlegr oups.com... > > > > > Pisalem juz wczesniej ale zalezy mi bardzo wiec robie nowy topic. > > Oto proc jaka napisalem: > > -- dodaje nowe seanse a takze uaktualniam tytuly. Ilosc seansow zalezy > > od @iloscWierszy przy czym gdy choc jeden z dodawanych wierszy juz > > znajduje sie w bazie > > -- transakcja zostaje wycofana i zaden z wierszy nie zostanie dodany > > CREATE PROCEDURE DodajSeans > > @dzienEmisji datetime, > ... > > while(@i<=@iloscWierszy) > > begin > > insert into seanse values(@idTytulu, @idSali, @cenaBiletuNorm, > > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji ) > > set @dzienEmisji = @dzienEmisji +1 > > set @i = @i +1 > ... > > Tak jak w komentarzu na poczatku proc, chce aby gdy cos sie nie > > powiedzie wszystkie zmiany zostaly wycofane. Niestety nie dzieje sie > > tak, te same wiersze nie sa wstawiane(program rzuca wyjatek) ale > > niestety nowe tak, a chcialbym tego uniknac. Wydaje mi sie ze przy > > pierwszym napotkanym konflikcie musze juz przerwac transakcje ale nie > > wiem jak wylapac to ze taki wiersz juz istnieje. Pomozcie > > Proponuj zmieni koncepcj na bardziej sql-ow (a mniej proceduraln ): > 1. utworzy pomocnicz tabel z kolejnymi numerkami, np.: > > SELECT TOP 8000 Number = IDENTITY(int, 1, 1) > INTO Numbers > FROM sys.all_columns t1, sys.all_columns t2 > Go > > Alter Table Numbers > Add Constraint > Pk_Numbers Primary Key (Number) > > Oczywi cie tabela Numbers mo e przyda Ci si w innych zapytaniach. > Dzi ki niej mo esz w prostszy sposób dodawa kolejne dni do tabeli z > seansami, co w dese : > > CREATE PROCEDURE DodajSeans > @dzienEmisji datetime, > @godzinaEmisji nvarchar(5), > @dostepnoscMiejsc nvarchar(375), > @cenaBiletuUlg money, > @cenaBiletuNorm money, > @tytul nvarchar(50), > @idSali int, > @iloscWierszy int > AS > > Declare @idTytulu int > Select @idTytulu = idTytulu From tytuly Where tytul Like @tytul > > Insert Into > seanse > Select > @idTytulu, @idSali, @cenaBiletuNorm, > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, > @dzienEmisji + Number - 1 > From > Numbers > Where > Number <= @iloscWierszy > > Update tytuly Set wyswietlany = 'TAK' Where tytul Like @tytul > Go > > Takie rozwi zanie jest du o wydajniejsze, poza tym b dzie dzia a tak jak > oczekujesz nawet bez u ywania transakcji, bo AFAIK wszystkie rekordy > b dziesz dodawa jednorazowo. > IMHO jest te bardziej czytelne. -- > > Pozdrawiam > Grzegorzhttp://gdanowski.blogspot.com/
Szczerze powiedziawszy nie bardzo zrozumialem:P nie jestem bazodanowcem. Nie istnieje jakis latwiejszy sposob? Wolalbym zostac przy mojej procedurze bez tworzenia nowych tabel(no chyba ze tymczasowych wewnatrz procedury).
Pozdrawiam KK
Grzegorz Danowski - 17-09-2007 00:00
"_nabuchodonozor" <kkocemba@wsb-nlu.edu.pl> wrote in message news:1189872096.968291.125570@n39g2000hsh.googlegr oups.com... <cite> > > -- dodaje nowe seanse a takze uaktualniam tytuly. Ilosc seansow zalezy > > od @iloscWierszy przy czym gdy choc jeden z dodawanych wierszy juz > > znajduje sie w bazie > > -- transakcja zostaje wycofana i zaden z wierszy nie zostanie dodany .... > Proponuj zmieni koncepcj na bardziej sql-ow (a mniej proceduraln ): > 1. utworzy pomocnicz tabel z kolejnymi numerkami, np.: .... > Dzi ki niej mo esz w prostszy sposób dodawa kolejne dni do tabeli z > seansami, co w dese : .... > Insert Into > seanse > Select > @idTytulu, @idSali, @cenaBiletuNorm, > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, > @dzienEmisji + Number - 1 > From > Numbers > Where > Number <= @iloscWierszy .... Szczerze powiedziawszy nie bardzo zrozumialem:P nie jestem bazodanowcem. Nie istnieje jakis latwiejszy sposob? Wolalbym zostac przy mojej procedurze bez tworzenia nowych tabel(no chyba ze tymczasowych wewnatrz procedury). </cite>
Hmm, to proste jak drut: wybierasz z tabelki Numbers tyle rekordów ile chcesz wygenerowac rekordów w tabeli seanse, a kolejny numer z tabeli Numbers sluzy do wyznaczania kolejnego dnia. Ale skoro jednak nie mozesz dodawac do bazy nowych tabel, to oczywiscie taki pomysl odpada. Spróbuj wiec zmodyfikowac swoja procedure wg pomyslu:
CREATE PROCEDURE DodajSeans @dzienEmisji datetime, @godzinaEmisji nvarchar(5), @dostepnoscMiejsc nvarchar(375), @cenaBiletuUlg money, @cenaBiletuNorm money, @tytul nvarchar(50), @idSali int, @iloscWierszy int AS begin tran
declare @i int set @i = 0
declare @idTytulu int select @idTytulu = idTytulu from tytuly where tytul like @tytul
while(@i<=@iloscWierszy) begin insert into seanse values(@idTytulu, @idSali, @cenaBiletuNorm, @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji + @i)
if @Error<>0 Begin rollback tran return End
set @i = @i +1 end
update tytuly set wyswietlany = 'TAK' where idTytulu = @idTytulu commit tran Go -- Pozdrawiam Grzegorz http://gdanowski.blogspot.com/
_nabuchodonozor - 17-09-2007 00:00
On 16 Wrz, 05:54, "Grzegorz Danowski" <gdn__na@serwerze__poczta.onet.pl> wrote: > "_nabuchodonozor" <kkoce...@wsb-nlu.edu.pl> wrote in message > > news:1189872096.968291.125570@n39g2000hsh.googlegr oups.com... > <cite> > > > > -- dodaje nowe seanse a takze uaktualniam tytuly. Ilosc seansow zalezy > > > od @iloscWierszy przy czym gdy choc jeden z dodawanych wierszy juz > > > znajduje sie w bazie > > > -- transakcja zostaje wycofana i zaden z wierszy nie zostanie dodany > ... > > Proponuj zmieni koncepcj na bardziej sql-ow (a mniej proceduraln ): > > 1. utworzy pomocnicz tabel z kolejnymi numerkami, np.: > ... > > Dzi ki niej mo esz w prostszy sposób dodawa kolejne dni do tabeli z > > seansami, co w dese : > ... > > Insert Into > > seanse > > Select > > @idTytulu, @idSali, @cenaBiletuNorm, > > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, > > @dzienEmisji + Number - 1 > > From > > Numbers > > Where > > Number <= @iloscWierszy > > ... > Szczerze powiedziawszy nie bardzo zrozumialem:P nie jestem > bazodanowcem. Nie istnieje jakis latwiejszy sposob? Wolalbym zostac > przy mojej procedurze bez tworzenia nowych tabel(no chyba ze > tymczasowych wewnatrz procedury). > </cite> > > Hmm, to proste jak drut: wybierasz z tabelki Numbers tyle rekordów ile > chcesz wygenerowac rekordów w tabeli seanse, a kolejny numer z tabeli > Numbers sluzy do wyznaczania kolejnego dnia. > Ale skoro jednak nie mozesz dodawac do bazy nowych tabel, to oczywiscie taki > pomysl odpada. Spróbuj wiec zmodyfikowac swoja procedure wg pomyslu: > > CREATE PROCEDURE DodajSeans > @dzienEmisji datetime, > @godzinaEmisji nvarchar(5), > @dostepnoscMiejsc nvarchar(375), > @cenaBiletuUlg money, > @cenaBiletuNorm money, > @tytul nvarchar(50), > @idSali int, > @iloscWierszy int > AS > begin tran > > declare @i int > set @i = 0 > > declare @idTytulu int > select @idTytulu = idTytulu from tytuly where tytul like @tytul > > while(@i<=@iloscWierszy) > begin > insert into seanse values(@idTytulu, @idSali, @cenaBiletuNorm, > @cenaBiletuUlg, @dostepnoscMiejsc, @godzinaEmisji, @dzienEmisji + > @i) > > if @Error<>0 > Begin > rollback tran > return > End > > set @i = @i +1 > end > > update tytuly set wyswietlany = 'TAK' where idTytulu = @idTytulu > commit tran > Go > -- > Pozdrawiam > Grzegorzhttp://gdanowski.blogspot.com/
Idealne rozwiazanie:D naprawde ogromnie mi pomogles dzieki wielkie i pozdrawiam:)
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[MSSQL2000] Problem z =?ISO-8859-2?Q?tabel=B1/indeksem/zapytanie?==?ISO-8859-2?Q?m_czy_b=B3=B1d_w_bazie_danych=2E=2E=2E?=
mysql i mysql-front, problem
String line; if (line=="cos"){...}....problem
Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?=
[postgres] Problem z =?ISO-8859-2?Q?zmian=B1_struktury_i_z?==?ISO-8859-2?Q?ale=BFno=B6ciami=2E?=
[oracle] =?ISO-8859-2?Q?zmia=BFd=BFony_przez_problem=3A_za?==?ISO-8859-2?Q?pytanie_do_hierarchi?=
Problem z wartościami w MySQL :( [ MySQL and ASP and VBScript ]
[PGSQL] czy ktos mial problemy z initdb pgsql 8.1 ?
[MySQL] Problem z zapisem danych w bazie danych
Problem z mysql - can't connect to MySQL/nietypowo...
zanotowane.pldoc.pisz.plpdf.pisz.plkfia-tek.keep.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|