I am new to mariadb trigger. I had this trigger in Oracle. Need help to convert it to mariadb:
DECLARE
v_newVal NUMBER(12) := 0;
v_incval NUMBER(12) := 0;
BEGIN
IF INSERTING AND :new.id IS NULL THEN
SELECT hvr_storyboards_id_SEQ.NEXTVAL INTO v_newVal FROM DUAL;
-- If this is the first time this table have been inserted into (sequence == 1)
IF v_newVal = 1 THEN
--get the max indentity value from the table
SELECT NVL(max(id),0) INTO v_newVal FROM hvr_storyboards;
v_newVal := v_newVal + 1;
--set the sequence to that value
LOOP
EXIT WHEN v_incval>=v_newVal;
SELECT hvr_storyboards_id_SEQ.nextval INTO v_incval FROM dual;
END LOOP;
END IF;
--used to emulate LAST_INSERT_ID()
--mysql_utilities.identity := v_newVal;
-- assign the value from the sequence to emulate the identity column
--:new.id := v_newVal;
END IF;
END;
I use a online conversion tool then manage to create it as
DECLARE
v_newVal NUMBER(12) := 0;
v_incval NUMBER(12) := 0;
BEGIN
IF INSERTING AND :new.id IS NULL THEN
SELECT hvr_storyboards_id_SEQ.NEXTVAL INTO v_newVal FROM DUAL;
-- If this is the first time this table have been inserted into (sequence == 1)
IF v_newVal = 1 THEN
--get the max indentity value from the table
SELECT NVL(max(id),0) INTO v_newVal FROM hvr_storyboards;
v_newVal := v_newVal + 1;
--set the sequence to that value
LOOP
EXIT WHEN v_incval>=v_newVal;
SELECT hvr_storyboards_id_SEQ.nextval INTO v_incval FROM dual;
END LOOP;
END IF;
--used to emulate LAST_INSERT_ID()
--mysql_utilities.identity := v_newVal;
-- assign the value from the sequence to emulate the identity column
--:new.id := v_newVal;
END IF;
END;
but I am getting this error
An exception occurred while executing 'INSERT INTO hvr_storyboards (name, updated_datetime, domain_id, ticker_id, updated_by) VALUES (?, ?, ?, ?, ?)' with params ["this is a test 6 - Ace", null, 21, null, null]: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'INSERTING' in 'field list'
what did I do wrong?
Related
I want to create a procedure that would generate records for a training schedule table with dates for 4 weeks(or a month) from the specified start date, 3 times per week (Monday, Wednesday, Friday or Tuesday, Thursday, Saturday). If a training already exists on a date for that user, there is no need to insert a record. The schedule table is:
TRAININGID NUMBER
USERNAME VARCHAR
TRAININGDATE DATE
Here my code:
CREATE OR REPLACE PROCEDURE schedule_training
(p_training_id IN OUT trainings.trainingid%TYPE,
p_username trainings.username%TYPE,
p_training_date IN OUT trainings.trainingdate%TYPE) IS
v_date DATE := TO_DATE(TO_CHAR(ADD_MONTHS(p_training_date,1),'DD-MON-YYYY'));
v_date1 trainings.trainingdate%TYPE;
v_username trainings.username%TYPE;
BEGIN
WHILE(p_training_date < v_date)
LOOP
SELECT trainingdate, username INTO v_date1, v_username
FROM trainings;
IF(TO_CHAR(p_training_date,'d') = 1) THEN
IF p_username != v_username AND p_training_date != v_date1
THEN INSERT INTO trainings VALUES
(p_training_id, p_username, p_training_date);
p_training_id := p_training_id + 1;
END IF;
ELSIF(TO_CHAR(p_training_date,'d') = 3) THEN
IF p_username != v_username AND p_training_date != v_date1
THEN INSERT INTO trainings VALUES
(p_training_id, p_username, p_training_date);
p_training_id := p_training_id + 1;
END IF;
ELSIF(TO_CHAR(p_training_date,'d') = 5) THEN
IF p_username != v_username AND p_training_date != v_date1
THEN INSERT INTO trainings VALUES
(p_training_id, p_username,p_training_date);
p_training_id := p_training_id + 1;
END IF;
END IF;
p_training_date := TO_DATE(TO_DATE(v_date,'dd.mm.yyyy')+ 1, 'dd.mm.yyyy');
END LOOP;
END schedule_training;
and I am calling this procedure like this:
schedule_training(1,'user1',TO_DATE('21-03-2021','DD-MM-YYYY'));
When I am calling it there is occurring unknown error:
Error starting at line : 41 in command -
schedule_training(1,'user1',TO_DATE('21-03-2021','DD-MM-YYYY'))
Error report -
Unknown Command
Running TO_DATE() on a values which is already a DATE does not make any sense.
So use simply
v_date DATE := ADD_MONTHS(p_training_date,1);
p_training_date := v_date + 1;
The result of TO_CHAR(..., 'd') depents on current user session NLS_TERRITORY settings, it may change at any time. Better use TO_CHAR(p_training_date, 'DY', 'nls_date_language = american') IN ('MON', 'WED', 'FRI')
The query SELECT trainingdate, username INTO v_date1, v_username FROM trainings; is a problem SELECT ... INTO ... requires the query to return exactly one row.
And finally you don't need any loop. You can use row generator, should be similar to this:
v_date DATE := ADD_MONTHS(p_training_date,1);
INSERT INTO trainings (better, list, column, names, here)
SELECT p_training_id + ROWNUM, p_username, training_date
FROM (
SELECT p_training_date + LEVEL as training_date
FROM dual
CONNECT BY p_training_date + LEVEL <= v_date)
WHERE to_char(training_date , 'DY', 'nls_date_language = american') in ('MON', 'WED', 'FRI')
AND NOT EXISTS (
SELECT 1
FROM trainings
WHERE username = v_username AND trainingdate = training_date)
p_training_id := p_training_id + SQL%ROWCOUNT;
I am trying to enable the user to upload a CSV file with more than 45 columns into my Oracle APEX application, so I am unable to use the Data Load Wizard functionality. I found the following thread on how to do this with a solution by ZKay: https://community.oracle.com/message/9316828#9316828. I have created a file browse item and attached the following PL/SQL procedure to a button that I want to import the file into the EMP table as described below. However, I am getting the following error:
ORA-06550: line 29, column 15: PLS-00201: identifier 'HEX_TO_DECIMAL' must be declared ORA-06550: line 29, column 1: PL/SQL: Statement ignored
PL/SQL Process:
BEGIN
DECLARE
v_blob_data BLOB;
v_blob_len NUMBER;
v_position NUMBER;
v_raw_chunk RAW(10000);
v_char CHAR(1);
c_chunk_len number := 1;
v_line VARCHAR2 (32767) := NULL;
v_data_array wwv_flow_global.vc_arr2;
v_rows number;
v_sr_no number := 1;
v_rows_loaded NUMBER;
BEGIN
-- Read data from wwv_flow_files</span>
select blob_content into v_blob_data
from wwv_flow_files
where last_updated = (select max(last_updated) from wwv_flow_files where UPDATED_BY = :APP_USER)
and id = (select max(id) from wwv_flow_files where updated_by = :APP_USER);
v_blob_len := dbms_lob.getlength(v_blob_data);
v_position := 1;
-- Read and convert binary to char</span>
WHILE ( v_position <= v_blob_len ) LOOP
v_raw_chunk := dbms_lob.substr(v_blob_data,c_chunk_len,v_position);
v_char := chr(hex_to_decimal(rawtohex(v_raw_chunk)));
v_line := v_line || v_char;
v_position := v_position + c_chunk_len;
-- When a whole line is retrieved </span>
IF v_char = CHR(10) THEN
-- Convert comma to : to use wwv_flow_utilities </span>
v_line := REPLACE (v_line, ',', ':');
-- Convert each column separated by : into array of data </span>
v_data_array := wwv_flow_utilities.string_to_table (v_line);
--DELETE OLD DATA
-- Insert data into target table </span>
IF v_sr_no >1 THEN
EXECUTE IMMEDIATE 'INSERT INTO EMP(EMPNO, ENAME, SAL, DEPTNO)
VALUES (:1, :2, :3, :4)'
USING
-- v_sr_no,
v_data_array(1),
v_data_array(2),
v_data_array(3),
v_data_array(4);
END IF;
-- Clear out
v_line := NULL;
v_sr_no := v_sr_no + 1;
END IF;
END LOOP;
END;
COMMIT;
END;
I'm trying to assign a value to a variable based on an if statement to be used to insert into a table as part of a trigger
I'm trying to assign a value to a variable based if another variable that is calculated is great than zero.
CREATE OR REPLACE TRIGGER transactions_checking_trigger
AFTER INSERT OR UPDATE ON checking
FOR EACH ROW
DECLARE
account_type char(4);
account_num char(4);
trans_date date;
trans_amt number;
trans_type char(4);
trans_comments varchar(25);
BEGIN
account_type := 'CHEK';
trans_date := sysdate;
trans_amt := :new.balance-:old.balance;
if trans_amt > 0
trans_type := 'DEPT'
ELSE
trans_type := 'WDRW'
end if;
IF UPDATE THEN
INSERT INTO transactions (account_type, account_num, trans_date,
trans_amt, trans_type,trans_comments)
VALUES (account_type, :new.account_num,trans_date,trans_amt, trans_type,
new:trans_comments);
END IF;
END;
/
I expect the trigger to insert DEPT if trans_amt > 0 and WDRW if trans_amt < 0
Syntax is IF-THEN-ELSE; you're missing the THEN. Also, statement has to be terminated with a semi-colon.
if trans_amt > 0
then --> this
trans_type := 'DEPT'; --> semi-colon
ELSE
trans_type := 'WDRW'; --> semi-colon
end if;
A simpler option:
trans_type := case when trans_amt > 0 then 'DEPT'
else 'WDRW'
end;
This is wrong:
IF UPDATE THEN
Did you mean updating instead?
i have this table , that i want to make before insert trigger
that will check if the new inserted value had null in column A , then it will insert 0 in column B + it will set created_On with sysdate
This is my desired output
COLUMN_A COLUMN_B CREATED_BY UPDATE_BY
null 0 sysdate sysdate
12 1 sysdate sysdate
And this my trigger
CREATE OR REPLACE TRIGGER SCH.TABLEA_TRG BEFORE
INSERT or update
ON SCH.TABLEA REFERENCING OLD AS old NEW AS new
FOR EACH ROW
begin
if inserting then
:NEW.CREATED_ON := sysdate ;
:NEW.UPDATED_ON := sysdate ;
if :COLUMN_A is null
then set :new.COLUMN_B 0
else :COLUMN_A is not null
then set :new.COLUMN_B 1
elsif updating then
:NEW.UPDATED_ON := sysdate ;
end if;
end;
but it has syntax error and can't figure it out
There were several mistakes - missing :NEW before some bind variables, missing end if, there is no "set" command, incorrect column name. This seemed to compile.
CREATE OR REPLACE TRIGGER tablea_trg BEFORE
INSERT OR UPDATE ON tablea
REFERENCING
OLD AS old
NEW AS new
FOR EACH ROW
BEGIN
IF inserting THEN
:new.created_on := SYSDATE;
:new.updated_on := SYSDATE;
IF :new.column_a IS NULL THEN
:new.column_b := 0;
ELSE
IF :new.column_a IS NOT NULL THEN
:new.column_b := 1;
END IF;
END IF;
ELSIF updating THEN
:new.updated_on := SYSDATE;
END IF;
END;
However dull it is, the Oracle Help is always a good reference.
I have oracle pl/sql procedure with below:
TYPE Paycomp2 IS RECORD(
Row_Id VARCHAR2(15),
Created DATE,
Created_By VARCHAR2(15),
Last_Upd DATE,
Last_Upd_By VARCHAR2(15),
Modification_Num NUMBER(10),
Conflict_Id VARCHAR2(15),
Comp_Price NUMBER(10),
Access_Level VARCHAR2(30),
Comp_Name VARCHAR2(30),
Depends_On VARCHAR2(30),
Gold_Cat VARCHAR2(30),
Order_Type VARCHAR2(30),
Parent_Id VARCHAR2(15),
Price_Plan VARCHAR2(30),
TYPE VARCHAR2(30),
Check_Flag VARCHAR2(1),
PREPAID_INIT_PRICE number(10),
DB_LAST_UPD date,
DB_LAST_UPD_SRC varchar2(50),
Unit_Type varchar2(30),
M2M_CATEGORY varchar2(30));
TYPE Paycomp IS REF CURSOR;
C2 Paycomp;
Cursor2 Paycomp2;
when I do the below operation
FETCH C2 INTO Cursor2;
I am getting this error :
ORA-01007: variable not in select list error.
This piece of script has worked previously.
How to resolve this issue?
script
Vordertype := 'Migration Prepaid - Postpaid';
Curcomp_Sql := Curcomp_Sql || Vordertype || '''' || ' union all ' || '' || Curcomp2sql || '' ||
Vordertype || '''';
OPEN C2 FOR Curcomp_Sql;
Sadmin.Pkg_Spliter.Prcsplitchar(Ppaycompstr, ';', Arrcomplist);
Vtotalcompprc := 0;
Arrcount := Arrcomplist.Count;
BEGIN
Dbms_output.put_line('reached17');
LOOP
FETCH C2
INTO Cursor2;
Dbms_output.put_line('reached18');
EXIT WHEN C2%NOTFOUND;
-- Processing each entry from Array
Compfndflg := 0;
dbms_output.put_line('arrCount 0: reached');
FOR Counter IN 1 .. Arrcount
LOOP
Vstrcommand := Arrcomplist(Counter);
dbms_output.put_line('arrCount : reached');
Sadmin.Pkg_Spliter.Prcsplitchar(Vstrcommand, '?', Arrdisclist);
IF Arrdisclist.Count <> 0 THEN
dbms_output.put_line('arrCount : reached1');
-- Extracting the ? seperated values and putting them into variables
Vcompname := Arrdisclist(1);
--dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||VCOMPNAME);
BEGIN
-- Added by Accenture
IF Vcompname IS NOT NULL THEN
--dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||ARRDISCLIST(1)||'-'||ARRDISCLIST(2)||'-'||ARRDISCLIST(3));
SELECT COUNT(0)
INTO v_Count_Exist
FROM Siebel.Cx_Paycomp_Mtx a, Siebel.Cx_Paycomp_Mtx b
WHERE a.Row_Id = b.Parent_Id
AND a.Order_Type = Vordertype
AND b.Type = 'Payment Component'
AND b.Comp_Name = Vcompname;
IF (v_Count_Exist = 0) THEN
Err_Msg := 'Invalid Payment Component in String';
Result_Out := '74';
Errflg := 1;
--dbms_output.put_line('Counter 2' || counter);
--dbms_transaction.rollback;
RAISE Error_Out;
END IF;
END IF;
--dbms_output.put_line('Counter 3' || CURSOR2.comp_name);
IF Vcompname = Cursor2.Comp_Name
--and VCOMPNAME != '3'
THEN
Compfndflg := 1;
EXIT;
END IF;
END;
END IF;
END LOOP;
---DBMS_OUTPUT.PUT_LINE('VCOMPNAME, COMPFNDFLG'||VCOMPNAME||','||COMPFNDFLG);
--dbms_output.put_line('CURSOR2.comp_name :'||CURSOR2.comp_name||' - COMPFNDFLG :'||COMPFNDFLG);
IF Compfndflg != 1 THEN
IF Temp_Comp_String IS NULL THEN
Temp_Comp_String := Cursor2.Comp_Name || '?0?;';
---DBMS_OUTPUT.PUT_LINE('STRING 1'||TEMP_COMP_STRING);
ELSE
Temp_Comp_String := Temp_Comp_String || Cursor2.Comp_Name || '?0?;';
---DBMS_OUTPUT.PUT_LINE('STRING 2'||TEMP_COMP_STRING);
END IF;
--- END IF;
ELSE
IF Temp_Comp_String IS NULL THEN
Temp_Comp_String := Arrdisclist(1) || '?' || Arrdisclist(2) || '?' ||
Arrdisclist(3) || ';';
---DBMS_OUTPUT.PUT_LINE('STRING 3'||TEMP_COMP_STRING);
ELSE
Temp_Comp_String := Temp_Comp_String || Arrdisclist(1) || '?' || Arrdisclist(2) || '?' ||
Arrdisclist(3) || ';';
---DBMS_OUTPUT.PUT_LINE('STRING 4'||TEMP_COMP_STRING);
END IF;
-- end if;
--- END IF;
END IF;
END LOOP;
END;
Curcomp_Sql VARCHAR2(2000) := 'SELECT mtx2.*
FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2
WHERE mtx2.parent_id = mtx1.row_id
AND mtx2.comp_name <> ''Security Deposit''
AND mtx2.TYPE = ''Payment Component''
AND mtx1.order_type = ''';
Curcomp2sql VARCHAR2(2000) := 'SELECT mtx2.*
FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2
WHERE mtx2.parent_id = mtx1.row_id
AND mtx2.comp_name = ''Security Deposit''
AND mtx2.TYPE = ''Payment Component''
AND mtx2.depends_on = ''ACCESS LEVEL''
AND mtx1.order_type = ''';
A simplified version of what you're seeing, with a dummy table and simple anonymous block:
create table t42 (id number, some_value varchar2(10));
declare
type t_rec is record(id number, some_value varchar2(10));
l_rec t_rec;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
PL/SQL procedure successfully completed.
To get the error you're seeing I just need to remove one of the table columns:
alter table t42 drop column some_value;
and run exactly the same code again:
declare
type t_rec is record(id number, some_value varchar2(10));
l_rec t_rec;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
ORA-01007: variable not in select list
ORA-06512: at line 10
The field list in the record type declared in the PL/SQL block no longer matches the column type in the cursor query. The record variable you're fetching into expects two columns (in my version; 22 in yours), but the query only gets one value.
You can (some would say should) specify all the columns you're selecting explicitly, but assuming you're actually referring to them all later you would then have done the equivalent of:
open l_cur for 'select id, some_value from t42';
which would still have errored after the column removal, though a bit more helpfully perhaps:
ORA-00904: "SOME_VALUE": invalid identifier
ORA-06512: at line 9
Since you're currently intending to get all columns from a single table, you could also have used the %rowtype syntax instead of your own record type:
declare
l_rec t42%rowtype;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
close l_cur;
end;
/
which with this trivial example runs successfully. You'll still have a problem though as soon as you refer to the removed column, assuming it's still part of the record:
declare
l_rec t42%rowtype;
l_cur sys_refcursor;
begin
open l_cur for 'select * from t42';
fetch l_cur into l_rec;
dbms_output.put_line(l_rec.some_value);
close l_cur;
end;
/
ORA-06550: line 7, column 30:
PLS-00302: component 'SOME_VALUE' must be declared
ORA-06550: line 7, column 3:
PL/SQL: Statement ignored
(Using %rowtype would give you some breathing space if a column was added, as it would just be ignored, unless and until you added code to refer to that record field. But with your code you'd get ORA-00932 inconsistent data types, rather than ORA-01007, so that doesn't seem to be what's happening here.)
If you aren't referring to the removed column/field anywhere then you shouldn't be selecting it anyway. Change the record type to only include the fields you actually need, and only get the corresponding columns in the cursor query.
If you are referring to the removed column/field then you're stuck anyway - you'll have find out what was removed and why, and then either fix your code to not refer to it (if that makes sense), or get that change reverted.