不明确的列名称错误

时间:2008-11-25 16:49:13

标签: sql sqlexception

在Microsoft SQL Server 2000上执行以下(完整)SQL查询时:

SELECT B.ARTIFACTTNS, B.ARTIFACTNAME, B.ARTIFACTTYPE, B.INITIALBYTES, B.TIMESTAMP1, B.FILENAME, B.BACKINGCLASS, 
       B.CHARENCODING, B.APPNAME, B.COMPONENTTNS, B.COMPONENTNAME, B.SCAMODULENAME, B.SCACOMPONENTNAME 
FROM (SELECT DISTINCT A.ARTIFACTTYPE, A.ARTIFACTTNS, A.ARTIFACTNAME 
      FROM (SELECT DISTINCT ARTIFACTTYPE, ARTIFACTTNS, ARTIFACTNAME 
            FROM CUSTPROPERTIES WHERE PNAME = 'AcmeSystemName' AND PVALUE = 'MyRuleGroup' 
                  UNION SELECT DISTINCT ARTIFACTTYPE, ARTIFACTTNS, ARTIFACTNAME 
                          FROM CUSTPROPERTIES WHERE PNAME = 'AcmeSystemDisplayName' AND PVALUE = 'MyRuleGroup') A, 
           (SELECT DISTINCT ARTIFACTTYPE, ARTIFACTTNS, ARTIFACTNAME 
            FROM CUSTPROPERTIES WHERE PNAME = 'AcmeSystemTargetNameSpace' AND PVALUE = 'http://MyModule') B 
WHERE A.ARTIFACTTYPE = B.ARTIFACTTYPE AND A.ARTIFACTTNS = B.ARTIFACTTNS AND A.ARTIFACTNAME = B.ARTIFACTNAME) A, BYTESTORE B 
    WHERE (A.ARTIFACTTYPE = 'BRG') AND A.ARTIFACTTYPE = B.ARTIFACTTYPE AND A.ARTIFACTTNS = B.ARTIFACTTNS AND A.ARTIFACTNAME = B.ARTIFACTNAME 
    ORDER BY ARTIFACTTYPE, ARTIFACTTNS, ARTIFACTNAME

我得到以下异常:

java.sql.SQLException: [Acme][SQLServer JDBC Driver][SQLServer]
    Ambiguous column name 'ARTIFACTTYPE'.

我在这里做错了什么,如何纠正?

5 个答案:

答案 0 :(得分:24)

由于ARTIFACTTYPE可以引用A.ARTIFACTTYPEB.ARTIFACTTYPE,服务器需要知道您想要哪一个,只需将其更改为A.ARTIFACTTYPE即可。这种情况。

为了澄清,您需要在列名不明确时指定别名前缀。总是使用别名前缀是不错的做法,因为它可以在您阅读查询时清楚显示哪些列来自哪些表,并消除了类似这样的问题。

有人可能想知道为什么当它们都引用同一个表中的同一列时,你需要区分两列中的哪一列。答案是,当您将表连接到自身时,来自A.column和B.column的值可能会根据连接条件而有所不同(例如,可能是外连接的情况,其中一列中的值可能是空)。

答案 1 :(得分:2)

如果这是你正在运行的确切查询,我不知道它为什么会发现任何含糊不清的内容。

我写了一个我认为是等效查询并在我的数据库(Oracle)中运行它没有问题。

编辑在Oracle中添加新实验的确切输出。在此实验中执行的查询是OP给出的确切查询,其中填写了表名。 NO OTHER CHANGES 。这个查询没有任何含糊之处。所以,这不是正在执行的确切查询,或者SQL Server有解析器错误。

SQL> create table props (pname varchar2(100),
  2                       pvalue varchar2(100),
  3                       artifacttype number,
  4                       artifacttns number,
  5                       artifactname number);

Table created.

SQL> SELECT      
  2    DISTINCT A.ARTIFACTTYPE, A.ARTIFACTTNS, A.ARTIFACTNAME
  3  FROM
  4   (SELECT DISTINCT 
  5      ARTIFACTTYPE, 
  6      ARTIFACTTNS, 
  7      ARTIFACTNAME 
  8    FROM props 
  9    WHERE PNAME = 'AcmeSystemName' 
 10        AND PVALUE = 'MyRuleGroup' 
 11    UNION 
 12    SELECT DISTINCT 
 13      ARTIFACTTYPE, 
 14      ARTIFACTTNS, 
 15      ARTIFACTNAME 
 16    FROM props
 17    WHERE PNAME = 'AcmeSystemDisplayName' 
 18        AND PVALUE = 'MyRuleGroup') A, 
 19  (SELECT DISTINCT 
 20      ARTIFACTTYPE, 
 21      ARTIFACTTNS, 
 22      ARTIFACTNAME 
 23   FROM props 
 24   WHERE PNAME = 'AcmeSystemTargetNameSpace' 
 25      AND PVALUE = 'http://mymodule') B
 26  WHERE A.ARTIFACTTYPE = B.ARTIFACTTYPE 
 27      AND A.ARTIFACTTNS = B.ARTIFACTTNS 
 28      AND A.ARTIFACTNAME = B.ARTIFACTNAME
 29  /

no rows selected

结束修改

我解决这个错误的建议是为每个select子句中的表提供一个唯一的别名,并限定所有列引用。像这样:

SELECT
  DISTINCT A.ARTIFACTTYPE, A.ARTIFACTTNS, A.ARTIFACTNAME
FROM
 (SELECT DISTINCT 
    P1.ARTIFACTTYPE, 
    P1.ARTIFACTTNS, 
    P1.ARTIFACTNAME 
  FROM {PROPERTIES_TABLE_NAME} P1
  WHERE PNAME = 'AcmeSystemName' 
      AND PVALUE = 'MyRuleGroup' 
  UNION 
  SELECT DISTINCT 
    P2.ARTIFACTTYPE, 
    P2.ARTIFACTTNS, 
    P2.ARTIFACTNAME 
  FROM {PROPERTIES_TABLE_NAME} P2
  WHERE PNAME = 'AcmeSystemDisplayName' 
      AND PVALUE = 'MyRuleGroup') A, 
(SELECT DISTINCT 
    P3.ARTIFACTTYPE, 
    P3.ARTIFACTTNS, 
    P3.ARTIFACTNAME 
 FROM {PROPERTIES_TABLE_NAME} P3
 WHERE PNAME = 'AcmeSystemTargetNameSpace' 
    AND PVALUE = 'http://mymodule') B
WHERE A.ARTIFACTTYPE = B.ARTIFACTTYPE 
    AND A.ARTIFACTTNS = B.ARTIFACTTNS 
    AND A.ARTIFACTNAME = B.ARTIFACTNAME

答案 2 :(得分:1)

您是否列出了完整的查询? 也许您还有ORDER BY子句 - 这可能会导致该问题

我支持Dave on that that发布的查询应该没有问题

答案 3 :(得分:0)

要清楚,第13,14和15行是含糊不清的列。

答案 4 :(得分:0)

您需要在ORDER BY子句中指定表格,如下所示:

ORDER BY A.ARTIFACTTYPE, A.ARTIFACTTNS, A.ARTIFACTNAME