Trying to update a field in Oracle based on a select statement - getting subquery returns more than one row error - oracle

I am trying to update a field on a table the query needs to get the value from a 2nd table and use that to get the data from a 3rd table. I keep getting the "ORA-01427: single-row subquery returns more than one row" Any help is appreciated.
update ord_detail set cuser1 = (select c.email from contact c,ord_detail m join orders o on o.ID = m.orders_ID where c.email is not null)
where EXISTS (select email from contact,orders where orders.contact_id2 = contact.id)

Since you did not provide further information like the results of your sub selects, it's not 100% clear what exactly is your problem. You should check those results and if this does not answer your question, please provide the details.
My guess is that this sub query will give multiple rows because you are missing a join from the table "contact" to one of the other tables:
select c.email from contact c,ord_detail m
join orders o on o.ID = m.orders_ID where c.email is not null
Therefore, this sub query will always lead to many rows as result unless the table "contact" contains one row only whose column email is not null.

Related

Oracle - Update COUNT of rows with specific value

This question has been posted several times but I am not able to get it work. I tried the approach mentioned in Update column to the COUNT of rows for specific values in another column. SQL Server. It gives me SQLException: java.sql.SQLException: ORA-01427: single-row subquery returns more than one row error not sure what I can do.
Below is my problem
UPDATE dataTable
SET ACCX = (select b.cnt
from dataTable a
join
(SELECT Account,
COUNT(1) cnt
FROM dataTable
GROUP BY Account) b
on a.Account=b.Account)
,ACCR = 15481
,ACCF = 3
WHERE ID = 1625
I only have the access & can change to the bold part since rest of the query is generated by the tool I cannot change it & I have to update ACCX column with the count of the value in column Account. Is it possible to do?
Note: - Account column is already populated with values.
You cannot follow that query because it is for sqlserver and NOT oracle. It is simpler in oracle and does not need a join to itself.
This update will set the count for id 1625 only based on number of account numbers in datatable. See demo here;
http://sqlfiddle.com/#!4/d154c/1
update dataTable a
set ACCR = 15481,
ACCF = 3,
a.ACCX = (
select COUNT(*)
from dataTable b
where b.Account=a.Account)
WHERE a.ID = 1625;

Getting ORA-01427 trying to select all from view I've created

I created a view from tables using these queries
CREATE VIEW AVAIL_TOOLS AS
SELECT T.TOOL_NAME AS "Name", R.RETAILER_NAME AS "Retailer", T.RETAILER_NUM AS "Number", I.TI_STATUS AS "Status",
(SELECT
CASE
WHEN DETAIL_RETURNDATE IS NULL THEN TO_CHAR(DETAIL_DUEDATE,'Day, Month, DD, YYYY')
ELSE 'Now' END FROM DETAILRENTAL) AS "Expected Avaliablity"
FROM TOOL T
INNER JOIN RETAILER R
ON T.RETAILER_NUM = R.RETAILER_NUM
INNER JOIN TOOLINSTANCE I
ON T.TOOL_NUM = I.TOOL_NUM
WHERE (I.TI_STATUS = 'Rented') OR (I.TI_STATUS = 'Available')
ORDER BY T.TOOL_NAME;
now when I try to run SELECT * FROM AVAIL_TOOLS
I receive the error ORA-01427: single-row subquery returns more than one row.
The case I am running in the query obviously seems to be the problem. Now is there anyway I could change the queries around. I am trying to create a view where if the return date is null it will be available when it is returned other wise it should be now.
I'm at a loss on how I should change about to get the resulted needed.
Query below should do what you want when you fill proper join condition.
CREATE VIEW AVAIL_TOOLS AS
SELECT T.TOOL_NAME AS "Name", R.RETAILER_NAME AS "Retailer", T.RETAILER_NUM AS "Number", I.TI_STATUS AS "Status",
CASE
WHEN DETAIL_RETURNDATE IS NULL THEN TO_CHAR(DETAIL_DUEDATE,'Day, Month, DD, YYYY')
ELSE 'Now' END "Expected Avaliablity"
FROM TOOL T
INNER JOIN RETAILER R
ON T.RETAILER_NUM = R.RETAILER_NUM
INNER JOIN TOOLINSTANCE I
ON T.TOOL_NUM = I.TOOL_NUM
LEFT OUTER JOIN DETAILRENTAL DR
ON (I.ID? = DR.TOOL_INSTANCE_ID?) --HERE fill join
WHERE (I.TI_STATUS = 'Rented') OR (I.TI_STATUS = 'Available')
ORDER BY T.TOOL_NAME;
Second option is adding to subquery with case where clause based on the same condition as join:
where I.INSTANCE_ID = DETAILRENTAL.INSTANCE_ID
You are combining the result of that CASE expression for ALL rows in DETAILRENTAL with ALL the rows from the three-table join. Instead, you probably only want the "expected availability" for the specific tool in the main SELECT. You could fix it by making the subquery into a correlated subquery; but it makes more sense to just have the CASE expression as a column in the outer SELECT, not wrapped within a subquery, and to add a join to DETAILRENTAL on whatever you need to join on (probably TOOL_NUM?)

cascading Input Control sql query return error: "ORA-01427: single-row subquery returns more than one row"

looking for solution on my sql query error.I'm trying to create second cascading Input Control in JaspersoftServer. The first Input Control works fine, however when I try to create a second cascade IC it returns with the error. I have 3 tables (user, client, user_client), many to many, so 1 linked table (user_client) between them.The 1st Input Control (client) - works well, end user will select the client, the client can have many users, so cascade is the key. Also, as the output, I would like to get not the user_id, but user's firstname and the lastname as one column field. And here is where i'm stuck. I'm pretty sure it is simple syntaxis error, but spent a good couple of hours to figure out what is wrong with it. Is anyone can have a look at it please and indicate where is the problem in my query ?! So far I've done:
select distinct
u.user_id,(
SELECT CONCAT(first_name, surname) AS user_name from tbl_user ),
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
Thank you in advance.
P.S. JasperServer + Oracle 11g
You're doing an uncorrelated subquery to get the first/last name from the user table. There is no relationship between that subquery:
SELECT CONCAT(first_name, surname) AS user_name from tbl_user
... and the user ID in the main query, so the subquery will attempt to return every first/last name for all users, for every row your joins find.
You don't need to do a subquery at all as you already have the tbl_user information available:
select u.user_id,
CONCAT(u.first_name, u.surname) AS user_name
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
If you want to put a space between the first and last name you'll either need nested concat() calls, since that function only takes two arguments:
select u.user_id,
CONCAT(u.first_name, CONCAT(' ', u.surname)) AS user_name
...
... or perhaps more readably use the concatenation operator instead:
select u.user_id,
u.first_name ||' '|| u.surname AS user_name
...
If the first control has selected a client and this query is supposed to find the users related to that client, you're joining the tables the wrong way round, aren't you? And you aren't filtering on the selected client - but no idea how that's actually implemented in Jasper. Maybe you do want the entire list and will filter it on the Jasper side.

Optimize Select on a CLOB field ine DB oracle

So, I got a table, which cotnains somes CLOB fields. And I found that they were increasing the result time.
I tried to add INDEX on this field, but apparently , it cannot be done on CLOB field.
But I still want to improve the response on my Select.
How can I optimize it if it's possible?
My table got like 50 fields, 5/6 CLOB and 2/3 BLOB(the others are number or Varchar2.
I don't have Index on this CLOB field, because it is impossible.
My query is a simple Select who got all fields of my table(without distinct, without order by clause). Just a SELECT ... FROM ...
AND 2 LEFT JOIN on the same table :
t_instance contains an id_winner and an id_loser.
A person can be an asker(in t_myTable), a winner in t_instance, or a loser.
I search all lines in myTable, where id_asker, id_winner or id_loser is the connected person (has a unique number to refer, that I use as number in my request)
SELECT p.id (and all the 50 fields)
FROM t_myTable p
LEFT JOIN t_instance iwd on iwd.id_object = p.id
LEFT JOIN t_instance iwv on iwv.id_object = p.id
WHERE(id_asker = 'number' OR iwd.id_winner = 'number' OR iwv.id_loser ='number' )
I do not have errors, but I just want to know if it's possible to have better response time with my SELECT.
Thank you.

Linq To Entity Framework selecting whole tables

I have the following Linq statement:
(from order in Orders.AsEnumerable()
join component in Components.AsEnumerable()
on order.ORDER_ID equals component.ORDER_ID
join detail in Detailss.AsEnumerable()
on component.RESULT_ID equals detail.RESULT_ID
where orderRestrict.ORDER_MNEMONIC == "MyOrderText"
select new
{
Mnemonic = detail.TEST_MNEMONIC,
OrderID = component.ORDER_ID,
SeqNumber = component.SEQ_NUM
}).ToList()
I expect this to put out the following query:
select *
from Orders ord (NoLock)
join Component comp (NoLock)
on ord .ORDER_ID = comp.ORDER_ID
join Details detail (NoLock)
on comp.RESULT_TEST_NUM = detail .RESULT_TEST_NUM
where res.ORDER_MNEMONIC = 'MyOrderText'
but instead I get 3 seperate queries that select all rows from the tables. I am guessing that Linq is then filtering the values because I do get the correct values in the end.
The problem is that it takes WAY WAY too long because it is pulling down all the rows from all three tables.
Any ideas how I can fix that?
Remove the .AsEnumerable()s from the query as these are preventing the entire query being evaluated on the server.

Resources