Оператор Oracle SQL% ROWCOUNT всегда возвращает 1 - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть простая таблица USERS в Oracle с 2 столбцами ID и USERNAME.ID - это первичный ключ, который автоматически увеличивается с помощью триггера.

Я вставляю или обновляю записи, используя процедуру, подобную этой

CREATE OR REPLACE PROCEDURE SaveUser(UID NUMBER, UN VARCHAR2, Row_Count OUT NUMBER) IS
BEGIN
    IF(UID > 0) THEN
        UPDATE USERS SET USERNAME = UN WHERE ID = UID;
    ELSE
        INSERT INTO USERS(USERNAME) VALUES(UN);
    END IF;

    Row_Count := SQL%ROWCOUNT;
END;

Я вызываю процедуру следующим образом:

VARIABLE Row_Count NUMBER;
EXEC SaveUser(50, 'Username_1', Row_Count);
PRINT Row_Count;

Проблема в том, что я передаю 50 в качестве первого параметра, но в таблице нет строки с ID 50 .Но я получаю 1 в результате.Даже если строка не обновляется, оператор SQL%ROWCOUNT возвращает 1 .Может кто-нибудь помочь мне исправить это?

Приведенный выше код упрощен и точный код здесь

CREATE OR REPLACE PROCEDURE SaveEmployee(ID NUMBER, User_Name VARCHAR2, Emp_Password VARCHAR2, Emp_Full_Name VARCHAR2, Emp_Date_Of_Birth DATE, Emp_Gender_ID NUMBER, Emp_Work_Type_ID NUMBER, Emp_Salary FLOAT, Emp_Email VARCHAR2, Row_Count OUT NUMBER) IS
    Username_Row_Count NUMBER := 0;
    Email_Row_Count NUMBER := 0;
BEGIN
    IF(ID > 0) THEN
        SELECT COUNT(1) INTO Username_Row_Count FROM EMPLOYEES WHERE LOWER(USERNAME) = LOWER(User_Name) AND EMPLOYEE_ID <> ID;
        SELECT COUNT(1) INTO Email_Row_Count FROM EMPLOYEES WHERE LOWER(EMAIL) = LOWER(Emp_Email) AND EMPLOYEE_ID <> ID;

        IF(Username_Row_Count = 0 AND Email_Row_Count = 0) THEN
            UPDATE EMPLOYEES
            SET USERNAME = LOWER(User_Name), PASSWORD = Emp_Password, FULL_NAME = Emp_Full_Name, DATE_OF_BIRTH = Emp_Date_Of_Birth, GENDER_ID = Emp_Gender_ID, WORK_TYPE_ID = Emp_Work_Type_ID, SALARY = Emp_Salary, EMAIL = LOWER(Emp_Email)
            WHERE EMPLOYEE_ID = ID;
        END IF;
    ELSE
        SELECT COUNT(1) INTO Username_Row_Count FROM EMPLOYEES WHERE LOWER(USERNAME) = LOWER(User_Name);
        SELECT COUNT(1) INTO Email_Row_Count FROM EMPLOYEES WHERE LOWER(EMAIL) = LOWER(Emp_Email);

        IF(Username_Row_Count = 0 AND Email_Row_Count = 0) THEN
            INSERT INTO EMPLOYEES(USERNAME, PASSWORD, FULL_NAME, DATE_OF_BIRTH, GENDER_ID, WORK_TYPE_ID, SALARY, EMAIL, LOGIN_ATTEMPTS)
            VALUES(LOWER(User_Name), Emp_Password, Emp_Full_Name, Emp_Date_Of_Birth, Emp_Gender_ID, Emp_Work_Type_ID, Emp_Salary, LOWER(Emp_Email), 0);
        END IF;
    END IF;

    Row_Count := SQL%ROWCOUNT;
END;

Ответы [ 3 ]

1 голос
/ 16 апреля 2019

Добавить SQL%ROWCOUNT после обновления, чтобы получить счетчик обновлений

UPDATE EMPLOYEES
            SET USERNAME = LOWER(User_Name), PASSWORD = Emp_Password, FULL_NAME = Emp_Full_Name, DATE_OF_BIRTH = Emp_Date_Of_Birth, GENDER_ID = Emp_Gender_ID, WORK_TYPE_ID = Emp_Work_Type_ID, SALARY = Emp_Salary, EMAIL = LOWER(Emp_Email)
            WHERE EMPLOYEE_ID = ID;
Row_Count := SQL%ROWCOUNT;
1 голос
/ 16 апреля 2019

Теперь стало понятнее.

Этот код:

SELECT COUNT(1) INTO Username_Row_Count FROM EMPLOYEES WHERE LOWER(USERNAME) = LOWER(User_Name) AND EMPLOYEE_ID <> ID;
SELECT COUNT(1) INTO Email_Row_Count FROM EMPLOYEES WHERE LOWER(EMAIL) = LOWER(Emp_Email) AND EMPLOYEE_ID <> ID;

должен обновить значения Username_Row_Count и Email_Row_Count, чтобы условие

IF(Username_Row_Count = 0 AND Email_Row_Count = 0) THEN

всегда ложно. И обновление никогда не выполняется. В результате в вашей переменной Row_Count вы получите результат последнего выбора, который равен 1 строке.

1 голос
/ 16 апреля 2019

Я не могу воспроизвести то, что вы говорите:

SQL> select * from users;

no rows selected

SQL> declare
  2    uid number := 50;
  3  begin
  4    if uid > 0 then
  5       update users set username = '&&un' where id = uid;
  6    else
  7       insert into users (username) values ('&&un');
  8    end if;
  9    dbms_output.put_line(sql%rowcount);
 10  end;
 11  /
Enter value for un: 50
0                              --> this is SQL%ROWCOUNT

PL/SQL procedure successfully completed.

SQL>

Код, который вы опубликовали, недействителен (тип данных NUBER отсутствует). Было бы полезно, если бы вы опубликовали что-то, что на самом деле работает , потому что - как вы это выразили - мы не можем быть уверены, что то, что вы утверждаете как истинное на самом деле , является истинным. Пожалуйста, скопируйте / вставьте свой собственный сеанс SQL * Plus (как и я), чтобы мы увидели, что у вас есть на самом деле и как на это отреагировал Oracle.

...