2017-02-13 42 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,这是一个很好的例子,为什么*有时*从oracle错误消息中获取“Action”的建议并不总是最好的行动方式:) –

回答

4

虽然这个标准的答案会是让你的DBA延长TEMP表空间,我认为问题出在你的查询。

具体来说,就是您编写WHERE子句谓词的方式。我怀疑前三个谓词是你的连接谓词,最后四个是为了限制正在连接的课程表中的行。

但是,发生的情况是前四个谓词首先被计算(因为AND优先于OR),并且我怀疑这会对您的连接造成一些问题 - 可能是一些意外的交叉连接,这可能是什么意外地炸毁了你的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'); 

以上组中的所有OR:

1.在正确的地方括号说明你与/或逻辑一起陈述,然后将它们与其他谓词进行AND运算。

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'; 

当然,后者没有当你排除使用括号在正确的地方重新使用where子句中的AND和OR的组合...

选项2将成为我的首选解决方案 - ANSI连接语法的确是当今编写SQL时的前进方向。

+0

谢谢Boneist。:) –

+0

我真的看到了很多,其中人们将Oracle外部连接语法转换为ANSI外部连接语法,并且使连接和谓词混淆或错位。他们最终得到的是“常量上的连接”,尽管语法上有效,但在语义上通常不是必需的。 – BobC

+0

@BOBC是啊;我对ANSI外连接语法有点谨慎,我通常不得不打开一个测试用例来证明它按我希望的方式工作!或者我外连接到一个子查询* {;-) – Boneist