Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写SQL查询时遇到问题_Sql_Oracle - Fatal编程技术网

编写SQL查询时遇到问题

编写SQL查询时遇到问题,sql,oracle,Sql,Oracle,我在写查询时遇到问题。我有一个名为“MYTABLE”的支持表,它有一个名为“TABLENAME”的列,其中可以有一个或多个表名。多个表用逗号分隔 例如: TBLUSER TBLUSER, TBLACCOUNT 我正在尝试编写一个查询,该查询将标识MYTABLE表中任何不是数据库中有效表的条目。我能写下面的 SELECT * FROM MYTABLE T1 LEFT outer JOI

我在写查询时遇到问题。我有一个名为“MYTABLE”的支持表,它有一个名为“TABLENAME”的列,其中可以有一个或多个表名。多个表用逗号分隔

例如:

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中做到这一点)。

你真的需要重新考虑你的数据库设计。在一个表中的一条记录上保留多个条目,以跟踪这些条目,这是一个巨大的WTF

您需要更改您的设计,这样您就可以使用以下内容,而不是您所描述的内容:

ID    TABLENAME
----------------------
1     TBLUSER
2     TBLUSER
2     TBLACCOUNT
其中ID+Tablename是复合主键。这将使您编写的查询能够正常工作(尽管根据我上面提供的简单示例,该查询无法正常工作)


注意我知道这可能不是您在寻找的确切问题,但我觉得说出来很重要,因为未来的用户可能会发现这个问题,并且需要更好地了解数据库规范化实践(由于应用程序的现状,您可能无法做到这一点,因为“情况就是这样”)。

你需要重新考虑你的数据库设计。在一个表中的一条记录上保留多个条目,以跟踪这些条目是一个巨大的WTF

您需要更改您的设计,这样您就可以使用以下内容,而不是您所描述的内容:

ID    TABLENAME
----------------------
1     TBLUSER
2     TBLUSER
2     TBLACCOUNT
其中ID+Tablename是一个复合主键。这将使您编写的查询能够工作(尽管根据我上面提供的简单示例无法工作)


注意我知道这可能不是您在寻找的确切问题,但我觉得说出来很重要,因为未来的用户可能会发现这个问题,并且需要更好地了解数据库规范化实践(由于应用程序的现状,您可能无法做到这一点,因为”就是这样的”)。

您正在MYTABLE.TABLENAME中存储一个字符串,并尝试将其与ALL_TAB_COLS.TABLE_NAME中的一个字符串进行匹配(顺便说一句,我看不出有任何理由在本例中使用ALL_TAB_COLS而不是ALL_TABLE)

如果您的字符串是'TBLUSER,TBLACCOUNT',它将不会等于字符串'TBLUSER'或字符串'TBLACCOUNT'。这就是所有正在测试的表达式
upper(T1.TABLENAME)=upper(t2.Table_Name)
——这两个字符串相等吗?您似乎期望它不知何故“知道”“您的数据恰好是一个以逗号分隔的表名列表

使用字符串比较使您所做的工作正常的暴力方法是将条件更改为
,“|124; 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列将始终包含单个表的名称。

您正在MYTABLE.TABLENAME中存储一个字符串,并尝试将其与ALL_TAB_COLS.table_name中的一个字符串相匹配(顺便说一句,我看不出在本例中使用ALL_TAB_COLS而不是ALL_表的任何原因)

如果您的字符串是'TBLUSER,TBLACCOUNT',它将不等于字符串'TBLUSER'或字符串'TBLACCOUNT'。这就是表达式
upper(T1.TABLENAME)=upper(t2.Table\u Name)
正在测试的全部内容——这两个字符串相等吗?您似乎期望它以某种方式“知道”您的数据恰好是一个以逗号分隔的表名列表

使用字符串比较使您所做的工作正常的暴力方法是将条件更改为
,“|124; 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列始终包含单个表的名称。

简短的回答是:

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)||',')
       )
      )
选择distinct
atc.table_名称
从…起
mytable mt
,所有标签栏atc
其中atc.owner='SOMESCHEMA'
及(
mt.tablename=atc.table\U名称
或
(
0
大卫·科斯塔的帖子已经很好地描述了长答案。

短答案是:

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)||',')
       )
      )
选择distinct
atc.table_名称