Литеральные версии курсоров могут быть получены с использованием данных из GV $ SQL_BIND_CAPTURE. По моему опыту, метаданные привязки Oracle bind не всегда доступны; приведенный ниже код работает с образцом курсора, но может быть недостаточно прочным для работы со всем кодом.
Пример схемы, уникальная строка
Изменить исходный код и добавить уникальные идентификаторы запросов, чтобы они могли быть программно выбран. Используйте подсказку, потому что анализируемая версия запроса не будет содержать регулярные комментарии. Я изменил типы данных, чтобы включить строки и даты, чтобы сделать пример более реалистичным.
drop table test1 purge;
create table test1(col1 number, col2 varchar2(100), col3 date);
create or replace procedure test_procedure is
C_Constant constant date := date '2000-01-01';
v_output1 number;
v_output2 varchar2(100);
v_output3 date;
CURSOR cFunnyCursor (
v1 NUMBER,
v2 VARCHAR2
) IS
SELECT /*+ unique_string_1 */ * FROM TEST1
WHERE col1 = v1
AND col2 != v2
AND col3 = C_CONSTANT;
begin
open cFunnyCursor(3, 'asdf');
fetch cFunnyCursor into v_output1, v_output2, v_output3;
close cFunnyCursor;
end;
/
Промойте Shared Pool
Oracle захватывает только первый экземпляр связываемых переменных. Запустите этот оператор перед запуском процедуры для очистки существующих данных привязки.
alter system flush shared_pool;
Запуск процедуры испытания
begin
test_procedure;
end;
/
PL/SQL блок для генерации SQL Буквенный
--Print a query with literals instead of binds.
declare
--Change this to match the query.
v_unique_string varchar2(100):= 'unique_string_1';
v_sql_id varchar2(100);
v_sql_text clob;
begin
--Get the SQL_ID and text.
select sql_id, sql_fulltext
into v_sql_id, v_sql_text
from gv$sql
where lower(sql_text) like '%'||v_unique_string||'%'
and sql_text not like '%quine%';
--Loop through the binds.
for binds in
(
select *
from gv$sql_bind_capture
where sql_id = v_sql_id
--Match longest names first to avoid matching substrings.
--For example, we don't want ":b1" to be matched to ":b10".
order by length(name) desc, position
) loop
--Convert the value from a string to a literal.
if binds.datatype_string = 'NUMBER' then
v_sql_text := replace(v_sql_text, binds.name, binds.value_string);
elsif binds.datatype_string like 'VARCHAR2%' then
v_sql_text := replace(v_sql_text, binds.name, ''''||binds.value_string||'''');
--Adjust this to match your server date format.
elsif binds.datatype_string like 'DATE%' then
v_sql_text := replace(v_sql_text, binds.name, 'to_date('''||binds.value_string||''', ''MM/DD/YYYY HH24:MI:SS'')');
--TODO: Add more types here.
end if;
end loop;
--Remove the unique string so it's not re-run with the literal version.
v_sql_text := replace(v_sql_text, v_unique_string, null);
--Print the SQL.
dbms_output.put_line(v_sql_text);
end;
/
Результат
SELECT /*+ */ * FROM TEST1 WHERE COL1 = 3 AND COL2 != 'asdf' AND COL3 = to_date('01/01/2000 00:00:00', 'MM/DD/YYYY HH24:MI:SS')
К сожалению, он потерял все форматирование. Это не так просто. Если это огромная сделка, вы можете создать что-то, используя PL/Scope, чтобы заменить переменные в процедуре, но у меня такое чувство, что это было бы смешно сложно. Надеемся, что у вашей среды IDE есть улучшитель кода.
Я все равно должен был бы войти в процедуру и скопировать/вставить все эти переменные в приглашение и поставить: infront каждой переменной. Это не намного быстрее, чем выбор имени переменной с помощью мыши -> ctfl + f, поиск/замена и установка правильной переменной. Мне нужно что-то, что делает эту замену для меня. – aLpenbog
Я согласен с вами относительно замены, это не сэкономит вам много времени ... в первый раз, когда вы это сделаете. Но если вам нужно довольно часто отлаживать эти запросы, я бы сохранил отладочную версию запроса (т. Е. Со всеми: »на месте), и значения запоминаются из предыдущего прогона (в любом случае, Toad) – Boneist
Моя проблема заключается в ситуации, когда клиент звонит, потому что что-то не работает. Я понимаю, что запись/строка не находится внутри набора записей, и я должен выяснить, почему. У нас есть тонна действительно больших грязных курсоров в нашей базе данных с s..load переменных. Так что мне нужно 30 минут, чтобы заменить переменные и как 30 секунд, чтобы прокомментировать некоторые строки, чтобы выяснить проблему. Эта ситуация не очень удовлетворяет, поэтому мне нужно обходное решение. – aLpenbog