2009-04-23 217 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)||',') 
     ) 
    ) 

长的答案已经深受大卫·科斯塔的职位描述。