SQL Server error '80040e14' Ambiguous column name - sql

I have an admin page to search for products to edit, but the page keeps returning the error:
Microsoft OLE DB Provider for SQL Server error '80040e14' Ambiguous
column name 'prod_id'. /__admin/searchproducts.asp, line 89
I'm unsure why this error is cropping up, because the page and site is a direct copy of another website and associated MSSQL database and the search product page works on that site.
This is the code in question (not sure if it will be easy to read here though);
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

The problem is that the query will select the column prod_id, but more than one of the tables referenced has a column with that name.
The query returns results from more than one table, but exactly which table depends on the values of the various parameters. So, that might explain why it works in one circumstance but not another.
You can make the prod_id reference unambiguous by prefixing it with the table name, e.g.
myTable.prod_id
I presume it's fairly obvious (to you) which table is the right one (of course it has to be a table that's ALWAYS part of the query, not one that's only there under certain conditions).

In the second half of the query the you could possibly select from the tables products, labels, categories and subcategories. If any of these tables have a prod_id the DBMS won't know which one you are referring to. A simple revision is to alias each table, e.g products p, labels l, etc.
An even better refacotoring would be to alter the query to us joins:
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
One other tip when dealing with these problems is to response.write the SQL string and copy it in to Management Studio instead, this will help you see passed the string manipulation to the error.
Finally, I would suggest looking at Stored Procedures so you can remove the SQL from your application.
Edit
Following on from some chat in the comments, if Stored Procedures are out of the question then a parameterized query would be a good step forward. This will bring a performance gain as the query plan will be cached and avoids the most basic forms of SQL Injection attack.

Are you sure that there is only one table with a column named prod_id in the list of tables that you're using in the query?

The code is a little difficult to read and work through but unless you can guarantee the same query runs in both the working and non-working scenarios then I would put it down to that.
This error is usually seen when you have more than one table or view in your query with the same column name and have not explicitly said which one you wanted to use. You should get in the habit of prefixing all columns with the table/view if there is going to be more than one to avoid ambiguity.
EDIT: in this example, obviously your products table has a prod_id but you'll probably be able to confirm that labels, categories or subcategories also has a prod_id column

Thank you for all of the replies. Sorry for not replying soon, but I haven't received any alerts to say that people had replied. Lol.
I seem to have fixed the error now. I removed 'prod_id' from the following line;
SQL = SQL & "prod_name, prod_id, prod_code, prod_icon, prod_thumb, prod_numViews, prod_archived"
Seems to work okay now. A little odd that the other site works with the exact same code, but all sorted now. :D
Once again, many thanks for the replies. Very much appreciated.

Related

SQL Server Join Tables By Combining 2 Columns

This sounds ridiculously easy but I've tried so many different approaches. This query is just set up weird and I'm trying to JOIN it but there's not a common column I can do that with. There is, however, a LastFirst column (consists of LastName then FirstName) written in the context of DOE, JOHN. Then on the columns I'm trying to join that with it's just FirstName (John) and LastName (Doe).
I'm actually trying to select data from 4 tables that all are returning 1 row. These 2 tables can be joined:
SELECT
RIFQuery.*,
_Employee.EmployeeLastName + ', ' + _Employee.EmployeeFirstName AS EmployeeLastFirst,
_Employee.EmployeeTitle, _Employee.Phone As EmployeePhone,
_Employee.EmailAddress As EmployeeEmailAddress
FROM
RIFQuery
INNER JOIN
_Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE
RIFQuery.Autonumber = 1
This one has nothing to join with so I'll probably union it and null remaining columns:
SELECT *
FROM tblOrganization
This is the table that contains LastName and FirstName that I'm trying to join with RIFQuery.LastFirst:
SELECT
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM
_Clients
WHERE
_Clients.LASTNAME = left(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst)))
AND _Clients.FIRSTNAME = ltrim(substring(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst))+2, len(RIFQuery.LastFirst)))
In that WHERE statement the code will split the LastFirst column and get the row by searching their LastName and FirstName. I'm wondering if there's a way I can write that into a JOIN? Otherwise I can probably UNION and null remaining columns but it will look very ugly.
UPDATE
I tried 2 suggestions from here and both result in a syntax error. I forgot to mention that I'm executing this code inside Microsoft Access VBA and trying to retrieve a DAO.RecordSet. I had to remove some table names in the SELECT statement to get past a syntax error from there, so maybe I should update the question to reflect MS ACCESS and not SQL Server, although only the query is the only pure Access object and the rest are linked ODBC tables to SQL Server.
UPDATE
Just one of those issues where I can't sleep until it's fixed and will obsess until it is. If I take out all _Employee references (from SELECT and JOIN statements), it wants to work but errors about too few parameters. I just now know this is related to _Employee. Getting different results from applying parentheses and just hoping I'll get lucky and hit on it.
The error is caused by this line:
INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy]
I get this error:
"Syntax error (missing operator) in query expression".
As seen in this screenshot:
Here's my latest query I'm playing with, minus the parentheses:
str = "SELECT [RIFQuery].*, " & vbCrLf & _
" ([_Employee].[EmployeeLastName] & ', ' & [_Employee].[EmployeeFirstName]) AS [EmployeeLastFirst], " & vbCrLf & _
" [_Employee].[EmployeeTitle], " & vbCrLf & _
" [_Employee].[Phone] AS [EmployeePhone], " & vbCrLf & _
" [_Employee].[EmailAddress] AS [EmployeeEmailAddress], " & vbCrLf & _
" [_Clients].[Gender] AS [ClientGender], " & vbCrLf & _
" [_Clients].[DOB] AS [ClientDOB], " & vbCrLf & _
" [_Clients].[SSN] AS [ClientSSN] " & vbCrLf & _
"FROM [_Clients] " & vbCrLf & _
" INNER JOIN [RIFQuery] ON [RIFQuery].[LastFirst] = [_Clients].[LASTNAME] & ', ' & [_Clients].[FIRSTNAME] " & vbCrLf & _
" INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy] " & vbCrLf & _
"WHERE [RIFQuery].[Autonumber] = 1;"
For debugging purposes, if I remove those last 2 lines and the _Employee SELECT statements, it'll process the query without a problem. If anyone has any ideas just let me know.
I was focused on that RIFQuery JOIN statement being the culprit for the longest time but I've found that simply is not the issue any more. With that said, this thread has been essentially solved and I appreciate the help.
MS Access is using a slightly different syntax than SQL Server when it comes to using more than one JOIN. You could leave out the JOIN with the _Clients (making it a cross join) and move that condition to the WHERE clause, which would make the query look like this (and which would allow you to display the design window for the query without any problem)
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME;
Instead of assembling the query string in VBA just for being able to change the parameter value, I suggest to save the following query as an Access object (maybe qryRIF):
PARAMETERS lgRIF Long;
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME
AND RIFQuery.Autonumber = [lgRIF];
In your VBA code, you can use code like the following to grab the QueryDef object, assign the parameter value and open a recordset:
With CurrentDb.QueryDefs!qryRIF
!lgRIF = lgRIF
With .OpenRecordset()
' ... your code ...
.Close
End With
.Close
End With

MS-Access - you tried to execute a query that does not include the specified aggregate function, Any other solution?

SQL = "TRANSFORM FIRST(a.TimeStamp1) "
SQL = SQL & "SELECT a.DealName, DealList.SettlementDate "
SQL = SQL & "FROM DealList, DealStepLog a INNER JOIN DealStepMasterData b on b.StepName = a.DealStep "
SQL = SQL & "WHERE b.StepClassification = 'Compliance' "
SQL = SQL & "GROUP BY DealName "
SQL = SQL & "PIVOT dealStep "
I know I have to put 'SettlementDate' in GROUP BY section but I dont want to group by settlementDate, any other options??
Then you will have to use one of the aggregating functions, for example one of these:
First(SettlementDate)
Last(SettlementDate)
Max(SettlementDate)
Avg(SettlementDate)
Min(SettlementDate)

Excel ODBC SQL Statement Throwing Error '[ODBC EXCEL Driver] Data Type Mismatch in criteria

The SQL statement below inserts values into a new table, in a new sheet (TempPoints). If I remove the last part of the statement (in bold) the query runs OK however when I add it back in to the statement I receive the following error message; '[ODBC EXCEL Driver] Data Type Mismatch in criteria'.
I have replicated the tables and query in SQLServer and it runs OK and as expected which proves the full statement is OK. Is this a limitation of the Excel ODBC driver??
Thank you in advance.
strSQL = "INSERT INTO [TempPoints$] (REFP, PointItemRef, LoadItemRef, PointDES, Iotype, Subtype, Notes) " & _
"SELECT " & tempref & ", [PointsDB$].ItemRef, [LoadstoPointsDB$].LoadRef, [PointsDB$].PointDES, [PointsDB$].Iotype, [PointsDB$].Subtype, [PointsDB$].Notes " & _
"FROM [LoadsToPointsDB$] INNER JOIN [PointsDB$] ON [LoadsToPointsDB$].PointRef = [PointsDB$].ItemRef " & _
"WHERE [LoadsToPointsDB$].LoadRef = " & moditemref & " AND [PointsDB$].SystemComp = 'Y' " & _
**"AND NOT EXISTS (SELECT * FROM [TempPoints$] WHERE [TempPoints$].PointItemRef = [PointsDB$].ItemRef)"**
Thank you for those that viewed this, but I seem to have found the answer.
There is a previous insert into statement that loads data in the table, once the data was being loaded into it, the table was storing the numbers as text and not integers. After removing the rows and ensuring the format of the columns was set to integer the SQL query began to function as expected.

How to use a table field as a parameter of a function?

I'm trying to do something like this in an Access module:
sql = "UPDATE Carrera "
sql = sql & "SET Carrera.[carnombre]= '" & strFunction(Carrera.[CarreraNombre]) & "' "
sql = sql & "WHERE Carrera.[CarreraNombre]='ANIMACION';"
MsgBox (sql)
Application.CurrentDb.Execute (sql)
but I get the error "has not defined the variable" and has highlighted Carrera in strFunction(Carrera.[CarreraNombre]). If I use any other string the update works. How to use the field Carrera.[CarreraNombre] as a parameter for strFunction() that returns a string?
Carrera.[CarreraNombre] only has a value when the SQL query is being executed. You are asking VBA to call strFunction() while you are building the string, and VBA has no idea what Carrera.[CarreraNombre] means. I believe you want to do this:
sql = sql & "SET Carrera.[carnombre] = strFunction(Carrera.[CarreraNombre]) "

VBScript not executing sql statment properly

I write you this time because a VBScript that one of the application my company uses to retrieve information from an Oracle database does not seem to be working properly. Here are the facts:
There's part of the code that does the following:
sSql = "SELECT REQ_PAYMODE" & _
" FROM SYSADM.GBPRESTATIEGROEP" & _
" WHERE 1=1" & _
" AND SLEUTEL = " & sKeyPrestatiegroep
Set oRSGBPrest = connADO.execute(sSql)
If Not oRSGBPrest.EOF Then
sRequestPaymodeKey = oRSGBPrest("REQ_PAYMODE")
Else
//error handling
End If
Using a Statement Tracer for Oracle (www.aboves.com) I can capture that same statement with its corresponding value:
SELECT REQ_PAYMODE FROM
SYSADM.GBPRESTATIEGROEP WHERE 1=1 AND
SLEUTEL = 1572499
Now, the VBScript is supposed to take that value and execute another query:
sSql = "SELECT PAM_CODE" & _
" FROM SYSADM.PAYMODES" & _
" WHERE 1=1" & _
" AND PAM_KEY = " & sRequestPaymodeKey
Set oRSPaymodes = connADO.execute(sSql)
Right in this last line of code, the script throws an error that says:
ORA-00936: missing expression at line XXX --> Set oRSPaymodes = connADO.execute(sSql) <--
Which basically means that the query in (3) is not correct, which also means that for some reason sRequestPaymodeKey is empty. I cannot tell this for sure because this failing sql statement does not appear in the statement tracer, but that's the only explanation I could find. However, the worst part is that when running the query (2) on SQLDeveloper (that's where value sRequestPaymodeKey comes from) it shows a row with a value other than null or zero.
I can't think of anything else that might be happening here, maybe it's just a server thing... no idea.
Any suggestions from you guys? Any way I can actually debug a VBE file?
Your help is much appreciated!
You need to cast sRequestPaymodeKey as a vbLong which corresponds to sql's INT. I'm assuming PAM_KEY is an INT. A recordset will return a string value. So, your code would look like this:
If IsNumeric(sRequestPaymodeKey) Then
sSql = "SELECT PAM_CODE" & _
" FROM SYSADM.PAYMODES" & _
" WHERE 1=1" & _
" AND PAM_KEY = " & CLng(sRequestPaymodeKey)
Set oRSPaymodes = connADO.execute(sSql)
Else
'do error handling due to bad returned data(empty string?)
End If
Also, consider parameterizing your queries to prevent sql injection.
A few ideas to try:
Before Set oRSPaymodes = connADO.execute(sSql), put in a MsbBox and see what SQL is being executed. Is it valid? Will it run in a Oracle query analyzer(if there is one)?
Hard code a valid value in place of sRequestPaymodeKey. Does it work then?