Есть более простой способ сделать это; просто возьмите время начала, прежде чем начать, и снимите его с текущего времени, когда вы закончили.
create or replace procedure measureTime (statement IN varchar2 )AS
l_start_time timestamp default systimestamp;
BEGIN
dbms_output.enable;
EXECUTE IMMEDIATE statement;
COMMIT;
dbms_output.put_line('executeTime '|| systimestamp - l_start_time);
END measureTime;
В качестве альтернативы, если вы хотите за считанные секунды, скажите systimestamp - l_start_time
на trunc((systimestamp - l_start_time) * 24 * 60 * 60)
Это похоже на переутомленный способ действовать. execute immediate
будет немного медленнее, так как Oracle должен проверить запрос, прежде чем он сможет выполняться каждый раз Почему вы не просто выполняете запрос?
commit
также будет фиксировать все, что произошло в этом сеансе, что может быть не тем, что вы хотите.
Вам также следует убедиться, что вы правильно экранировали statement
, чтобы избежать внедрения SQL.
В ответ на ваш вопрос:
Ваша процедура не скомпилировалась бы, так как вам нужна была точка с запятой после execute immediate
. Это должно не быть включено в параметр statement
.
Ваш синтаксис для выбора также неверен. Поскольку это PL / SQL, а не SQL, вам нужно использовать into в предложении , и в конце этого оператора вы также пропустили точку с запятой.
select elapsed_time
into neededTime
from v$sql
where sql_text = statement;
Даже без синтаксических ошибок, например, ваш оператор может не работать, например, sql_text
в v$sql
содержит только первые 1000 символов, поэтому, если statement
имеет длину более 1 КБ не будет никакого совпадения. Если у вас есть предложение group by
, то, согласно документации, статистика не сохраняется.