Переход в спящий режим и хранимые процедуры oracle

#oracle #hibernate

#Oracle #переход в спящий режим

Вопрос:

У меня есть хранимая процедура oracle:`


     create or replace procedure getClientFromAuthentification(myCursorResult out sys_refcursor, login in VARCHAR2, pwd in VARCHAR2) as
num_client NUMBER(6);

compte_epargne VARCHAR2(50);

compte_courant VARCHAR2(50);

nom VARCHAR2(50);

prenom VARCHAR2(50);

adresse VARCHAR2(100);

begin

  open myCursorResult for

    select client.num_client, client.num_compte_epargne, client.num_compte_courant, 
client.nom_client, client.prenom_client, client.adresse_client

    from client 

    where client.login_client = login and client.mdp_client = pwd;

  fetch myCursorResult into num_client, compte_epargne, compte_courant, nom, prenom, adresse;

  if myCursorResult%ROWCOUNT > 1 then raise TOO_MANY_ROWS;

  else if myCursorResult%ROWCOUNT = 0 then raise NO_DATA_FOUND;

  end if;

  end if;

  exception

    when TOO_MANY_ROWS then raise_application_error(-20000, 'base corrompue');

    when NO_DATA_FOUND then raise_application_error(-20001, 'pas de résultats');

end getClientFromAuthentification;`
  

Я протестировал это в oracle sqldevelopper, и это работает нормально :


 `set serveroutput on;

declare

myCursor sys_refcursor;

begin

  dbms_output.enable;

  getclientfromauthentification(myCursor, 'durant.jean', 'durant.jean1234');

  dbms_output.put_line('cursor = ' || myCursor%ROWCOUNT);

end;`
  

курсор = 1 (он его нашел : =))

Теперь я пытаюсь использовать эту процедуру на стороне Java с hybernate.

Отображение :


 `<hibernate-mapping>

  <class name="model.entity.Client">

    <id name="num_client" type="int" />

    <property name="num_compte_epargne" type="string" />

    <property name="num_compte_courant" type="string" />

    <property name="nom" type="string" />

    <property name="prenom" type="string" />

    <property name="adresse" type="string" />

  </class>

  <sql-query name="getClientFromAuthentification_SP" callable="true">

    <return alias="client" class="model.entity.Client" >

        <return-property name="num_client" column="NUM_CLIENT"/>

        <return-property name="num_compte_epargne" column="NUM_COMPTE_EPARGNE"/>

        <return-property name="num_compte_courant" column="NUM_COMPTE_CLIENT"/>

        <return-property name="nom" column="NOM_CLIENT"/>

        <return-property name="prenom" column="PRENOM_CLIENT"/>

        <return-property name="adresse" column="ADRESSE_CLIENT"/>

    </return>

    { call getClientFromAuthentification(?, :login, :mdp) }

  </sql-query>

</hibernate-mapping>`
  

Когда я использую его :


`

 ArrayList<Client> clients;

 Query q = session.getNamedQuery("getClientFromAuthentification_SP");

 q.setString("login", "durant.jean");

 q.setString("mdp", "durant.jean1234");


 clients = (ArrayList<Client>) q.list();`
  

У меня нет ошибок, но, к сожалению, список пуст…

Помогите мне, пожалуйста

Ответ №1:

В хранимой процедуре используйте %NOTFOUND вместо %ROWCOUNT :

  • Вы должны использовать %rowcount только с неявными курсорами, которые выполняют вставку / обновление / удаление.
  • Вы должны использовать %notfound с SELECTs, чтобы посмотреть, возвращают ли они данные или нет. Например.

редактировать: весь процесс добавлен к ответу

 create or replace procedure getClientFromAuthentification(myCursorResult out sys_refcursor, login in VARCHAR2, pwd in VARCHAR2) as
num_client NUMBER(6);
compte_epargne VARCHAR2(50);
compte_courant VARCHAR2(50);
nom VARCHAR2(50);
prenom VARCHAR2(50);
adresse VARCHAR2(100);
begin
  open myCursorResult for
    select client.num_client, client.num_compte_epargne, client.num_compte_courant, 
client.nom_client, client.prenom_client, client.adresse_client
    from client 
    where client.login_client = login and client.mdp_client = pwd;
  fetch myCursorResult into num_client, compte_epargne, compte_courant, nom, prenom, adresse;
  if myCursorResult%NOTFOUND then 
    raise NO_DATA_FOUND;
  end if;
exception
    when NO_DATA_FOUND then raise_application_error(-20001, 'pas de résultats');
end getClientFromAuthentification;
  

Что касается всего дизайна:

  • Почему вы возвращаете что-то, заключенное в курсор, имеющий ровно одну строку?
  • Почему бы не использовать их в качестве параметра out:

    num_client, compte_epargne, compte_courant, nom, prenom, adresse

Комментарии:

1. Спасибо за ваш ответ, но давайте представим, что я хочу использовать курсор. Как это будет работать?

2. Это первая часть моего ответа! заменить %ROWCOUNT на %NOTFOUND . Позвольте мне помочь вам с этим, я добавляю это к своему ответу

3. Как вызвать исключение ‘TWO_MANY-ROWS’ с помощью NOTFOUND.

4. и, просто изменив rowcount на notfound, hibernate сможет отобразить курсор в моем списке объектов?

5. Если вы хотите вызвать ‘TWO_MANY-ROWS’, вы можете сделать это, либо попытавшись извлечь еще одну строку из курсора — вы вызываете ‘TWO_MANY-ROWS’, если вторая попытка извлечения была успешной ( if not myCursorResult%NOTFOUND then )