I am trying to update column in table get it from another table and I have relation between two tables as parent have primary key "tbl_Inv_ClientItemsReturnOrders" and child have foreign key "tbl_Inv_ClientItemsReturnOrderDetails".
I try this
update U
set U.InventoryReturnReasonID =
(select InventoryReturnReasonID
from tbl_Inv_ClientItemsReturnOrders
where ClientItemsReturnOrderID = U.ClientItemsReturnOrderID)
from [dbo].[tbl_Inv_ClientItemsReturnOrderDetails] U
But I get this error
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.The statement has been terminated.
I want to update column "InventoryReturnReasonID" in table "tbl_Inv_ClientItemsReturnOrderDetails" by value of column "InventoryReturnReasonID" from table "tbl_Inv_ClientItemsReturnOrders"
you can use the query given below for getting better idea about the issue.
SELECT * FROM [dbo].[tbl_Inv_ClientItemsReturnOrderDetails] U
INNER JOIN [dbo].[tbl_Inv_ClientItemsReturnOrders] P ON (P.ClientItemsReturnOrderID = U.ClientItemsReturnOrderID)
we have the option to compile update with join. The query is as follows
UPDATE U
SET U.InventoryReturnReasonID = P.InventoryReturnReasonID
FROM [dbo].[tbl_Inv_ClientItemsReturnOrderDetails] U
INNER JOIN [dbo].[tbl_Inv_ClientItemsReturnOrders] P ON (P.ClientItemsReturnOrderID = U.ClientItemsReturnOrderID)
The error is pretty clear. You can select an arbitrary value using TOP 1:
Update U
set U.InventoryReturnReasonID = (select TOP 1 ro.InventoryReturnReasonID
from tbl_Inv_ClientItemsReturnOrders ro
where ro.ClientItemsReturnOrderID = U.ClientItemsReturnOrderID
)
from [dbo].tbl_Inv_ClientItemsReturnOrderDetails U;
Normally, TOP should have an ORDRER BY. You can include an ORDER BY to specify which of multiple values the update should use.
Note: Using qualified column names (i.e. including a table alias) is always a good idea. It should be mandatory with a correlated subquery because of the potential danger if something goes wrong. For instance, your query would return too many rows if the column ro.ClientItemsReturnOrderID did not exist.
Another approach is to use aggregation:
Update U
set U.InventoryReturnReasonID = (select max(ro.InventoryReturnReasonID)
from tbl_Inv_ClientItemsReturnOrders ro
where ro.ClientItemsReturnOrderID = U.ClientItemsReturnOrderID
)
from [dbo].tbl_Inv_ClientItemsReturnOrderDetails U;
Related
I run the following query:
SELECT
orderdetails.sku,
orderdetails.mf_item_number,
orderdetails.qty,
orderdetails.price,
supplier.supplierid,
supplier.suppliername,
supplier.dropshipfees,
cost = (SELECT supplier_item.price
FROM supplier_item,
orderdetails,
supplier
WHERE supplier_item.sku = orderdetails.sku
AND supplier_item.supplierid = supplier.supplierid)
FROM orderdetails,
supplier,
group_master
WHERE invoiceid = '339740'
AND orderdetails.mfr_id = supplier.supplierid
AND group_master.sku = orderdetails.sku
I get the following error:
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Any ideas?
Try this:
SELECT
od.Sku,
od.mf_item_number,
od.Qty,
od.Price,
s.SupplierId,
s.SupplierName,
s.DropShipFees,
si.Price as cost
FROM
OrderDetails od
INNER JOIN Supplier s on s.SupplierId = od.Mfr_ID
INNER JOIN Group_Master gm on gm.Sku = od.Sku
INNER JOIN Supplier_Item si on si.SKU = od.Sku and si.SupplierId = s.SupplierID
WHERE
od.invoiceid = '339740'
This will return multiple rows that are identical except for the cost column. Look at the different cost values that are returned and figure out what is causing the different values. Then ask somebody which cost value they want, and add the criteria to the query that will select that cost.
Check to see if there are any triggers on the table you are trying to execute queries against. They can sometimes throw this error as they are trying to run the update/select/insert trigger that is on the table.
You can modify your query to disable then enable the trigger if the trigger DOES NOT need to be executed for whatever query you are trying to run.
ALTER TABLE your_table DISABLE TRIGGER [the_trigger_name]
UPDATE your_table
SET Gender = 'Female'
WHERE (Gender = 'Male')
ALTER TABLE your_table ENABLE TRIGGER [the_trigger_name]
SELECT COLUMN
FROM TABLE
WHERE columns_name
IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');
note: when we are using sub-query we must focus on these points:
if our sub query returns 1 value in this case we need to use (=,!=,<>,<,>....)
else (more than one value), in this case we need to use (in, any, all, some )
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier
where Supplier_Item.SKU=OrderDetails.Sku and
Supplier_Item.SupplierId=Supplier.SupplierID
This subquery returns multiple values, SQL is complaining because it can't assign multiple values to cost in a single record.
Some ideas:
Fix the data such that the existing subquery returns only 1 record
Fix the subquery such that it only returns one record
Add a top 1 and order by to the subquery (nasty solution that DBAs hate - but it "works")
Use a user defined function to concatenate the results of the subquery into a single string
The fix is to stop using correlated subqueries and use joins instead. Correlated subqueries are essentially cursors as they cause the query to run row-by-row and should be avoided.
You may need a derived table in the join in order to get the value you want in the field if you want only one record to match, if you need both values then the ordinary join will do that but you will get multiple records for the same id in the results set. If you only want one, you need to decide which one and do that in the code, you could use a top 1 with an order by, you could use max(), you could use min(), etc, depending on what your real requirement for the data is.
I had the same problem , I used in instead of = , from the Northwind database example :
Query is : Find the Companies that placed orders in 1997
Try this :
SELECT CompanyName
FROM Customers
WHERE CustomerID IN (
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Instead of that :
SELECT CompanyName
FROM Customers
WHERE CustomerID =
(
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Either your data is bad, or it's not structured the way you think it is. Possibly both.
To prove/disprove this hypothesis, run this query:
SELECT * from
(
SELECT count(*) as c, Supplier_Item.SKU
FROM Supplier_Item
INNER JOIN orderdetails
ON Supplier_Item.sku = orderdetails.sku
INNER JOIN Supplier
ON Supplier_item.supplierID = Supplier.SupplierID
GROUP BY Supplier_Item.SKU
) x
WHERE c > 1
ORDER BY c DESC
If this returns just a few rows, then your data is bad. If it returns lots of rows, then your data is not structured the way you think it is. (If it returns zero rows, I'm wrong.)
I'm guessing that you have orders containing the same SKU multiple times (two separate line items, both ordering the same SKU).
The select statement in the cost part of your select is returning more than one value. You need to add more where clauses, or use an aggregation.
The error implies that this subquery is returning more than 1 row:
(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
You probably don't want to include the orderdetails and supplier tables in the subquery, because you want to reference the values selected from those tables in the outer query. So I think you want the subquery to be simply:
(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
I suggest you read up on correlated vs. non-correlated subqueries.
As others have suggested, the best way to do this is to use a join instead of variable assignment. Re-writing your query to use a join (and using the explicit join syntax instead of the implicit join, which was also suggested--and is the best practice), you would get something like this:
select
OrderDetails.Sku,
OrderDetails.mf_item_number,
OrderDetails.Qty,
OrderDetails.Price,
Supplier.SupplierId,
Supplier.SupplierName,
Supplier.DropShipFees,
Supplier_Item.Price as cost
from
OrderDetails
join Supplier on OrderDetails.Mfr_ID = Supplier.SupplierId
join Group_Master on Group_Master.Sku = OrderDetails.Sku
join Supplier_Item on
Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID
where
invoiceid='339740'
Even after 9 years of the original post, this helped me.
If you are receiving these types of errors without any clue, there should be a trigger, function related to the table, and obviously it should end up with an SP, or function with selecting/filtering data NOT USING Primary Unique column. If you are searching/filtering using the Primary Unique column there won't be any multiple results. Especially when you are assigning value for a declared variable. The SP never gives you en error but only an runtime error.
"System.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated."
In my case obviously there was no clue, but only this error message. There was a trigger connected to the table and the table updating by the trigger also had another trigger likewise it ended up with two triggers and in the end with an SP. The SP was having a select clause which was resulting in multiple rows.
SET #Variable1 =(
SELECT column_gonna_asign
FROM dbo.your_db
WHERE Non_primary_non_unique_key= #Variable2
If this returns multiple rows, you are in trouble.
I need to update a column in one of my tables based on data from 2 other tables.
So I want the column isAvailable, in the table questionObjectives, to be set to 1 based on 2 conditions and this is what I have:
UPDATE
dbo.questObjectives
SET
isAvailable = 1
FROM
dbo.questObjectives qo
INNER JOIN
dbo.dungeonList dl
ON
qo.questID = dl.questID
WHERE dl.dungeonType = 17
AND qo.objectiveID IN(SELECT objectiveID FROM gameMissions)
So to translate, isAvailable should be set to 1 if:
the linked dungeonList type is 17
the questionObjectives objectiveID is in the table gameMissions
So I thought I had my logic right, but I keep getting this error:
'invalid column name isAvailable.'
But it is there. It is in the questionObjectives table so I'm not sure what I'm doing wrong.
Any ideas?
Thanks!
Is this what you want?
update qo
set qo.isavailable = 1
from questObjectives qo
inner join dungeonList dl on qo.questID = dl.questID
where
dl.dungeonList = 17
and exists (select 1 from gameMissions gm where gm.objectiveID = qo.objectiveID)
The main problem with your query is that you have target table questObjectives both in the update and from clauses; you should have it just once, in the from clause, and then refer to the alias in the update clause.
I also rewrote the in condition as a correlated subquery with exists - the logic is the same, but this might perform better.
I need to add multirows at the same time in my sql server Table using this code
declare #idproduct int
declare #idfile int
set #idproduct = (select id from Products where name = 'DR-8416')
set #idfile = (select id from Files where filename like '%8416%')
insert into ProductsFiles(idproducts, idfile) values (#idproduct, #idfile)
that #idfile is an array with many values;
when I try to add I recied this error
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
How Can I solve this Problem ?
Best I can guess is what you are after is:
INSERT INTO ProductsFiles (idproducts,
idfile)
SELECT P.id,
F.id
FROM Products AS P
CROSS JOIN Files AS F
WHERE P.[name] = 'DR-8416'
AND F.[filename] LIKE '%8416%';
Note I have used as CROSS JOIN, as your question suggests there is no relationship between Products and Files. If there is change the CROSS JOIN to an INNER JOIN and add the relevant ON clause. If you don't know about JOIN syntax I suggest looking it up, and learning it. JOIN syntax is one of the fundamentals for SQL and you will not get far without learning it. You will learn far more by taking the time to read up about it than me giving you an answer and trying to explain the basics.
I run the following query:
SELECT
orderdetails.sku,
orderdetails.mf_item_number,
orderdetails.qty,
orderdetails.price,
supplier.supplierid,
supplier.suppliername,
supplier.dropshipfees,
cost = (SELECT supplier_item.price
FROM supplier_item,
orderdetails,
supplier
WHERE supplier_item.sku = orderdetails.sku
AND supplier_item.supplierid = supplier.supplierid)
FROM orderdetails,
supplier,
group_master
WHERE invoiceid = '339740'
AND orderdetails.mfr_id = supplier.supplierid
AND group_master.sku = orderdetails.sku
I get the following error:
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Any ideas?
Try this:
SELECT
od.Sku,
od.mf_item_number,
od.Qty,
od.Price,
s.SupplierId,
s.SupplierName,
s.DropShipFees,
si.Price as cost
FROM
OrderDetails od
INNER JOIN Supplier s on s.SupplierId = od.Mfr_ID
INNER JOIN Group_Master gm on gm.Sku = od.Sku
INNER JOIN Supplier_Item si on si.SKU = od.Sku and si.SupplierId = s.SupplierID
WHERE
od.invoiceid = '339740'
This will return multiple rows that are identical except for the cost column. Look at the different cost values that are returned and figure out what is causing the different values. Then ask somebody which cost value they want, and add the criteria to the query that will select that cost.
Check to see if there are any triggers on the table you are trying to execute queries against. They can sometimes throw this error as they are trying to run the update/select/insert trigger that is on the table.
You can modify your query to disable then enable the trigger if the trigger DOES NOT need to be executed for whatever query you are trying to run.
ALTER TABLE your_table DISABLE TRIGGER [the_trigger_name]
UPDATE your_table
SET Gender = 'Female'
WHERE (Gender = 'Male')
ALTER TABLE your_table ENABLE TRIGGER [the_trigger_name]
SELECT COLUMN
FROM TABLE
WHERE columns_name
IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');
note: when we are using sub-query we must focus on these points:
if our sub query returns 1 value in this case we need to use (=,!=,<>,<,>....)
else (more than one value), in this case we need to use (in, any, all, some )
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier
where Supplier_Item.SKU=OrderDetails.Sku and
Supplier_Item.SupplierId=Supplier.SupplierID
This subquery returns multiple values, SQL is complaining because it can't assign multiple values to cost in a single record.
Some ideas:
Fix the data such that the existing subquery returns only 1 record
Fix the subquery such that it only returns one record
Add a top 1 and order by to the subquery (nasty solution that DBAs hate - but it "works")
Use a user defined function to concatenate the results of the subquery into a single string
The fix is to stop using correlated subqueries and use joins instead. Correlated subqueries are essentially cursors as they cause the query to run row-by-row and should be avoided.
You may need a derived table in the join in order to get the value you want in the field if you want only one record to match, if you need both values then the ordinary join will do that but you will get multiple records for the same id in the results set. If you only want one, you need to decide which one and do that in the code, you could use a top 1 with an order by, you could use max(), you could use min(), etc, depending on what your real requirement for the data is.
I had the same problem , I used in instead of = , from the Northwind database example :
Query is : Find the Companies that placed orders in 1997
Try this :
SELECT CompanyName
FROM Customers
WHERE CustomerID IN (
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Instead of that :
SELECT CompanyName
FROM Customers
WHERE CustomerID =
(
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Either your data is bad, or it's not structured the way you think it is. Possibly both.
To prove/disprove this hypothesis, run this query:
SELECT * from
(
SELECT count(*) as c, Supplier_Item.SKU
FROM Supplier_Item
INNER JOIN orderdetails
ON Supplier_Item.sku = orderdetails.sku
INNER JOIN Supplier
ON Supplier_item.supplierID = Supplier.SupplierID
GROUP BY Supplier_Item.SKU
) x
WHERE c > 1
ORDER BY c DESC
If this returns just a few rows, then your data is bad. If it returns lots of rows, then your data is not structured the way you think it is. (If it returns zero rows, I'm wrong.)
I'm guessing that you have orders containing the same SKU multiple times (two separate line items, both ordering the same SKU).
The select statement in the cost part of your select is returning more than one value. You need to add more where clauses, or use an aggregation.
The error implies that this subquery is returning more than 1 row:
(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
You probably don't want to include the orderdetails and supplier tables in the subquery, because you want to reference the values selected from those tables in the outer query. So I think you want the subquery to be simply:
(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
I suggest you read up on correlated vs. non-correlated subqueries.
As others have suggested, the best way to do this is to use a join instead of variable assignment. Re-writing your query to use a join (and using the explicit join syntax instead of the implicit join, which was also suggested--and is the best practice), you would get something like this:
select
OrderDetails.Sku,
OrderDetails.mf_item_number,
OrderDetails.Qty,
OrderDetails.Price,
Supplier.SupplierId,
Supplier.SupplierName,
Supplier.DropShipFees,
Supplier_Item.Price as cost
from
OrderDetails
join Supplier on OrderDetails.Mfr_ID = Supplier.SupplierId
join Group_Master on Group_Master.Sku = OrderDetails.Sku
join Supplier_Item on
Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID
where
invoiceid='339740'
Even after 9 years of the original post, this helped me.
If you are receiving these types of errors without any clue, there should be a trigger, function related to the table, and obviously it should end up with an SP, or function with selecting/filtering data NOT USING Primary Unique column. If you are searching/filtering using the Primary Unique column there won't be any multiple results. Especially when you are assigning value for a declared variable. The SP never gives you en error but only an runtime error.
"System.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated."
In my case obviously there was no clue, but only this error message. There was a trigger connected to the table and the table updating by the trigger also had another trigger likewise it ended up with two triggers and in the end with an SP. The SP was having a select clause which was resulting in multiple rows.
SET #Variable1 =(
SELECT column_gonna_asign
FROM dbo.your_db
WHERE Non_primary_non_unique_key= #Variable2
If this returns multiple rows, you are in trouble.
The Problem
I need to write an Update query where my SET references an outer joined table.
I can do this fairly easily with SQL Server but I'm having a heck of a time figuring out the syntax in Oracle as I'm only allow a single table in an update query.
I have written the following Oracle query:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE EXISTS (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
AND tmp.sysind = 'AIM';
This takes care of the intersection but I need to deal with values in SalesExt_tmp that do not have equivalent matches in dw_sls_rep_conv (I plan to add a case statement to set null values to a default value). To do this I need to set up dw_sls_rep_conv as an outer joined table. But this is where I get stuck.
SQL Server Example
In SQL Server the solution is a piece of cake as you can have multiple tables in an Update Query:
UPDATE SalesExt_tmp tmp
LEFT JOIN dw_sls_rep_conv sls ON sls.aims_rep = tmp.slsrep
SET tmp.slsrep = sls.three_dig_rep
WHERE tmp.sysind = 'AIM';
But I can't for the life of me figure out how to do this in Oracle. I understand that this query will allow my slsrep field to be set to NULL in some occasions which causes me to fear that this operation may not be allowed.
Questions
1) Firstly is this possible in Oracle? (It's got to be, right?)
2) How do I need to restructure my query to pull this off? I'm guessing my WHERE EXISTS clause needs to go... but I'm still stuck as to where to place my JOIN.
If I understood you correctly, you want to set the value to NULL if there is no match in the dw_sls_rep_conv table? If so, just drop your EXISTS condition and all the rows will be updated:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE tmp.sysind = 'AIM';
If there is a match in the dw_sls_rep_conv table, then the slsrep column will be updated with selected value, otherwise, with NULL.
Have you considered using a subquery in your where clause that performs the outer join as you stated like this:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls WHERE sls.aims_rep = tmp.slsrep)
WHERE
tmp.rowid in
(SELECT tmp1.rowid
FROM SalesExt_tmp tmp1,
dw_sls_rep_conv sls
WHERE
tmp1.slsrep = sls.aims_rep (+)
AND tmp1.sysind = 'AIM' );