2009-04-23 119 views
0

我在寫查詢時遇到問題。我有一個名爲'MYTABLE'的支持表,它有一個名爲'TABLENAME'的列,它可以有一個或多個表名。多個表格用逗號分隔。無法寫入SQL查詢

例子:

TBLUSER 
TBLUSER, TBLACCOUNT 

我試圖寫一個查詢,將識別MyTable表不在數據庫中的有效表的任何條目。我能寫的後續....

     SELECT * 
         FROM MYTABLE T1 
      LEFT outer JOIN ALL_TAB_COLS T2 
         ON ( upper(T1.TABLENAME) = upper(t2.Table_Name) 
          AND T2.Owner = 'ME' 
          ) 
         WHERE TABLE_NAME IS NULL; 

而且它的工作原理正是我想要的 - 但是當MYTABLE的條目包含一個單一的表只適用。當有多個以逗號分隔的表格時 - 失敗。我的SQL技能有點缺乏,我的天生本能是'爲每個人做',但我覺得這不是正確的方法(我不知道如何在SQL中做到這一點)。

+0

爲什麼在世界上你會在單排上保留多個表格? – TheTXI 2009-04-23 19:57:30

+0

反向標準化,TheTXI。這是所有的憤怒。 – Welbog 2009-04-23 19:58:08

回答

2

你正在MYTABLE.TABLENAME中存儲一個字符串,並試圖將它與ALL_TAB_COLS.TABLE_NAME中的一個字符串進行匹配(這種情況下,我沒有看到任何理由在這種情況下使用ALL_TAB_COLS而不是ALL_TABLES)。

如果您的字符串是'TBLUSER,TBLACCOUNT',它不會等於字符串'TBLUSER'或字符串'TBLACCOUNT'。這就是所有的表達式upper(T1.TABLENAME) = upper(t2.Table_Name)正在測試 - 這兩個字符串是否相等?您似乎期待它能夠「知道」您的數據恰好是逗號分隔的表名列表。

蠻力的方法,使您使用字符串比較工作是將條件更改爲','||upper(T1.TABLENAME)||',' LIKE '%,'||upper(t2.Table_Name)||',%。所以你基本上會考慮TABLE_NAME是否是TABLENAME列值的子字符串。

但是,真正的一點是,這是一個不太好的數據庫設計。首先,從一個簡單的角度來看,爲什麼要命名一個「TABLENAME」列(單數),然後在其中添加代表多個表名的值?如果你打算這麼做,至少應該把它叫做「TABLENAMELIST」。

更重要的是,這通常不是我們在關係數據庫中做事的方式。如果您MYTABLE看起來是這樣的:

ID  TABLENAME 
1  TBLUSER 
2  TBLUSER, TBLACCOUNT 

然後設計表更合適的關係的方式是:

ID  TBL_NUM TABLENAME 
1  1   TBLUSER 
2  1   TBLUSER 
2  2   TBLACCOUNT 

那麼你的查詢將過去一樣工作,或多或少,因爲TABLENAME列將始終包含單個表的名稱。

3

你真的需要重新考慮你的數據庫設計。在應該跟蹤這些條目的表格中的一個記錄上保留多個條目是一個巨大的WTF。

你需要改變你的設計,這樣,而不是你描述你碰到這樣的:

ID TABLENAME 
---------------------- 
1  TBLUSER 
2  TBLUSER 
2  TBLACCOUNT 

其中ID + tablename是一個複合主鍵。這會讓你的查詢寫出來(儘管不是基於上面提供的裸機例子)。

注意我知道這可能不是你所期待的在您的具體問題,但我覺得不管怎樣說,這是重要的,因爲未來用戶可以來找這個問題,需要更好地理解數據庫規範化實踐(你可能無法做到,因爲應用程序是因爲「這就是它」)。

1

簡短的回答是:

select distinct 
    atc.table_name 
from 
    mytable mt 
,all_tab_cols atc 
where atc.owner = 'SOMESCHEMA' 
    and (
     mt.tablename = atc.table_name 
     or 
     (
     0 < instr(','||replace(upper(mt.tablename),' ','')||',' 
          ,','||upper(atc.table_name)||',') 
     ) 
    ) 

長的答案已經深受大衛·科斯塔的職位描述。