[MySQL 4.1.21-standard]Cursor??

0

Mam następującą DB na serwerze MySQL 4.1.21-standard:

BEGIN;
CREATE TABLE IF NOT EXISTS User(
 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
 login VARCHAR(32) NOT NULL UNIQUE,
 pass VARBINARY(32),
 bids INT UNSIGNED);
CREATE TABLE IF NOT EXISTS Bid(
 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
 kkey VARBINARY(64) NOT NULL,
 friend BIGINT UNSIGNED REFERENCES User(id) ON DELETE CASCADE ON UPDATE RESTRICT,
 time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL);
COMMIT

I potrzebuję wykombinować zapytanie SQL, które:

  • Dla każdej krotki z relacji Bid, która się przeterminowała (tzn Bid.time<DATE_ADD(NOW(),INTERVAL 1 DAY)):
    -- Incrementuje wartość pola User.bids odpowiadającemu urzytkownikowi (czyli którego User.id=Bid.friend);
    -- Następnie usuwa daną krotkę z relacji Bid

Zaczełem próbować tak:

BEGIN;
DECLARE cur CURSOR FOR SELECT friend,COUNT(*) AS cnt FROM Bid WHERE time<DATE_ADD(NOW(),INTERVAL 1 DAY) GROUP BY friend;
DECLARE f,c,i BIGINT UNSIGNED;
DECLARE done BOOL DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
OPEN cur;

myLoop:LOOP
 FETCH cur INTO f,c,i;
 IF done THEN
  CLOSE cur;
  LEAVE myLoop;
 END IF;
 UPDATE User SET bids=bids+c WHERE id=f AND bids NOTNULL;
 DELETE FROM Bid WHERE id=i;
END LOOP;

COMMIT

...ale przedchwilą zauważyłem, że w MySQL 4.1.21 nie ma jeszcze CURSOR'ów :( [glowa]

0

w tej wersji MySQLa nie zrobisz tego w jednym zapytaniu - pozostaje Ci jedynie po stronie PHP najpierw zrobić update a potem delete

0

No właśnie domyślałem się, że tak to się skończy :/

A chciałem być pewny, że nikt mi się nie wtryni podczas wykonywania tranzakcji :(

0

nie wtryni podczas wykonywania transakcji? a co dokładnie wykonujesz? znaczy się przed czym chciałeś się zabezpieczyć?

może przesiądź się na PostgreSQL'a? daje większe możliwości

0

Chodzi o to, że każdy User ma mieć możliwość dysponowania określoną liczbą zaproszeń. Zaproszenia można udostępnić wybranej osobie wysyłając jej link z odpowiednio wygenerowanym ciągiem pseudolosowych znaków (kluczem), ale takie zaproszenie ma także termin ważności, po którym, jeśli nie zostało wykorzystane, jest anulowane, a User powinien mieć w tym momęcie możliwość wygenerowania następnego.
Chodzi o to, że jeśli będę usuwał przeterminowane zaproszenia, a następnie oddawał je User'om w oddzielnych tranzakcjach może się zdarzyć, że mi się jakimś dziwnym trafem te zaproszenia rozmnorzą lub poznikają :P

Nie no w sumie to może lekko przesadzam...

Co do Postgres'a to jusz dawno się do niego przekonałem - tylko, że nie znam darmowych publicznie dostępnych serwerów ;]

0

ale dla tabel InnoDB masz transakcje

co do Postgresa to True chociaż może w końcu http://www.freesql.org/ ruszy

0

co do Twojego problemu. ;)

to ja to widze tak. Za każdym razem kiedy musiałem podobną rzecz zrobić i objąć to w transakcję :) generowałem sobie połączenie i robiłem takie coś:

   $connection = mysql_connect(//tu wiadomo);
   mysql_query($connection, "begin transaction");
      //tutaj wykonuję wszystko co chcę łącznie z kodem php
   mysql_query($connection, "commit");
     //i zamknięcie połączenia

a co do bazy danych. dużo miejsca byś potrzebował na taką bazę danych 10 MB by ci starczyło? tyle ci mogę dać za free na PostgreSQL 8.1 z publicznym adresem i bez problemów z dostępem.

0
jmail napisał(a)
   $connection = mysql_connect(//tu wiadomo);
   mysql_query("begin transaction",$connection);
      //tutaj wykonuję wszystko co chcę łącznie z kodem php
   mysql_query("commit",$connection);
     //i zamknięcie połączenia

Ja myślałem, że begin i commit muszą być w jednym zapytaniu.
poza tym poprawiłem mały błąd składni w powyższym kodzie ;-)

jmail napisał(a)

a co do bazy danych. dużo miejsca byś potrzebował na taką bazę danych 10 MB by ci starczyło? tyle ci mogę dać za free na PostgreSQL 8.1 z publicznym adresem i bez problemów z dostępem.

No nie wiem czy starczy - chciałem tam wrzucać obrazki i filmiki w polach BLOB ;]
Ale wymyśliłem jusz nieco inne rozwiązanie :-)
W relacji User zapisuję maxymalną ilość dozwolonych krotek relacji Bid dla danego usera (a nie ile mu pozostało). A następnie tworząc nową zliczam ile jusz ich on ma i czy może zrobić następną. Dzięki temu nie muszę modyfikować pola User.bids - wystarczy po prostu wywalać przeterminowane krotki z relacji Bid [browar]

PS: Kto powiedział, że robię to w PHP'ie :>

1 użytkowników online, w tym zalogowanych: 0, gości: 1