Utilizator anonim
Mai mult
Verificați dacă un rând există, în caz contrar se introduce
Am nevoie pentru a scrie un T-SQL proceduri stocate care actualizează un rând într-un tabel. Dacă rand nu't există, introduceți-l. Toate aceste măsuri înfășurat de o tranzacție.
Acest lucru este pentru un sistem de rezervare, așa că trebuie să fie atomică și de încredere. Acesta trebuie să se întoarcă adevărat în cazul în care tranzacția a fost comisă și zborul rezervat.
Am'm nou pentru T-SQL, și nu sunt sigur despre cum să folosiți @@rowcount
. Aceasta este ceea ce am'am scris până acum. Sunt pe drumul cel bun? Am'sunt sigur că este o problemă ușoară pentru tine.
-- BEGIN TRANSACTION (HOW TO DO?)
UPDATE Bookings
SET TicketsBooked = TicketsBooked + @TicketsToBook
WHERE FlightId = @Id AND TicketsMax < (TicketsBooked + @TicketsToBook)
-- Here I need to insert only if the row doesn't exists.
-- If the row exists but the condition TicketsMax is violated, I must not insert
-- the row and return FALSE
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Bookings ... (omitted)
END
-- END TRANSACTION (HOW TO DO?)
-- Return TRUE (How to do?)
225
11
Uită-te la MERGE comandă. Poți să faci "UPDATE", "INSERT" & "DELETE", într-o declarație.
Aici este un lucru punere în aplicare privind utilizarea
MERGE
dacă există(selectați 1 din INFORMATION_SCHEMA.TABELELE T în cazul în care T. TABLE_NAME = 'Rezervari') începe drop table Rezervările end DU-te
crea Rezervări de masă( FlightID int identitate(1, 1) cheie primară, TicketsMax int not null, TicketsBooked int not null ) DU-te
introduce Rezervari(TicketsMax, TicketsBooked) selectați 1, 0 introduce Rezervari(TicketsMax, TicketsBooked) selectați 2, 2 introduce Rezervari(TicketsMax, TicketsBooked) selectați 3, 1 DU-te
selectați * de la Rezervari
Și apoi ...
Presupun că un singur rand pentru fiecare zbor? Dacă așa:
Presupun că ceea ce am spus, ca mod de a face lucrurile pot cere mai mult un zbor, ca se va introduce un rând nou, atunci când sunt 10 bilete max și vă rezervarea 20.
Trece updlock, rowlock, holdlock indicii atunci când testarea pentru existența rând.
La updlock indiciu forțele de interogare pentru a lua o actualizare de blocare pe rând dacă acesta există deja, prevenind alte tranzacții la modificarea până nu se angajeze sau să se rostogolească înapoi.
La holdlock indiciu forțele de interogare pentru a lua o serie de blocare, prevenind alte tranzacții la adăugarea unui rând de potrivire dumneavoastră de criterii de filtrare până nu se angajeze sau să se rostogolească înapoi.
La rowlock indiciu forțele de blocare granularitate la rândul nivel în loc de default la nivel de pagină, astfel încât tranzacția a câștigat't bloca alte tranzacții încercarea de a actualiza legătură rânduri în aceeași pagină (dar să fie conștienți de trade-off între redusă dispută și creșterea blocare deasupra capului - ar trebui să evite a lua un număr mare de nivel de rând blochează într-o singură tranzacție).
Vezi http://msdn.microsoft.com/en-us/library/ms187373.aspx pentru mai multe informații.
Rețineți că încuietorile sunt luate ca declarațiile pe care le ia sunt executate - invocarea begin tran nu't oferi imunitate împotriva o altă tranzacție ciupit blochează pe ceva înainte de a ajunge la ea. Ar trebui să încercați și factor SQL pentru a ține încuietori pentru cel mai scurt timp posibil de a comite tranzacția cât mai curând posibil (de a dobândi târziu, eliberați mai devreme).
Rețineți că la nivel de rând încuietori pot fi mai puțin eficiente dacă PK este un bigint, ca intern hashing pe SQL Server este degenerat pentru 64-bit valori (diferite valori-cheie poate hash la acelasi id blocare).
am'm scris soluția mea. metoda mea nu't sta 'daca' sau 'merge'. metoda mea este ușor.
De Exemplu:
Explicație:
(1) SELECT col1,col2 FROM nume tabelă UNDE col1=@par1 ȘI col2=@par2 Se selectează din tabela nume căutat valori
(2) SELECTAȚI @par1, @par2 în cazul în CARE NU EXISTĂ E nevoie, dacă nu există la (1) subinterogare
(3) Introduce în TableName (2) pasul valori
În cele din urmă am fost capabil de a introduce un rând, cu condiția că aceasta nu't există deja, folosind următorul model:
ceea ce am găsit la:
http://www.postgresql.org/message-id/87hdow4ld1.fsf@stark.xeocode.com
Acest lucru este ceva recent am avut de-a face:
Ai putea folosi Merge Funcționalitate pentru a atinge. În caz contrar, puteți face:
Soluție completă este mai jos (inclusiv cursorul structura). Multe mulțumiri pentru Cassius Porcus pentru a începe trans ... comite` cod de la postarea de mai sus.
Cea mai bună abordare a acestei probleme este de a face prima coloana de date UNICE
ALTER TABLE nume_tabel ADD CHEIE UNICĂ
APOI INTRODUCEȚI IGNORA ÎN nume_tabel
,o valoare't fi introdus în cazul în care rezultă într-o cheie duplicat/există deja în tabel.