2008-11-25 8 views
8

Lors de l'exécution suivantes (complet) requête SQL sur Microsoft SQL Server 2000:erreur nom de la colonne Ambigu

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 

que je reçois l'exception suivante:

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

ce que je fais mal ici et comment puis-je le corriger?

+0

Vous pouvez vous débarrasser de chaque distinct dans votre requête. –

+0

En outre, il semble que vous avez construit une "Table de recherche True One", une erreur de conception de modélisation de données si commune qu'elle a son propre nom. Bien que je puisse me tromper, le motif semble Oh! Très famillier. Google ce terme. –

Répondre

24

Parce que ARTIFACTTYPE peut se référer soit A.ARTIFACTTYPE ou B.ARTIFACTTYPE et le serveur a besoin de savoir lequel vous voulez, changer juste à A.ARTIFACTTYPE et vous devriez être bien dans ce cas. Pour clarifier, vous devez spécifier le préfixe d'alias chaque fois que le nom de la colonne est ambigu. Ce n'est pas une mauvaise habitude de toujours utiliser les préfixes d'alias car cela permet de savoir quelles colonnes proviennent des tables lorsque vous lisez la requête, et élimine les problèmes comme celui-ci.

On peut se demander pourquoi vous avez besoin de distinguer entre deux colonnes que vous voulez quand elles se réfèrent à la même colonne dans la même table. La réponse est que lorsque vous joignez une table à lui-même, les valeurs de A.column et B.column peuvent être différentes selon les critères de jointure (comme cela peut être le cas avec une jointure externe où les valeurs dans l'une des colonnes peuvent être nul).

+0

Quel est le vote pour? –

+0

Parce que, selon ma propre réponse ci-dessous, je ne vois pas pourquoi quelque chose dans cette requête est ambigu. En particulier, je ne vois pas d'ARTIFACTTYPE non qualifié où l'ajout d'un A ou B aurait du sens. Votre explication de ce que signifie l'ambiguïté est très bien, mais je soupçonne que le PO comprend tout cela. –

+1

Merci Dave, après avoir examiné la requête plus attentivement, il ne semble pas y avoir d'ambiguïté bien que j'aie utilisé des bases de données très pointilleuses sur l'application d'alias, SQL Server pourrait être l'un d'entre eux. Dans tous les cas, quelle que soit la requête publiée, ma réponse répond clairement à l'erreur signalée. –

0

Pour être clair, ce sont les lignes 13, 14 et 15 qui ont les colonnes ambiguës.

+0

Pourquoi? Pourquoi ces lignes seraient-elles ambiguës, mais les lignes 5, 6 et 7 ne le seraient-elles pas? –

+0

Je pensais la même chose au début, mais après avoir regardé de plus près le code, je soutiendrais Dave sur ce – kristof

+0

Je ne sais pas pourquoi ces lignes sont ambiguës. Juste vous dire ce que MGMT studio dit. Le serveur db de 8 ans pourrait avoir quelque chose à voir avec cela. Je suppose que vous avez essayé ceci sur SQL Server 2000 comme l'affiche originale spécifiée. Merci pour les votes vers le bas sans même l'essayer sur sql 2000. – Logicalmind

2

Si c'est la requête exacte que vous exécutez, je ne sais pas pourquoi il trouverait quelque chose d'ambigu.

J'ai écrit ce que je pense être une requête équivalente et l'ai couru dans ma base de données (Oracle) sans problème.

EDIT Ajout de la sortie exacte d'une nouvelle expérience dans Oracle. La requête exécutée dans cette expérience est la requête exacte donnée par l'OP, avec le nom de la table renseigné. AUCUN AUTRE CHANGEMENT. Il n'y a rien d'ambigu dans cette requête. Donc, soit ce n'est pas la requête exacte en cours d'exécution, soit SQL Server a un bogue d'analyseur.

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 

Fin Modifier

Ma suggestion pour contourner l'erreur est de donner la table dans chaque clause select d'un alias unique et de qualifier toutes les références de colonne. Comme ceci:

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 
+0

Vous avez utilisé des noms d'alias là où l'OP ne l'a pas fait - c'est la raison pour laquelle c'est correct dans votre version - vous avez corrigé le problème. –

+0

Sean: La requête que j'ai écrite ci-dessus est ma suggestion à l'OP sur la façon de contourner son problème. Ce n'est pas ce que j'ai couru dans ma base de données. Deux pensées séparées. –

+0

Ajout d'un exemple concret montrant que je peux exécuter la requête EXACT de l'OP dans Oracle sans avoir d'erreur d'ambiguïté. –

1

Avez-vous l'énumération de la requête complète? Peut-être vous avez également la clause ORDER BY - qui pourrait causer ce problème

Je soutiens Dave on that that il devrait y avoir aucun problème avec la requête affichée

0

Vous devez spécifier les tables dans la clause ORDER BY, comme ceci:

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