I get this error
23/112 PL/SQL: ORA-00920: invalid relational operator
It's pointing to AND CURRENT OF statement..
CREATE OR replace PROCEDURE alga_uz_pasirodyma(grupe_id in grupes.id%TYPE, alga in out number)
IS
v_kliento_id nariai.asm_kodas%TYPE;
TYPE bendras IS RECORD (
alga number
);
globalus bendras;
CURSOR c_klientai IS
SELECT nariai.asm_kodas
FROM nariai
where nariai.fk_grupe = grupe_id
FOR UPDATE OF nariai.alga;
BEGIN
globalus.alga:= alga;
IF grupe_id <= 0 THEN
raise_application_error(-20101, 'Nepavyko surasti grupes');
END IF;
OPEN c_klientai;
LOOP
FETCH c_klientai INTO v_kliento_id;
EXIT WHEN c_klientai%NOTFOUND;
UPDATE nariai set nariai.alga = nariai.alga * globalus.alga where nariai.asm_kodas = v_kliento_id AND CURRENT OF c_klientai;
END LOOP;
UPDATE grupes set grupes.pasirodymu_kiekis = grupes.pasirodymu_kiekis + 1 where grupes.id = grupe_id;
SELECT max(nariai.alga) into alga from nariai where nariai.fk_grupe = grupe_id;
CLOSE c_klientai;
END alga_uz_pasirodyma;
What should I do? I believe everything is declared correctly in the where statement..
"CURRENT OF" should be by itself in the where clause. It allows you to update or delete the record at the current loop iteration of the cursor.
On a different note, I don't see you doing anything significant in the loop to warrant a cursor. Ignore this note if that will change, otherwise just run the update "where nariai.fk_grupe = grupe_id"
Related
I have a MariaDB database with a list of sites stored and their chronology (e.g. 1st to 5th c. CE). I need to export a table of all the sites active in the 1st c., in the 2nd c., etc. I wanted to avoid exporting individual tables for single centuries and then combining them, because I am frequently adding new sites and I am using this exported .csv to perform some actions in R.
I thought to create a WHILE loop to generate a single table, but I get this error:
[42000][1064] (conn=4) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SET Counter = Counter + 1; [42000][1064] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SET Counter = Counter + 1; END WHILE; END' at line 17
The code I am using is:
CREATE PROCEDURE while_centuries()
BEGIN
DECLARE Counter INT DEFAULT -1;
WHILE Counter <= 11 DO
SELECT site_list.site_code, site_name, st.type_name, cl.culture_type, startcentury, endcentury, site_altitude,
geo_name, x,y, regions.region_name, available_data, bot, zoo, poll
-- BOT ZOO POLL are links to the UUIDs of the rows of plant_remains, pollen_remains and faunal_remains table.
FROM site_list
INNER JOIN regions ON site_list.region_id = regions.region_id
INNER JOIN geo_type gt on site_list.geo_feature = gt.geo_id
INNER JOIN site_type st on site_list.site_type = st.type_id
INNER JOIN culture_list cl on site_list.culture = cl.id_culture
WHERE startcentury <=Counter AND endcentury>=Counter
SET Counter = Counter + 1;
END WHILE;
where 11 is the last century I need and -1 is the first century I need.
I am sorry I am not fluent in programming. Could somebody help me?
Thank you in advance.
I think you need a semicolon after endcentury>=Counter
to end the SELECT statement.
It is NOT the SET Counter = Counter + 1
statement actually causing the error.
i have a major problem and trying to find a workaround. I have an application in PB12.5 that works on both sql and oracle dbs.. (with a lot of data)
and i m using CURSOR at a point,, but the aplications crashes only in sql. Using debuging in PB i found that the sql connection returs -1 due to huge transaction size. But i want to fetch row by row my data.. is any work around to fetch data like paging?? i mean lets fetch the first 1000 rows next the other 1000 and so on.. i hope that you understand what i want to achieve (to break the fetch process and so to reduce the transaction size if possible) , here is my code
DECLARE trans_Curs CURSOR FOR
SELECT associate_trans.trans_code
FROM associate_trans
WHERE associate_trans.usage_code = :ggs_vars.usage ORDER BY associate_trans.trans_code ;
OPEN trans_Curs;
FETCH trans_Curs INTO :ll_transId;
DO WHILE sqlca.sqlcode = 0
ll_index += 1
hpb_1.Position = ll_index
if not guo_associates.of_asstrans_updatemaster( ll_transId, ls_error) then
ROLLBACK;
CLOSE trans_Curs;
SetPointer(Arrow!)
MessageBox("Update Process", "Problem with the update process on~r~n" + sqlca.sqlerrtext)
cb_2.Enabled = TRUE
return
end if
FETCH trans_Curs INTO :ll_transId;
LOOP
CLOSE trans_Curs;
Since the structure of your source table s not fully presented, I'll make some assumptions here.
Let's assume that the records include a unique field that can be used as a reference (could be a counter or a timestamp). I'll assume here that the field is a timestamp.
Let's also assume that PB accepts cursors with parameters (not all solutions do; if it does not, there are simple workarounds).
You could modify your cursor to be something like:
[Note: I'm assuming also that the syntax presented here is valid for your environment; if not, adaptations are simple]
DECLARE TopTime TIMESTAMP ;
DECLARE trans_Curs CURSOR FOR
SELECT ots.associate_trans.trans_code
FROM ots.associate_trans
WHERE ots.associate_trans.usage_code = :ggs_vars.usage
AND ots.associate_trans.Timestamp < TopTime
ORDER BY ots.associate_trans.trans_code
LIMIT 1000 ;
:
:
IF (p_Start_Timestamp IS NULL) THEN
TopTime = CURRENT_TIMESTAMP() ;
ELSE
TopTime = p_Start_Timestamp ;
END IF ;
OPEN trans_Curs;
FETCH trans_Curs INTO :ll_transId;
:
:
In the above:
p_Start_Timestamp is a received timestamp parameter which would initially be empty and then will contain the OLDEST timestamp fetched in the previous invocation,
CURRENT_TIMESTAMP() is a function of your environment returning the current timestamp.
This solution will work solely when you need to progress in one direction (i.e. from present to past) and that you are accumulating all the fetched records in an internal buffer in case you need to scroll up again.
Hope this makes things clearer.
First of all thank you FDavidov for your effort, so i managed to do it using dynamic datastore instead of cursor,, so here is my solution in case someone else need this.
String ls_sql, ls_syntax, ls_err
Long ll_row
DataStore lds_info
ls_sql = "SELECT associate_trans.trans_code " &
+ " FROM associate_trans " &
+ " WHERE associate_trans.usage_code = '" + ggs_vars.usage +"' "&
+ " ORDER BY associate_trans.trans_code"
ls_syntax = SQLCA.SyntaxFromSQL( ls_sql, "", ls_err )
IF ls_err <> '' THEN
MessageBox( 'Error...', ls_err )
RETURN
END IF
lds_info = CREATE DataStore
lds_info.Create( ls_syntax, ls_err )
lds_info.SetTransObject( SQLCA )
lds_info.Retrieve( )
DO WHILE sqlca.sqlcode = 0 and ll_row <= ll_count
FOR ll_row = 1 TO ll_count
ll_transId = lds_info.GetItemNumber( ll_row, 'trans_code' )
ll_index += 1
hpb_1.Position = ll_index
do while yield(); loop
if not guo_associates.of_asstrans_updatemaster( ll_transId, ls_error) then
ROLLBACK;
DESTROY lds_info
SetPointer(Arrow!)
MessageBox("Update Process", "Problem with the update process on~r~n" + sqlca.sqlerrtext)
cb_2.Enabled = TRUE
return
end if
NEXT
DESTROY lds_info
LOOP
The following is a proc code that I have written . I am getting a syntax error in the block marked from (A) to (B) , namely , ORA06550, saying SQL command not ended properly.
If I eliminate the line l.ban4_upd ='UPDATED' there are no more of nay error messages.
I don't know how to correct it . Hoping for your help and thanks in advance
DECLARE
dummy_BAN4 VARCHAR2(30);
dummy_bank_acc_num VARCHAR2(20);
CURSOR c_customers is
SELECT BAN4,Bank_acc_num FROM Test_Table ;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into dummy_BAN4 , dummy_bank_acc_num;
IF c_customers%notfound THEN
update Test_Table chs Set
chs.error_msg ='No such record found in DB '
where bank_acc_num =dummy_bank_acc_num;
END IF;
update Transact_ord2 l Set.........................(A)
l.ban4_upd ='UPDATED'
l.x_account_number =dummy_BAN4
where X_account_number =dummy_bank_acc_num; ..........(B)
you are missing , between the fields you set:
update Transact_ord2
Set ban4_upd = 'UPDATED',
x_account_number = dummy_BAN4
where X_account_number = dummy_bank_acc_num;
Check this
I'm new to Triggers and PL/SQL in general. FOr testing purpose I'm using slely the Oracle Database Express Edition with its own Command Line.
The script supposed to create a trigger looks like follows:
CREATE OR REPLACE TRIGGER SESSION_LOGIN_HANDLER
AFTER UPDATE OF LOGGED_IN ON BENUTZERKONTO
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
BEGIN
if (:OLD.LOGGED_IN == 1)
if (:NEW.LOGGED_IN == 0)
{
UPDATE SESSION_LOGGING AS current_session SET DAUER = (sysdate-ZEITSTEMPEL) WHERE DAUER IS NULL AND SECURE_IDENTIFIER = :NEW.SECURE_IDENTIFIER;
}
END;
commit;
And I call it with #C:/SQL.../DB_TRIGGER.trg; in the command line.
Yet just after calling it, the command line seems just to count the line number with each time I press .
It seems like it somehow waits for another line or anything, but I don't know what ><
There's also no failure message or anything.
I even commented out the entire code between "BEGIN" and "END" with no difference!
Could someone help this beginner? Thanks in advance!
That's no Oracle syntax, it must be like this:
if (:OLD.LOGGED_IN = 1) then
if (:NEW.LOGGED_IN = 0) then
UPDATE SESSION_LOGGING AS current_session SET DAUER = (sysdate-ZEITSTEMPEL)
WHERE DAUER IS NULL AND SECURE_IDENTIFIER = :NEW.SECURE_IDENTIFIER;
end if;
end if;
I am working on Sql Developper an I created the following procedure in a package:
PROCEDURE VALIDER(a_session IN NUMBER) AS
i NUMBER;
TYPE type_tab IS TABLE OF PANIER%ROWTYPE;
tabSeances type_tab;
BEGIN
SELECT * BULK COLLECT INTO tabSeances
FROM PANIER
WHERE a_session = sessionweb;
i:=0;
FOR i IN 1 .. tabSeances.count LOOP
-- UPADTE DU NOMBRE DE PLACES LIBRES
BEGIN
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND day = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
--UPDATE ON PANIER
UPDATE PANIER
SET valide = 1
WHERE sessionweb = a_session
AND num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN raise_application_error(-20035, 'Pas de données');
WHEN OTHERS THEN raise_application_error(-20006,'Autres Erreurs');
END;
END LOOP;
END VALIDER;
The procedure executes normaly and I don't get an error.
I have a kind of product cart: "PANIER". I loop all the entries in thsi cart for one person (session) to validate them in the database and decrement the total number of seats.
But the field "remaining-seats" (from PROJECTIONS) in the first update don't work. The field isn't updated. I have already tried with other values but nothing.
I am sure that the procedure is executetd because the second update still works. It marks the cart entry as "CONFIRMED".
I don't have any trigger on this field.
My tables contains valid data (<>NULL).
I execute this procedure like this (in a BEGIN END; block):
CMDPLACES.VALIDER(1);
Thank for your reply.
Is it day or dateseance in your first update?
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
Also as #ThorstenKettner was mentioning, the timestamp data in the date , may fail while comparing, so we have TRUNCATE the timestamp data using TRUNC() [if needed]!
If the date column is indexed, beware the index will not be used by the database .
To handle NO Data in UPDATE, you can check (SQL%ROWCOUNT > 0) to identify the number of rows updated!
Your first update compares days. What data type are these? In case you deal with DATETIME, make sure to compare without the time part if any. Use TRUNC to achieve this.
AND TRUNC(day) = TRUNC(tabseances(i).dateseance)