2009-07-22 15 views
0

J'ai une page d'administration pour rechercher des produits à modifier, mais la page revient sans cesse l'erreur:erreur SQL Server « 80040e14 » nom de la colonne Ambigu

Microsoft OLE DB Provider for SQL Server error '80040e14' Ambiguous column name 'prod_id'. /__admin/searchproducts.asp, line 89

Je ne suis pas sûr pourquoi cette erreur est recadrage, car la page et le site sont une copie directe d'un autre site Web et de la base de données MSSQL associée, et la page du produit de recherche fonctionne sur ce site.

Ceci est le code en question (je ne sais pas si ce sera facile à lire ici);

if request("fldSubmitted") <> "" then 
if request("fldprodid") <> "" and isNumeric(request("fldprodid")) then 
    SQL = "select * from products where prod_id = " & cdbl(request("fldprodid")) 
else 
    SQL = "select " 
    if request("showtop") <> "all" then 
     SQL = SQL & " top " & request("showtop") & " " & replace(replace(request("orderby")," asc","")," desc","") & ", " 
    end if 
    SQL = SQL & "prod_name, prod_id, prod_code, prod_icon, prod_thumb, prod_numViews, prod_archived" 
    if request("fldLabel") <> "" then SQL = SQl & ", label_name" 
    if request("fldCat") <> "" then SQL = SQL & ", cat_name" 
    if request("fldSubcat") <> "" then SQL = SQL & ", subcat_name" 
    SQL = SQL & " from products" 
    if request("fldLabel") <> "" then SQL = SQL & ", labels" 
    if request("fldCat") <> "" then SQL = SQL & ", categories" 
    if request("fldSubcat") <> "" then SQL = SQl & ", subcategories" 
    sql = sql & " where 1=1" 
    if request("fldLabel")<> "" then SQL = SQL & "and prod_label = label_id " 
    if request("fldCat") <> "" then SQL = SQL & "and prod_category = cat_id " 
    if request("fldSubcat") <> "" then SQL = SQL & "and prod_subcategory = subcat_id " 
    if request("fldName") <> "" then SQL = SQL & " and (prod_name like '%" & replace(request("fldName"),"'","''") & "%')" 
    if request("fldCode") <> "" then SQL = SQL & " and (prod_code like '%" & replace(request("fldCode"),"'","''") & "%')" 
    if request("fldLabel") <> "" then SQL = SQL & " and prod_label = " & request("fldLabel") 
    if request("fldCat") <> "" then SQL = SQL & " and prod_category = " & request("fldCat") 
    if request("fldSubcat") <> "" then SQL = SQL & " and prod_subcategory = " & request("fldSubcat") 
    if request("fldArchived") = "No" then 
     SQL = SQL & " and prod_archived = 0" 
     if request("instock") = "No" then SQL = SQL & " and prod_numleft > 0" 
    end if 

    SQL = SQL & " order by " & request("orderby") 
end if 
+1

Je ne suis pas convaincu que le code serait facile à lire * n'importe où * :-) –

+0

Les "produits" sont-ils une vue ou une table? – gbn

+1

Beaucoup d'entrée de requête non testée étant directement ajoutée à une chaîne de requête, très risquée. – Andrew

Répondre

3

Dans la seconde moitié de la requête la vous pourrait éventuellement choisir parmi les tableaux produits, étiquettes, catégories et sous-catégories. Si l'une de ces tables a un prod_id, le SGBD ne saura pas à qui vous faites référence. Une simple révision est d'alias chaque table, par exemple les produits p, étiquettes l, etc.

encore mieux refacotoring serait de nous modifier la requête Jointures:

SELECT p.prod_name, l.label_name 
FROM products p 
JOIN labels l 
    ON l.label_id = p.label_id 
WHERE p.in_stock > 0 

Une autre astuce pour traiter ces les problèmes sont à response.write la chaîne SQL et copiez-le dans Management Studio à la place, cela vous aidera à voir passer la manipulation de la chaîne à l'erreur.

Enfin, je suggère de regarder Stored Procedures de sorte que vous pouvez supprimer le SQL de votre application.

Modifier

Faisant suite à une discussion dans les commentaires, si les procédures stockées sont hors de question alors parameterized query serait un bon pas en avant. Cela apportera un gain de performances car le plan de requête sera mis en cache et évite les formes les plus basiques d'attaque par injection SQL.

+0

@Keith - Je ne recommanderais pas d'utiliser des procédures stockées. – Liao

+0

@Liao Je pense qu'ils aideraient dans cette situation, ASP classique parlant à SQL Server. Que suggérez-vous plutôt? –

+0

Les programmeurs veulent rarement sp. C'est une chose de contrôle. – JeffO

0

Etes-vous sûr qu'il n'y a qu'une seule table avec une colonne nommée prod_id dans la liste des tables que vous utilisez dans la requête?

5

Le problème est que la requête sélectionnera la colonne prod_id, mais plus d'une des tables référencées a une colonne avec ce nom.

La requête renvoie les résultats de plusieurs tables, mais exactement dont la table dépend des valeurs des différents paramètres. Donc, cela pourrait expliquer pourquoi cela fonctionne dans une circonstance mais pas dans une autre.

Vous pouvez rendre la référence prod_id non ambiguë en la préfixant avec le nom de la table, par ex.

myTable.prod_id 

Je présume qu'il est assez évident (pour vous) quelle table est la bonne (bien sûr, il doit être une table qui est toujours partie de la requête, et non pas celui qui est là seulement sous certaines conditions).

0

Le code est un peu difficile à lire et à traiter, mais à moins que vous ne puissiez garantir que la même requête s'exécute à la fois dans les scénarios de travail et de non-fonctionnement, je le réduirai à cela.

Cette erreur apparaît généralement lorsque vous avez plusieurs tables ou vues dans votre requête portant le même nom de colonne et que vous n'avez pas indiqué explicitement celle que vous vouliez utiliser. Vous devriez avoir l'habitude de préfixer toutes les colonnes avec la table/vue s'il y en aura plus qu'une pour éviter l'ambiguïté.

EDIT: dans cet exemple, de toute évidence votre table de produits a un prod_id mais vous serez probablement en mesure de confirmer que les étiquettes, les catégories ou sous-catégories a également une colonne prod_id

0

Merci pour toutes les réponses. Désolé de ne pas avoir répondu bientôt, mais je n'ai reçu aucune alerte pour dire que les gens avaient répondu. Lol.

Je semble avoir corrigé l'erreur maintenant. J'ai enlevé 'prod_id' de la ligne suivante; SQL = SQL & "prod_name, prod_id, prod_code, prod_icon, prod_thumb, prod_numViews, prod_archived"

semble fonctionner bien maintenant. Un peu étrange que l'autre site fonctionne avec exactement le même code, mais tous triés maintenant. : D

Encore une fois, merci beaucoup pour les réponses. Très apprécié.

+0

tout ce que vous deviez faire était de changer "prod_id" pour dire "products.prod_id" et ça aurait marché. – Hogan

+0

êtes-vous sûr que cette demande de test ("fldprodid") <> "" et isNumeric (request ("fldprodid")) a le même résultat sur le site qui fonctionne et celui que vous testez. – Hogan

Questions connexes