Как увидеть фактический оператор SQL SQL, который выполняется
Я использую собственное встроенное приложение, которое генерирует стандартный набор отчетов на еженедельной основе. У меня нет доступа к исходному коду приложения, и все говорят, что для схемы базы данных Oracle нет документации. (Aargh!)
Мне было предложено определить спецификации для варианта существующего отчета (например, применить дополнительные фильтры для ограничения набора данных и немного изменить макет). В принципе это звучит достаточно просто, но сложно без какой-либо существующей документации.
Я понимаю, что журналы не могут помочь мне, потому что отчет запрашивает только базу данных; он фактически не вставляет, не удаляет или не обновляет значения базы данных, поэтому ничего не записывать (это правильно?).
Итак, мой вопрос заключается в следующем: есть ли инструмент или утилита (Oracle или иначе), которые я могу использовать, чтобы увидеть фактический оператор SQL, который выполняется во время выполнения задания генерации отчета? Я полагаю, что если я увижу, какие таблицы фактически доступны для создания существующего отчета, у меня будет очень хорошая отправная точка для изучения схемы и определения правильного SQL для моего собственного отчета.
Ответы
Ответ 1
На стороне словаря данных есть много инструментов, которые вы можете использовать, например Schema Spy
Чтобы посмотреть, какие запросы запущены, просмотрите представления sys.v_ $sql и sys.v_ $sqltext. Вам также потребуется доступ к sys.all_users
Следует отметить, что запросы, которые используют параметры, будут отображаться один раз с такими типами, как
and TABLETYPE=’:b16’
в то время как другие, которые не будут отображаться несколько раз, например:
and TABLETYPE=’MT’
Примером этих таблиц в действии является следующий SQL, чтобы найти 20 лучших свиней. Вы можете изменить это, удалив WHERE rownum <= 20 и, возможно, добавив ORDER BY module. Вы часто обнаруживаете, что модуль даст вам представление о том, какое программное обеспечение выполняет запрос (например: "TOAD 9.0.1.8", "Тонкий клиент JDBC", "runcbl @somebox (TNS V1-V3)" и т.д.)
SELECT
module,
sql_text,
username,
disk_reads_per_exec,
buffer_gets,
disk_reads,
parse_calls,
sorts,
executions,
rows_processed,
hit_ratio,
first_load_time,
sharable_mem,
persistent_mem,
runtime_mem,
cpu_time,
elapsed_time,
address,
hash_value
FROM
(SELECT
module,
sql_text ,
u.username ,
round((s.disk_reads/decode(s.executions,0,1, s.executions)),2) disk_reads_per_exec,
s.disk_reads ,
s.buffer_gets ,
s.parse_calls ,
s.sorts ,
s.executions ,
s.rows_processed ,
100 - round(100 * s.disk_reads/greatest(s.buffer_gets,1),2) hit_ratio,
s.first_load_time ,
sharable_mem ,
persistent_mem ,
runtime_mem,
cpu_time,
elapsed_time,
address,
hash_value
FROM
sys.v_$sql s,
sys.all_users u
WHERE
s.parsing_user_id=u.user_id
and UPPER(u.username) not in ('SYS','SYSTEM')
ORDER BY
4 desc)
WHERE
rownum <= 20;
Обратите внимание, что если запрос длинный, вам нужно будет запросить v_ $sqltext. В этом сохранен весь запрос. Вам нужно будет найти ADDRESS и HASH_VALUE и забрать все части. Например:
SELECT
*
FROM
sys.v_$sqltext
WHERE
address = 'C0000000372B3C28'
and hash_value = '1272580459'
ORDER BY
address, hash_value, command_type, piece
;
Ответ 2
Извините за короткий ответ, но уже поздно. Google "oracle event 10046 sql trace". Лучше всего проследить отдельный сеанс, потому что вычисление того, какой SQL принадлежит тому, какой сеанс из v $sql нелегко, если он является общим SQL и используется несколькими пользователями.
Если вы хотите произвести впечатление на своих друзей Oracle DBA, узнайте, как установить трассировку oracle с событием 10046, интерпретируйте смысл событий ожидания и найдите пользователей верхнего уровня.
У Quest был бесплатный продукт, который позволил вам захватить SQL, когда он вышел с клиентской стороны, но не уверен, что он работает с вашим продуктом/версией Oracle. Google "квест oracle sql monitor" для этого.
Спокойной ночи.
Ответ 3
Я думаю, что таблица V $SQLAREA содержит то, что вы ищете (см. столбцы SQL_TEXT и SQL_FULLTEXT).
Ответ 4
Да, это определенно возможно. Представления v $sql содержат эту информацию. Что-то вроде этот фрагмент кода должен указывать на вас в правильном направлении. Я сам не пробовал эту часть кода - нигде рядом с Oracle DB прямо сейчас.
[Edit] Прокляните еще два ответа. В следующий раз нужно набирать скорость; -)
Ответ 5
- я использую что-то вроде этого, с концепциями и некоторым кодом, украденным из аштома.
- предложения по улучшению приветствуются
С
sess AS
(
SELECT *
ОТ V $SESSION
WHERE USERNAME = USER
ORDER BY SID
)
SELECT si.SID,
si.LOCKWAIT,
si.OSUSER,
si.PROGRAM,
si.LOGON_TIME,
si.STATUS,
(
SELECT ROUND (USED_UBLK * 8/1024,1)
FROM V $TRANSACTION,
Sess
WHERE sess.TADDR = V $TRANSACTION.ADDR
И sess.SID = si.SID
) rollback_remaining,
(
SELECT (MAX (DECODE (PIECE, 0, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 1, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 2, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 3, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 4, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 5, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 6, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 7, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 8, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 9, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 10, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 11, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 12, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 13, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 14, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 15, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 16, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 17, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 18, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 19, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 20, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 21, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 22, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 23, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 24, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 25, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 26, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 27, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 28, SQL_TEXT, NULL)) ||
MAX (DECODE (PIECE, 29, SQL_TEXT, NULL)))
FROM V $SQLTEXT_WITH_NEWLINES
WHERE ADDRESS = SI.SQL_ADDRESS AND
PIECE < 30
) SQL_TEXT
FROM sess si;
Ответ 6
У меня была аналогичная проблема в приложении Java. Я написал оболочку драйвера JDBC вокруг драйвера Oracle, поэтому весь вывод отправляется в файл журнала.