2017-02-13 110 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