Поэтому у меня есть приложение, которое проверяет запросы SQL SELECT на определенный ответ.
Сейчас он сравнивает результирующие наборы двух запросов с помощью некоторых циклов FOR из PHP. Он ищет каждый столбец из определенного запроса и пытается найти его во входном запросе;
Есть ли способ проверить это на уровне оракула?
Пример: скажем, у нас есть следующая таблица
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 13-JUL-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 13-JUL-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10
Определенный ответ:
SELECT ENAME, JOB FROM EMP WHERE DEPTNO=20;
Входной ответ:
SELECT * FROM EMP WHERE DEPTNO=20;
Эти два запроса более руд менее эквивалентны по выбранным строкам.
Как я могу проверить этот факт?
Что я пробовал:
Какие-либо предложения?
Заранее спасибо.
В какой-то степени это зависит от того, какую информацию вы готовы полагаться на свое приложение для предоставления, и на что вы надеетесь извлечь динамически. Это также зависит от того, как вы должны задать вопрос Oracle.
Если идея состоит в том, что вы построите запрос, включающий ссылочный запрос и входной запрос, и сообщите, соответствуют ли они, и если вы готовы полагаться на приложение, предоставляющее явный список столбцов, и если одна из вещей вам нужна чтобы проверить метки столбцов набора результатов, и если вам не нужен порядок столбцов или строк, вы можете сделать это следующим образом:
WITH
expected AS (
-- select all the expected columns, plus a count
SELECT ENAME, JOB, COUNT(*) AS count FROM (
-- the standard query to test against
SELECT ENAME, JOB FROM EMP WHERE DEPTNO=20
) reference
-- group by all the columns of the result
GROUP BY ENAME, JOB
),
observed AS (
-- choose only the expected columns (Oracle will barf if any are not present),
-- plus a count
SELECT ENAME, JOB, COUNT(*) AS count FROM (
-- the query whose results are to be tested
SELECT * FROM EMP WHERE DEPTNO=20
) user_specified
-- group by all the columns of the reference result
GROUP BY ENAME, JOB
)
SELECT COUNT(*) as differences
FROM (
(
SELECT * FROM expected
MINUS
SELECT * FROM observed
)
UNION ALL
(
SELECT * FROM observed
MINUS
SELECT * FROM expected
)
) differing_rows
Это в значительной степени шаблонный. Вы включаете весь ссылочный запрос в одном месте, весь запрос ввода в другом и (тот же) ожидаемый список столбцов в четырех отдельных местах. Результат запроса - это одна строка с одним столбцом, содержащим значение 0, если результаты запроса точно совпадают для интересующих столбцов (игнорируя порядок столбцов и строк) или значение больше нуля в противном случае. В случае, если запрос компонента возвращает повторяющиеся строки, общий результат проверяет, возвращают ли оба числа одинаковое количество копий каждой повторяющейся строки.
SELECT ENAME name, JOB FROM emp WHERE DEPTNO=20
; Если на входе есть псевдонимы? Как я могу обобщить?