#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
)