SQL Trigger Statement ignored - sql

It should ensure that you can set only predefined values else it shows error. I get error
Error at line 6: PL/SQL: Statement ignored
4. FOR EACH ROW
5. DECLARE
6. v_stru VARCHAR2(50);
CREATE OR REPLACE TRIGGER radnici_strucna_sprema
BEFORE INSERT OR UPDATE OF STRUCNA_SPREMA ON radnici
FOR EACH ROW
DECLARE
v_stru VARCHAR2(50);
BEGIN
v_stru := :NEW.strucna_sprema;
IF v_ss = 'osnovno' THEN
:NEW.strucna_sprema := v_stru;
ELSIF v_ss = 'srednje' THEN
:NEW.strucna_sprema := v_stru;
ELSIF v_ss = 'vise' THEN
:NEW.strucna_sprema := v_stru;
ELSIF grade = 'visoko' THEN
:NEW.strucna_sprema := v_stru;
ELSE
RAISE_APPLICATION_ERROR(NUM => -20002,
MSG => 'Forma strucne spreme nije odgovarajuca!');
END IF;
END;

try like this:
CREATE OR REPLACE TRIGGER radnici_strucna_sprema
BEFORE INSERT OR UPDATE ON radnici
FOR EACH ROW
DECLARE
v_stru VARCHAR2(50);
BEGIN
v_stru := :NEW.strucna_sprema;
IF v_ss = 'osnovno' THEN
:NEW.strucna_sprema := v_stru;
ELSIF v_ss = 'srednje' THEN
:NEW.strucna_sprema := v_stru;
ELSIF v_ss = 'vise' THEN
:NEW.strucna_sprema := v_stru;
ELSIF grade = 'visoko' THEN
:NEW.strucna_sprema := v_stru;
ELSE
RAISE_APPLICATION_ERROR(NUM => -20002,
MSG => 'Forma strucne spreme nije odgovarajuca!');
END IF;
END;
The problem is
OF STRUCNA_SPREMA.
This variable, STRUCNA_SPREMA, is a column in your table, radnici, or what is representing ?
But to be honest, I do not understand your logic. You assign the value of the column in a variable and then assign the value of that variable in your column. Why ?! Moreover, be sure that STRUCNA_SPREMA is a varchar.
Kind regards,
Stefan

Related

I keep getting this error: ORA-06502: PL/SQL: numeric or value error: character to number conversion error

I keep getting this error: ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 44
ORA-06512: at "SYS.DBMS_SQL", line 1721
Please what am I doing wrong here, because I have checked and it seems the code is fine. I declare a boolean payment_status, and reassigned a value 'tru' to it
DECLARE
pyld_id number(30);
p_amt number(30);
p_user_id number(30);
p_reference varchar2(100);
p_name varchar2(100);
p_narration varchar2(100);
p_payment_date DATE default sysdate;
p_net_amt NUMBER default null;
p_payment_type_id number(30);
p_transaction_type_id number(30);
p_payment_id number(30);
payment_status boolean ;
done boolean ;
p_order number(30);
p_id number(30);
p_parent_id number(30);
p_order_id number(30);
BEGIN
p_payment_id := 1;
done := TRUE;
p_reference := 'vartesr56';
p_payment_id := 45;
p_user_id := 19411 ;
p_amt := 2000;
p_net_amt := 2000;
p_name := 'Test';
p_narration := 'Product Activation';
p_transaction_type_id := 1;
p_payment_type_id := 1;
payment_status := TRUE;
PSTK_PAYMENT_PACKAGE.add_payment(p_amt, p_user_id, p_reference, p_name, p_narration, p_payment_date, p_net_amt, p_payment_type_id, p_transaction_type_id, p_payment_id, payment_status);
if payment_status != TRUE then
---do somethinh
DBMS_OUTPUT.ENABLE ('NULL');
p_id := 19411;
p_order_id := 3080514;
p_user_id := 19411;
-- get the parent id of the user
DBMS_OUTPUT.PUT_LINE('wants to assign');
select draft_parent_user_id into p_parent_id from users where id = p_id fetch first 1 rows only;
-- set the parent id of the user
update users set PARENT_USER_ID = p_parent_id where id = p_id;
DBMS_OUTPUT.PUT_LINE('updated');
order_pkg.confirm_order(p_order_id=>p_id,p_user_id=>p_user_id ,p_done => done);
if done = true then
---Do something
DBMS_OUTPUT.PUT_LINE('NULL');
else
-- apex_error.add_error (
--p_message => 'Unable to activate package. Please contact admin',
-- p_display_location => apex_error.c_inline_in_notification );
DBMS_OUTPUT.PUT_LINE('NULL');
end if;
END IF;
END;

catch the value of response headers and use it in another api call in pl sql

I would like to ask how can I loop the value of a return in 'url_next' variable into url varible so that I can use the function until the all users imported from the api call .
so the value returned from 'url_next'
into
url := 'https://dev-9466225.okta.com/api/v1/users';
l_http_request := utl_http.begin_request(apex_string.format( url , 'GET', 'HTTP/1.1'));
create or replace function OKTA_API_X
(url IN VARCHAR2)
return varchar2
IS
v_username VARCHAR2(50);
v_email VARCHAR2(50);
v_firstname VARCHAR2(50);
v_last_name VARCHAR2(50);
l_http_request utl_http.req;
l_http_response utl_http.resp;
l_text VARCHAR2(32767);
resp CLOB := '';
l_json_obj json_object_t;
l_json_in json_array_t;
name VARCHAR2(2560);
value VARCHAR2(2024);
url_next VARCHAR2(100);
url VARCHAR2(50);
BEGIN
url := 'https://dev-9466225.okta.com/api/v1/users';
l_http_request := utl_http.begin_request(apex_string.format( url , 'GET', 'HTTP/1.1'));
utl_http.set_wallet('file:c:/okta_wallet_base/', NULL);
utl_http.set_header(l_http_request, 'content-type', 'application/json');
utl_http.set_header(l_http_request, 'authorization', 'SSWS 00mz6_ost-rfegVu5K5I6dEs33JLIFSmcBO8VxzI');
utl_http.set_header(l_http_request, 'Accept', 'application/json');
l_http_response := utl_http.get_response(l_http_request);
-- dbms_output.put_line('HTTP response status code =>' || l_http_response.status_code);
-- dbms_output.put_line('HTTP response reason phrase => ' || l_http_response.reason_phrase);
BEGIN
LOOP
utl_http.read_text(l_http_response, l_text,32766)
resp := resp || l_text;
END LOOP;
END;
--- JASON PARSING
l_json_in := json_array_t(resp);
FOR indx IN 0..l_json_in.get_size - 1 LOOP
l_json_obj := TREAT(l_json_in.get(indx) AS json_object_t);
--GET JSON OBJECT AND STRINGS FROM RESPONSE
v_firstname := l_json_obj.get_object('profile').get_string('firstName');
v_last_name := l_json_obj.get_object('profile').get_string('lastName');
v_email := l_json_obj.get_object('profile').get_string('email');
v_username := l_json_obj.get_object('profile').get_string('login');
-------------------------------
dbms_output.put_line(v_firstname);
--dbms_output.put_line(v_EMAIL);
END LOOP;
---------------------------------------------------------------------------- FOR i IN 1..
utl_http.get_header_count(l_http_response) LOOP
utl_http.get_header(l_http_response, i, name, value);
IF
name = 'link'
AND value LIKE '%rel="next"'
THEN
url_next := ( trim(TRAILING '>' FROM regexp_substr(value, 'http[^>]+>')) );
END IF;
END LOOP;
BEGIN
WHILE url_next IS NOT NULL LOOP
IF url_next <> url THEN
url := url_next;
ELSE
NULL;
END IF;
END LOOP;
END;
EXCEPTION
WHEN OTHERS THEN
BEGIN
utl_http.end_response(l_http_response);
dbms_output.put_line('ERROR →' || sqlerrm);
END;
END;

Bypass the JSON object using PL / SQL, and output all data in key value format in Oracle

I have JSON, I want to bypass it and display all the data that is in it. But the problem is that I can't know what data will be there. I made the code, but it only looks for top-level objects. And the rest are not. I will be grateful for your help.
DECLARE
l_object json_object_t;
l_key_list json_key_list;
v_clob CLOB;
tv apex_json.t_values;
BEGIN
-- JSON_OBJECT can figure out what keys it has...
v_clob := '{"devices":{"id":"d652f632-0835-871b-a140-58701f019000","scale_id":"88348A32BD3D149FE055000000000001"},"data":{"external_id":"40023"},"data_weight":{"weight":"20322","prevWeight":"1000","prevTransaction":"1607680754361","transaction":"1607680754361","on":"false","transactionDataCount":"1","stable":"false","duration":"12","transactionMaxWeight":"2000","perimetr":"true","driverInCar":"false"}}';
apex_json.parse(tv,v_clob);
l_object := json_object_t.parse (v_clob);
l_key_list := l_object.get_keys;
FOR counter IN 1 .. l_key_list.COUNT
LOOP
DBMS_OUTPUT.put_line (
l_key_list (counter)
|| ' : '
|| apex_json.get_varchar2(p_path => l_key_list (counter), p_values => tv));
END LOOP;
END;
If you take into account only the top level objects, then this code works
DECLARE
l_object json_object_t;
l_key_list json_key_list;
v_clob CLOB;
tv apex_json.t_values;
BEGIN
-- JSON_OBJECT can figure out what keys it has...
v_clob := '{"devices":"3423","data":"okwwwe"}';
apex_json.parse(tv,v_clob);
l_object := json_object_t.parse (v_clob);
l_key_list := l_object.get_keys;
FOR counter IN 1 .. l_key_list.COUNT
LOOP
DBMS_OUTPUT.put_line (
l_key_list (counter)
|| ' : '
|| apex_json.get_varchar2(p_path => l_key_list (counter), p_values => tv));
END LOOP;
END;
RESULT :
devices : 3423
data : okwwwe
And how to deduce the data from the first example, I can not understand. These data must correspond to the hierarchy.
If you have access to the native JSON types (JSON_ELEMENT_T, JSON_ARRAY_T, etc.) you should always use them over using the APEX_JSON package ans they will have much better performance. A package similar to the one below can be used to output the full hierarchy of a JSON object or array. Feel free to tweak the package to change the format of the output.
Package Specification
CREATE OR REPLACE PACKAGE output_json
AS
c_padding_char CONSTANT VARCHAR2 (1) := '-';
c_padding_amount CONSTANT PLS_INTEGER := 1;
PROCEDURE output_scalar (p_element json_element_t,
p_padding PLS_INTEGER,
p_json_key VARCHAR2 DEFAULT NULL);
PROCEDURE output_object (p_object json_object_t, p_padding PLS_INTEGER);
PROCEDURE output_array (p_array json_array_t, p_padding PLS_INTEGER);
PROCEDURE output_element (p_element json_element_t,
p_padding PLS_INTEGER,
p_json_key VARCHAR2 DEFAULT NULL);
END;
/
Package Body
CREATE OR REPLACE PACKAGE BODY output_json
AS
PROCEDURE output_scalar (p_element json_element_t,
p_padding PLS_INTEGER,
p_json_key VARCHAR2 DEFAULT NULL)
IS
BEGIN
DBMS_OUTPUT.put_line (
LPAD (c_padding_char, p_padding, c_padding_char)
|| CASE WHEN p_json_key IS NOT NULL THEN p_json_key || ' : ' END
|| CASE
WHEN p_element.is_boolean
THEN
CASE WHEN p_element.to_boolean THEN 'TRUE' ELSE 'FALSE' END || ' (boolean)'
WHEN p_element.is_date
THEN
TO_CHAR (p_element.TO_DATE, 'YYYY-MM-DD') || ' (date)'
WHEN p_element.is_number
THEN
p_element.TO_NUMBER || ' (number)'
WHEN p_element.is_string
THEN
p_element.TO_STRING || ' (string)'
END);
END;
PROCEDURE output_object (p_object json_object_t, p_padding PLS_INTEGER)
IS
l_keys json_key_list;
l_element json_element_t;
BEGIN
l_keys := p_object.get_keys;
FOR i IN 1 .. l_keys.COUNT
LOOP
l_element := p_object.get (l_keys (i));
output_element (l_element, p_padding, l_keys (i));
END LOOP;
END;
PROCEDURE output_array (p_array json_array_t, p_padding PLS_INTEGER)
IS
BEGIN
FOR i IN 0 .. p_array.get_size - 1
LOOP
output_element (p_array.get (i), p_padding);
END LOOP;
END;
PROCEDURE output_element (p_element json_element_t,
p_padding PLS_INTEGER,
p_json_key VARCHAR2 DEFAULT NULL)
IS
BEGIN
DBMS_OUTPUT.put_line (
CASE
WHEN p_json_key IS NOT NULL AND NOT p_element.is_scalar THEN p_json_key || ' : '
END);
IF p_element.is_scalar
THEN
output_scalar (p_element, p_padding, p_json_key);
ELSIF p_element.is_object
THEN
output_object (TREAT (p_element AS json_object_t), p_padding + c_padding_amount);
ELSIF p_element.is_array
THEN
output_array (TREAT (p_element AS json_array_t), p_padding + c_padding_amount);
END IF;
END;
END;
/
Example Call
DECLARE
l_clob CLOB;
BEGIN
l_clob :=
'{"arr":[1,2,3],"devices":{"id":"d652f632-0835-871b-a140-58701f019000","scale_id":"88348A32BD3D149FE055000000000001"},"data":{"external_id":"40023"},"data_weight":{"weight":"20322","prevWeight":"1000","prevTransaction":"1607680754361","transaction":"1607680754361","on":"false","transactionDataCount":"1","stable":"false","duration":"12","transactionMaxWeight":"2000","perimetr":"true","driverInCar":"false"}}';
output_json.output_element (json_element_t.parse (l_clob), 0);
END;
/
Example Output
arr :
--1 (number)
--2 (number)
--3 (number)
devices :
--id : "d652f632-0835-871b-a140-58701f019000" (string)
--scale_id : "88348A32BD3D149FE055000000000001" (string)
data :
--external_id : "40023" (string)
data_weight :
--weight : "20322" (string)
--prevWeight : "1000" (string)
--prevTransaction : "1607680754361" (string)
--transaction : "1607680754361" (string)
--on : "false" (string)
--transactionDataCount : "1" (string)
--stable : "false" (string)
--duration : "12" (string)
--transactionMaxWeight : "2000" (string)
--perimetr : "true" (string)
--driverInCar : "false" (string)
I also made my own version, but it is limited to 2 levels of objects, and does not take into account arrays.
DECLARE
l_object json_object_t;
l_key_obj json_key_list;
v_clob CLOB;
tv apex_json.t_values;
obj_in_obj JSON_OBJECT_T;
l_key_list json_key_list;
BEGIN
v_clob := '{
"devices":{
"id":"d652f632-0835-871b-a140-58701f019000",
"scale_id":"88348A32BD3D149FE055000000000001"
},
"data":{
"external_id":"40023"
},
"data_weight":{
"weight":"20322",
"prevWeight":"1000",
"prevTransaction":"1607680754361",
"transaction":"1607680754361",
"on":"false",
"transactionDataCount":"1",
"stable":"false",
"duration":"12",
"transactionMaxWeight":"2000",
"perimetr":"true",
"driverInCar":"false"
}
}';
apex_json.parse(tv,v_clob);
l_object := json_object_t.parse (v_clob);
l_key_list := l_object.get_keys;
FOR counter IN 1 .. l_key_list.COUNT
LOOP
obj_in_obj := l_object.get_object(l_key_list (counter));
l_key_obj := obj_in_obj.get_keys;
FOR counter_all_obj IN 1 .. l_key_obj.COUNT
LOOP
DBMS_OUTPUT.put_line (
l_key_list (counter)||'.'||l_key_obj (counter_all_obj)
|| ' : '
|| apex_json.get_varchar2(p_path => l_key_list (counter)||'.'|| l_key_obj (counter_all_obj), p_values => tv));
END LOOP;
END LOOP;
END;

Error ORA-06530 from function that returns an object type

I have the following function GET_UN_COLLECTED_4LD which returns the type ld_data_type:
CREATE OR REPLACE TYPE ld_data_type AS OBJECT(collected NUMBER, uncollected NUMBER);
/
CREATE OR REPLACE FUNCTION GET_UN_COLLECTED_4LD (VAPPOINTOFCAID NUMBER,
VPREVLIQUIDATE NUMBER,
VCURRLIQUIDATE NUMBER,
VNEXTLIQUIDATE NUMBER,
YEPT NUMBER)
RETURN LD_DATA_TYPE
AS
OUT_VAR LD_DATA_TYPE;
VNETV23 NUMBER;
VNETV24 NUMBER;
VCURR23 NUMBER;
VCURR24 NUMBER;
VCOLLECTED NUMBER;
VUNCOLLECTED NUMBER;
BEGIN
SELECT SUM (NETX) - SUM (NETP)
INTO VNETV23
FROM VIEW_CUSTOMER_TRN4INVS4LD
WHERE APPOINTOFCAID = VAPPOINTOFCAID AND VAT = ABS (1.23);
SELECT SUM (NETX) - SUM (NETP)
INTO VNETV24
FROM VIEW_CUSTOMER_TRN4INVS4LD
WHERE APPOINTOFCAID = VAPPOINTOFCAID AND VAT = ABS (1.24);
VCOLLECTED := 0;
VUNCOLLECTED := 0;
CASE
WHEN YEPT = 0
THEN
VCURR24 := VCURRLIQUIDATE - VNETV24;
CASE
WHEN VCURR24 > 0
THEN
VCOLLECTED := VNETV24 * 1.24;
VCURR23 := VCURRLIQUIDATE - VNETV23;
CASE
WHEN VCURR23 > 0
THEN
VCOLLECTED := -999;
ELSE
VCOLLECTED :=
VCOLLECTED + ( (VCURRLIQUIDATE - VCURR24) * 1.23);
END CASE;
ELSE
VCOLLECTED := -1999;
END CASE;
ELSE
OUT_VAR.COLLECTED := -888;
OUT_VAR.UNCOLLECTED := -889;
END CASE;
SELECT VCOLLECTED, VUNCOLLECTED
INTO OUT_VAR.COLLECTED, OUT_VAR.UNCOLLECTED
FROM DUAL;
/*
OPEN buffer_cur;
FETCH buffer_cur INTO out_var.val1, out_var.val2;
CLOSE buffer_cur; */
RETURN OUT_VAR;
END GET_UN_COLLECTED_4LD;
When I call the function like
select GET_UN_COLLECTED_4LD(171231, 42240, 31680, 0, 0) from dual;`
I get an error:
Execution (50: 8): ORA-06530: Reference to uninitialized composite
ORA-06512: at "C##SOLSA.GET_UN_COLLECTED_4LD", line 56
I'm use Oracle 12c Standard edition.
How should I be calling the function GET_UN_COLLECTED_4LD and Where is the problem that causes the error?
As the error says, you haven't initialised your object variable:
...
RETURN LD_DATA_TYPE
AS
OUT_VAR LD_DATA_TYPE := new LD_DATA_TYPE(null, null);
...
Your logic is slightly confused though; at the end of your case you do:
ELSE
OUT_VAR.COLLECTED := -888;
OUT_VAR.UNCOLLECTED := -889;
but then overwrite the value immediately afterwards with:
SELECT VCOLLECTED, VUNCOLLECTED
INTO OUT_VAR.COLLECTED, OUT_VAR.UNCOLLECTED
FROM DUAL;
Possibly you meant to set VCOLLECTED and VUNCOLLECTED in that ELSE. If you did that then you wouldn't need to initialise OUT_VAR, as the first remaining reference would create it; which you could do as:
OUT_VAR := LD_DATA_TYPE (VCOLLECTED, VUNCOLLECTED);
instead of selecting from dual; or you could not have the local variable at all and just do:
...
ELSE
VCOLLECTED := -888;
VUNCOLLECTED := -889;
END CASE;
RETURN LD_DATA_TYPE (VCOLLECTED, VUNCOLLECTED);
END GET_UN_COLLECTED_4LD;
First you need to initialize your object type OUT_VAR before you can set its properties like this:
OUT_VAR:= LD_DATA_TYPE(0,0);
See the details here.

how to compare two linear lists in pascal

The task is to create new list which contains 2 linear lists, and if elements of first list equal to elements of second list then we must delete the same element from new list
procedure CreateList(var t1,L1,t2,L2:plist);
var
tmp1, tmp2:plist;
begin
t1 := L1;
t2 := L2;
while t1 <> nil do
begin
write(t1^.Data, ' ');
t1 := t1^.Next;
while t2 <> nil do
begin
write(t2^.data, ' ');
tmp2:=t2;
t2 := t2^.Next;
if(t2 = tmp1^.next) then // here is the problem how to compare 2 elements
begin
tmp1 := t1;
t1 := t1^.Next;
Dispose(tmp1);
end;
end;
end;
Writeln;
readkey;
end;
I advise you to change type of you list for something like:
type
TData = integer;
PList = ^TList;
TList = record
data : TData;
next : PList;
copy : boolean;
end;
After you will use value .copy for checking copys. Here is simple code you need.
I tried to make all code as simple as possible.
procedure deleteCopys(var list:PList);
// make all TList.copy := false (after we will use it)
var
curList : PList;
begin
curList := list;
while (curList<>nil) do
begin
curList^.copy := false;
curList := curList^.next;
End;
End;
procedure createList(var list1, list2, list3:PList);
// we belive that: (list3 is empty) and (there is no copys in list1)
// and (there is no copys in list2)
var
curList1, curList2 : PList;
begin
deleteCopys(list1);
deleteCopys(list2);
deleteCopys(list3);
// make TList.copy := true for equal elements
// from curList1 and curList2
curList1 := list1;
while (curList1 <> nil) do
begin
curList2 := list2;
while (curList2 <> nil) do
begin
if (curList1^.data = curList2^.data) then
begin
curList1^.copy := true;
curList2^.copy := true;
break;
End;
curList2 := curList2^.next;
End;
curList1 := curList1^.next;
End;
// now we can put all elements from list1 and list2
// with state TLilt.copy=false
// and each of them will be different
// (Let's do it :)
curList1 := list1;
while (curList1 <> nil) do
begin
if (curList1^.copy = false) then
begin
//some procedure for new element
putNewElement(list3, curList1^.data);
End;
End;
curList2 := list2;
while (curList2 <> nil) do
begin
if (curList2^.copy = false) then
begin
//some procedure for new element
putNewElement(list3, curList2^.data);
End;
End;
end;
I hope it will help you!