2014-11-14 3 views
0

Я написал эту функцию для БД Oracle для проекта класса:Почему эта функция Oracle PLSQL необходимо перекомпилировать при обновлении таблицы?

create or replace Function loginUser (name_in IN varchar2, pass_in IN varchar2) 
Return Number 
IS 
    cursor c1 is 
    SELECT u_id 
    FROM userinfo 
    WHERE username = name_in AND pass = pass_in AND lockedout='N'; 

    user_id_return number; 
PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN 

    open c1; 
    fetch c1 into user_id_return; 

    if c1%notfound then 
    user_id_return := 0; 
    INSERT INTO LoginAttempt(username, whenattempted, attempt_status) VALUES (name_in, SYSDATE, 'N'); 
    commit; 
    ELSE 
    INSERT INTO LoginAttempt(username, whenattempted, attempt_status) VALUES (name_in, SYSDATE, 'Y'); 
    commit; 
    END IF; 

    close c1; 

Return user_id_return; 

EXCEPTION 
WHEN OTHERS THEN 
    raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM); 
END; 

Он отлично работает, я получаю вставку в таблицу под названием LoginAttempt при вызове

SELECT loginUser('name','pass') FROM DUAL; 

Проблема, однако , заключается в том, что новые записи и обновления для userinfo не отражаются в инструкции SELECT в верхней части функции.

Мне нужно перекомпилировать функцию каждый раз, когда я обновляю таблицу userinfo.

Почему это? Это работает с операторами SELECT? Является ли таблица, которая выбрана из компиляции при компиляции функции?

Это связано с битом PRAGME AUTONOMOUS_TRANSACTION?

Схему для таблицы можно найти на GitHub (https://github.com/tmsimont/cs3810schema/blob/master/export.sql)

+1

Можете ли вы объяснить, как вы вставляете новые записи в таблицу userinfo? Может быть, вы делаете это с другой сессии и не выполняете вставки? – benji

+0

это возможно. Я просто использую sqldeveloper. Я не слишком хорошо знаком с программным обеспечением. Я ввожу команду в окно и нажимаю F5 ... Когда я вызываю INSERT INTO userinfo ... Я нажимаю F5 .. Когда я позже вернусь и сделаю SELECT * FROM userinfo, я вижу мои изменения ... Я ' Мне нужно сделать еще несколько тестов, чтобы узнать, что происходит с SQLDeveloper и что делает F5. Спасибо за руководство – tmsimont

+0

OK извините за хромый комментарий .. Все, что я знаю о F5, это то, что вызывает «Run script» - я просто пишу «INSERT INTO userinfo (имя пользователя, пароль) VALUES (« Тревор »,« ТЕСТ »,) «Я не думаю, что« RUN SCRIPT »в SQLDeveloper будет включать в себя комментирование запроса, но я могу ошибаться – tmsimont

ответ

0

Поскольку ваша функция выполняет свой DML в автономной транзакции (т.е. отдельный сеанс вызывающих один), он не может видеть данные, которые не были совершенные сеансом вызова. Пока ваш код не зафиксируется, сделанные изменения не будут видны ни одному другому сеансу, включая тот, который используется вашей функцией.

Это не имеет никакого отношения к необходимости компиляции функции. Компиляция причины заставила его внезапно увидеть данные, потому что DDL всегда выдает фиксацию, тем самым имея побочный эффект от ввода данных, которые вы вставили.

+0

Да, я думал, что F5 в SQL Developer совершает изменения, но это не так. Вы должны поразить F11. Это немного отличается от Microsoft SQL Server – tmsimont