1. SQL / Говнокод #5235

    −861

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    CREATE FUNCTION "insert_payment" (integer) RETURNS integer AS '                                                                                                                     
    DECLARE                                                                                                                                                                             
            l_payment       integer;                                                                                                                                                    
    BEGIN                                                                                                                                                                               
            INSERT INTO payments (client,type_,pdate,number_)                                                                                                                           
            VALUES ($1,4,current_date,nextval_(''payments_number_1_seq''));                                                                                                             
                                                                                                                                                                                        
            SELECT INTO l_payment last_value FROM payments_id_seq;                                                                                                                      
            RETURN l_payment;                                                                                                                                                           
    END;' LANGUAGE 'plpgsql';

    Функция должна вставлять платеж и возвращать его id.
    Под нагрузкой конечно же 8 строка возвращает нен тот id. (когда несколько параллельных транзакций успевают сделать вставку.)
    Что интересно - возвращаемый функцией id используется другой хранимкой для проставления суммы платежа. И это пости всегда работает :)
    Перл от "отцов основателей".

    Запостил: SanityIO, 12 Января 2011

    Комментарии (6) RSS

    • на этом много прогеров погорело
      Ответить
    • А какая СУБД?

      Вот для этого в Firebird, например, есть волшебная секция RETURNING в INSERT и UPDATE запросах:
      INSERT INTO table (....)
      VALUES (....)
      RETURNING id

      запрос вернет ID вставленной записи

      Другой православный способ - использовать генераторы (SEQUENCE) вместо автоинкрементных полей.

      Отстутствие этих двух фич я не могу простить MySQLю. Кстати, проясните раз и навсегда как правильно решать эту задачу в MySQL? В своем проекте делал в PHP через mysqli_insert_id, но ИМХО это костыль какой-то.
      Ответить
      • пардон, в примере кажись sequence и использован. но анально, да
        Ответить

    Добавить комментарий