Неоднозначная ошибка имени столбца - PullRequest
8 голосов
/ 25 ноября 2008

При выполнении следующего (полного) запроса SQL на Microsoft SQL Server 2000:

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 ]

24 голосов
/ 25 ноября 2008

Поскольку ARTIFACTTYPE может относиться либо к A.ARTIFACTTYPE, либо к B.ARTIFACTTYPE, а сервер должен знать, какой из них вы хотите, просто измените его на A.ARTIFACTTYPE, и в этом случае все будет в порядке.

Чтобы уточнить, вам нужно указывать префикс псевдонима каждый раз, когда имя столбца неоднозначно. Неплохая практика - всегда использовать префиксы псевдонимов, так как при чтении запроса становится ясно, какие столбцы идут из каких таблиц и какие проблемы устраняются.

Можно задаться вопросом, почему вам нужно различать, какой из двух столбцов вы хотите, когда они оба ссылаются на один и тот же столбец в одной таблице. Ответ заключается в том, что когда вы присоединяете таблицу к себе, значения из A.column и B.column могут различаться в зависимости от критериев объединения (например, в случае внешнего объединения, где значения в одном из столбцов могут быть нуль).

2 голосов
/ 25 ноября 2008

Если это именно тот запрос, который вы выполняете, я понятия не имею, почему он нашел бы что-то неоднозначное.

Я написал, как мне кажется, эквивалентный запрос и без проблем запустил его в своей базе данных (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
  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
1 голос
/ 25 ноября 2008

Вы выводите полный запрос? Возможно, у вас есть также предложение ORDER BY - это может вызвать эту проблему

Я бы поддержал Дейв на том, что не должно быть проблем с опубликованным запросом

0 голосов
/ 09 января 2009

Вам необходимо указать таблицы в предложении ORDER BY, например:

ORDER BY A.ARTIFACTTYPE, A.ARTIFACTTNS, A.ARTIFACTNAME
0 голосов
/ 25 ноября 2008

Для ясности, это строки 13, 14 и 15, которые имеют неоднозначные столбцы.

...