PLSQL - Update statement with variable - sql

I am currently trying to write an update statement using a variable (which will be expanded to use multiple variables later on).
Currently I have the following statement (altered for posting here), but I am running into an error and I don't immediately see the mistake I am making:
DECLARE
v_var1 table1.CY_VALUE % TYPE;
BEGIN
SELECT SUM(Column1 + Column2)
INTO v_var1
FROM table2
WHERE survey_ID = 1 AND Active_Flag = 1
GROUP BY SURVEY_ID;
UPDATE table1
SET CY_VALUE = v_var1
WHERE SURVEY_ID = 1 AND KPI_ID = 1;
END;
This is the error I am receiving:
SQL Error [6550] [65000]: ORA-06550: line 15, column 1:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
:= . ( # % ;
What do I need to alter in order to get this to work in this example?
Or are there better ways to write the update for table 1, containing a sum from table 2?

There is nothing obviously wrong with your code. But why not just use a correlated subquery and dispense with the variable -- and the PL/SQL?
UPDATE table1 t1
SET CY_VALUE = (SELECT SUM(t2.Column1 + t2.Column2)
FROM table2 t2
WHERE t2.survey_ID = t1.survey_ID AND
t2.Active_Flag = 1
)
WHERE SURVEY_ID = 1 AND KPI_ID = 1;
Although not related to your error, the GROUP BY in the first query is also misleading. An aggregate query with a GROUP BY can return any number of rows -- including 0. Instead, just lead out the GROUP BY:
SELECT SUM(Column1 + Column2)
INTO v_var1
FROM table2
WHERE survey_ID = 1 AND Active_Flag = 1;
The WHERE clause filters down to the survery_ID you want and without the GROUP BY this query always returns exactly one row.

Related

update table only if subquery returns the result postgres

I have query which might not return result which will cause NULL value
update public.test set geom =
(select geom from public.test where st_geometrytype(geom) = 'X' limit 1)
I tried to add COALESCE to replace with original value but gives error
update public.ec_1_eur_1 set geom =
COALESCE(select geom from public.ec_1_eur_1 where
st_geometrytype(geom) = 'X' limit 1, geom)
Also this also gives error
with s2 as (select geom from public.test where st_geometrytype(geom) = 'X' limit 1)
update public.test set geom = s2 where s2 is not null
I would use the update/join syntax here, so nothing is updated if the subquery returns no row:
update public.test t
set geom = t1.geom
from (
select geom
from public.test
where st_geometrytype(geom) = 'X'
limit 1
) t1
As for the query you wanted to write, using coalesce(): you would need to surround the subquery with parentheses, so it is explicit that it returns a scalar:
update public.test t
set geom = coalesce(
(select geom from public.test where st_geometrytype(geom) = 'X' limit 1),
geom
)
However this approach is less efficient, because it still updates all rows of the table back to their original value if the subquery returns no rows; the update/join approach is preferrable in that regard.
Note, however, that limit without order by makes little sense, because it is not deterministic; when the subquery produces several rows, it is undefined which one will be picked.

How do I UPDATE from a SELECT in Informix?

I'm trying to do an update using data from another table. I've tried this answer (the second part), but it is not working for me. I'm receiving a generic error message of syntax error.
I've also tried this solution and received a syntax error message too.
If I try to update just one column, it works:
UPDATE dogs
SET name =
(
SELECT 'Buddy'
FROM systables
WHERE tabid = 1
);
But I need to update multiples columns. Unfortunately, this is not working:
UPDATE dogs
SET (name, breed) =
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
);
Informix version is 12.10.FC8
You are missing 1 more set of parentheses around the subquery.
From the Informix manual:
The subquery must be enclosed between parentheses. These parentheses
are nested within the parentheses that immediately follow the equal (
= ) sign. If the expression list includes multiple subqueries, each subquery must be enclosed between parentheses, with a comma ( , )
separating successive subqueries:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
The following examples show the use of subqueries in the SET clause:
UPDATE items
SET (stock_num, manu_code, quantity) =
(
(
SELECT stock_num, manu_code
FROM stock
WHERE description = 'baseball'
),
2
)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
(
(
SELECT MIN (ship_charge), MAX (ship_charge)
FROM orders
),
'07/01/2007'
)
WHERE col4 = 1001;
So in order for your update to be accepted by Informix it has to be:
UPDATE dogs
SET (name, breed) =
(
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
)
);

ORA-01002: fetch out of sequence

I am getting org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL
UPDATE responses
SET version_no = ( version_no + 1 ),
read_status = 0,
tslastmodified = SYSDATE
WHERE responseid IN (SELECT responseid
FROM responses
WHERE read_status = 1
AND tslastmodified < SYSDATE - 45 / ( 24 * 60 )
AND id IN (SELECT id
FROM emp))
; SQL state [24000]; error code [1002]; ORA-01002: fetch out of sequence
; nested exception is java.sql.SQLException: ORA-01002: fetch out of sequence
JAVA code :
getJdbcTemplate().queryForObject(SurveyQuery.UPDATE_INPROCESS, Integer.class);
Please let me know what is wrong in above query
You can modify your UPDATE statement to something like below
UPDATE RESPONSES SET VERSION_NO=(VERSION_NO+1),
READ_STATUS=0,
TSLASTMODIFIED = SYSDATE
WHERE READ_STATUS = 1
AND TSLASTMODIFIED < SYSDATE - 45/(24*60)
AND EXISTS (SELECT 1 FROM EMP
WHERE RESPONSES.ID = EMP.ID)
Note: Though you can use the above modified query but I doubt the said error is because of the posted update statement. From Documentation it looks like the cause of the above error could be
When you perform a FETCH on an active cursor after all records have
been fetched.
(OR)
When you perform a FETCH on a SELECT FOR UPDATE after a COMMIT has
been issued.

SQL Update - Cant specify target table in select

I have the following table
#key | #value
colour | red
weather | blue
Now I want to update the value of the row with the key colour to be the value of the row with the key weather. So I am doing:
UPDATE table_name
SET value = (SELECT value FROM table_name WHERE key = "weather")
WHERE key = "colour";
But this update gives me following error message:
You can't specify target table for update in FROM clause
How can I do that query without error?
This may be because it may be the case that the select query returns more than one value for the column value
UPDATE table_name
SET value = (SELECT max(value) FROM table_name WHERE key = "weather")
WHERE key = "colour";
or
UPDATE table_name
SET value = (SELECT value FROM table_name WHERE key = "weather" limit 1)
WHERE key = "colour";
You may try to change it like this by replacing the instance of table_name in the sub-query with (SELECT * FROM table_name):
UPDATE table_name
SET table_name.A =
(
SELECT B
FROM (SELECT * FROM table_name) AS something
INNER JOIN ...
)
Also check How to select from an update target in MySQL
You don’t want to just SELECT * FROM table in the subquery in real
life; I just wanted to keep the examples simple. In reality you should
only be selecting the columns you need in that innermost query, and
adding a good WHERE clause to limit the results, too.
EDIT:-
As you have already commented that but I have answered above to use the temporary table like this:-
UPDATE table_name
SET value = (SELECT value FROM (SELECT value FROM table_name WHERE key="weather") AS x)
WHERE key="colour"
you might try this if your sql supports 'LIMIT'
UPDATE table_name SET value = (SELECT value FROM table_name WHERE key = "weather" LIMIT 1 ) WHERE key = "colour";
UPDATE table_name
SET colour ='red',weather =blue
WHERE column_name = some_value;
It won't work that way. You can't have a read and a write query at the same time for the same table. With two different tables it will work.
UPDATE `table` SET value = (SELECT value FROM `Table_b` WHERE `other_value` = 'xy' LIMIT 1) WHERE `key` = 'colour'

How to insert bulky value to sql table?

I want to add bulky data from another data below. But I can not do that: error is returned. But areas are the same as another.
declare #hrmtable1 table(musterino int, ekno smallint)
insert into #hrmtable1 (musterino , ekno)
select distinct musterino, ekno
from hareketmuhasebe (nolock)
where islemtarihi >= '20120101'
and isnull(musterino, 0) <> 0
and isnull(musterino, 0) > 9000000
and isnull(ekno,0) <> 0
insert into table1(A,B,C,D,E,. . . . .N)
SELECT DISTINCT
case when ((select count(*) from table1 where musterino=e.musterino) > 0)
then (select top 1 *
from dbo.table1
where musterino = e.musterino
order by ekno desc)
else
(select 100, e.musterino, e.ekno, 0, K, L, M)
from #hrmtable1 e )
end
ERROR:
Msg 120, Level 15, State 1, Line 10
The select list for the INSERT statement contains fewer items than the insert list.
The number of SELECT values must match the number of INSERT columns.
As mentioned in the error the number of columns in insert does not mach the number of value that you are providing
insert into #hrmtable1 (musterino , ekno)
select distinct musterino,ekno
from hareketmuhasebe (nolock)
where islemtarihi >= '20120101'
and isnull(musterino,0) <> 0 and isnull(musterino,0) < 9000000 and isnull(ekno,0) <> 0
Try this:
insert into #hrmtable1 (musterino , ekno)
select distinct musterino,ekno
from hareketmuhasebe (nolock)
where islemtarihi >= '20120101'
and isnull(musterino,0) <> 0 and isnull(musterino,0) < 9000000 and isnull(ekno,0) <> 0
You are having 2 columns in insert & 5 columns in select clause, that is the cause of error.
EDIT: Since you edited the question, still the answer remains the same. Your number of columns in Select statement doesn't match to your insert statement columns in the 2nd part of your code.
In your first statement you are specifying 2 columns and in select you have 5 columns, they should match and that is what the error is telling you exactly.
insert into #hrmtable1 (musterino , ekno)
^^^^^^^ ^^^^
select distinct musterino,ekno,defterid,dovizcinsi, subekodu
^^^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^
From your insert statement it looks like you don't need the last three columns in your Select statement.
The select list for the INSERT statement contains fewer items than the
insert list. The number of SELECT values must match the number of
INSERT columns.
The error itself tells you the story that what you are doing wrong. you have fewer columns in insert statement than to select statement.
From MSDN
The select list of the subquery must match the column list of the
INSERT statement. If no column list is specified, the select list must
match the columns in the table or view being inserted into.
Read more about Inert into