2017-02-13 22 views
0

Я пытаюсь выполнить ниже запрос в Oracle:удалось продлить временный сегмент на 128 в табличной TEMP

SELECT DISTINCT 
    t4.s_studentreference "Student ID", 
    t3.p_surname "Surname", 
    t3.p_forenames "Forenames", 
t1.m_reference "Course", 
t2.e_name "Enrolment Name" 
FROM student t4, 
    person t3, 
    enrolment t2, 
    course t1 
WHERE t4.s_id(+) =t3.p_id 
AND (t2.e_student=t3.p_id) 
AND (t2.e_course =t1.m_id) 
AND (t1.m_reference LIKE 'LL563%15') 
OR (t1.m_reference LIKE 'LL562%15') 
OR (t1.m_reference LIKE 'LL563%16') 
OR (t1.m_reference LIKE 'LL562%16') 

Но, я получаю ниже ошибки:

ORA-01652: unable to extend temp segment by 128 in tablespace TEMP 
01652. 00000 - "unable to extend temp segment by %s in tablespace %s" 
*Cause: Failed to allocate an extent of the required number of blocks for 
      a temporary segment in the tablespace indicated. 
*Action: Use ALTER TABLESPACE ADD DATAFILE statement to add one or more 
      files to the tablespace indicated. 

я использовал ниже запроса для найти временный сегмент пространства:

select inst_id, tablespace_name, total_blocks, used_blocks, free_blocks 
from gv$sort_segment; 

дает:

INST_ID, TABLESPACE_NAME, TOTAL_BLOCKS, USED_BLOCKS, FREE_BLOCKS 
1   TEMP   3199872  15360   3184512 

Любая идея, как решить проблему?

Спасибо, Аруна

+1

Я думаю, что этот вопрос может быть лучше ответил на dba.stackexchange.com. – BriteSponge

+1

В сообщении об ошибке указано, какие действия необходимо предпринять. – OldProgrammer

+0

@OldProgrammer, это хороший пример, почему * иногда * принятие совета «Action» из сообщения об ошибке oracle не всегда обязательно является лучшим способом действия :) –

ответ

4

Хотя стандартный ответ на это было бы получить DBA продлить TEMP табличного, я думаю, что проблема заключается в запросе.

В частности, то, как вы написали предложение WHERE, предикаты. Я подозреваю, что первые три предиката предназначены для ваших предикатов соединения, а последние четыре должны ограничивать строки из таблицы курса, к которой они присоединены.

Однако, происходит то, что первые четыре предиката вычисляются сначала (поскольку И имеет приоритет над ИЛИ), и я подозреваю, что это вызывает некоторые проблемы с вашими объединениями - возможно, некоторые непреднамеренные перекрестные соединения, и это может быть неожиданно взрывает ваше табличное пространство TEMP.

Чтобы предотвратить это, у вас есть два возможных решения:

1. Уточнить свой Логическое И/ИЛИ с кронштейнами в правильных местах:

SELECT DISTINCT 
     t4.s_studentreference "Student ID", 
     t3.p_surname "Surname", 
     t3.p_forenames "Forenames", 
     t1.m_reference "Course", 
     t2.e_name "Enrolment Name" 
FROM student t4, 
     person t3, 
     enrolment t2, 
     course t1 
WHERE t4.s_id(+) = t3.p_id 
AND t2.e_student = t3.p_id 
AND t2.e_course = t1.m_id 
AND (t1.m_reference LIKE 'LL563%15' 
     OR t1.m_reference LIKE 'LL562%15' 
     OR t1.m_reference LIKE 'LL563%16' 
     OR t1.m_reference LIKE 'LL562%16'); 

Вышеуказанные группы все ИЛИ и вместе с ними помещаются в остальные предикаты.

2. Использование ANSI синтаксис объединения и выделить поисковые предикаты из предикаты:

SELECT DISTINCT 
     t4.s_studentreference "Student ID", 
     t3.p_surname "Surname", 
     t3.p_forenames "Forenames", 
     t1.m_reference "Course", 
     t2.e_name "Enrolment Name" 
FROM student t4, 
     RIGHT OUTER JOIN person t3 ON t4.s_id = t3.p_id 
     INNER JOIN enrolment t2 ON t3.p_id = t2.e_student 
     INNER JOIN course t1 ON t2.e_course = t1.m_id 
WHERE t1.m_reference LIKE 'LL563%15' 
OR  t1.m_reference LIKE 'LL562%15' 
OR  t1.m_reference LIKE 'LL563%16' 
OR  t1.m_reference LIKE 'LL562%16'; 

Конечно, последний не исключает использование скобок в нужном месте, когда вы» re работа с соединением ANDs и ORs в разделе where ...

Вариант 2 был бы моим предпочтительным решением - синтаксис ANSI join действительно является способом продвижения вперед в эти дни при написании SQL.

+0

Спасибо, Boneist. :) –

+0

Я на самом деле вижу это много, где люди преобразуют синтаксис внешнего соединения Oracle в синтаксис внешнего соединения ANSI и получают объединенные и предикаты, запутанные или неуместные. То, что у них получается, - это «объединение на константе», которое, хотя и синтаксически корректно, часто не является семантически необходимым. – BobC

+0

@BobC да; Я немного опасаюсь синтаксиса внешнего соединения ANSI, и обычно мне приходится сбивать тестовый пример, чтобы доказать, что он работает так, как я хочу, чтобы он работал!Или я внешнее соединение с подзапросом * {;-) – Boneist