Oracle APEX Pass null to REST Data source on POST/PUT - json

I would like to know if there is a way to pass a null on a json with REST Data Source? Currently, the problem i have is the null have double quote "null"
Here is my Request Body Template
{"dt_deb":"#DT_DEB#","dt_fin":"#DT_FIN#", "nom_proj":"#NOM_PROJ#","id_doss_clien":"#ID_DOSS_CLIEN#"}
In my Operation Operator i've put default value to null
And this is my PL/SQL i use to call my PUT REST API
declare
l_parameters apex_exec.t_parameters;
l_date date;
begin
if :REQUEST = 'CHANGE' then
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'id', p_value => :P910_ID_PROJ_COLAB_TRNFO_NUM );
end if;
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'ID_PROJ_COLAB_TRNFO_NUM', p_value => OTN.otnk_api_gestn_seq.nuf_otnprj );
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'NOM_PROJ', p_value => :P910_NOM_PROJET );
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'DT_DEB', p_value => to_char( to_date( SYSDATE ), 'YYYY-MM-DD' ) || 'T00:00:00Z' );
IF :P910_DT_FIN != 'O' THEN
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'DT_FIN', p_value => to_char( to_date( SYSDATE ), 'YYYY-MM-DD' ) || 'T00:00:00Z' );
END IF;
apex_exec.add_parameter( p_parameters => l_parameters, p_name => 'ID_DOSS_CLIEN', p_value => :P910_ID_DOSS_CLIEN );
apex_exec.execute_rest_source(
p_static_id => 'DETAIL_PROJET',
p_operation => case :REQUEST
when 'CHANGE' then 'PUT'
when 'CREATE' then 'POST' end,
p_parameters => l_parameters );
end;
Like you see, DT_FIN are optional and can have null, but because i've put null as defaut parameter, when i check the APEX Debug tool, i see "null"
Any idea how i can manage null value with a date?
Thanks for your help.

Related

Oracle Rest Data Service return a collection as JSON

I have some data in a collection, and I would like to send it as a result set in the response body.
Is it possible parse an associative array to JSON, and then send it as a result set?
As requested, let me show you how to use a collection embedded in a type to create a json and deliver it by a web rest service
Let's imagine I have the data of my employees in a table and I want to retrieve them by a web service using JSON. In this case I use ORDS, APEX 5.1.4 and Oracle 12c
1.This procedure retrieves the information in JSON using APEX_JSON. I think APEX_JSON is quite good for JSON generation in Oracle 12c, because there is a lot of bugs related with JSON in 12c.
CREATE OR REPLACE PROCEDURE get_emp_json (p_empno IN emp.empno%TYPE DEFAULT NULL) AS
l_cursor SYS_REFCURSOR;
BEGIN
OPEN l_cursor FOR
SELECT e.empno AS "empno",
e.ename AS "employee_name",
e.job AS "job",
e.mgr AS "mgr",
TO_CHAR(e.hiredate,'YYYY-MM-DD') AS "hiredate",
e.sal AS "sal",
e.comm AS "comm",
e.deptno AS "deptno"
FROM emp e
WHERE e.empno = DECODE(p_empno, NULL, e.empno, p_empno);
APEX_JSON.open_object;
APEX_JSON.write('employees', l_cursor);
APEX_JSON.close_object;
END;
/
2.Build the ORDS REST module ( in your own schema )
BEGIN
ORDS.define_module(
p_module_name => 'rest-v4',
p_base_path => 'rest-v4/',
p_items_per_page => 0);
ORDS.define_template(
p_module_name => 'rest-v4',
p_pattern => 'employees/');
ORDS.define_handler(
p_module_name => 'rest-v4',
p_pattern => 'employees/',
p_method => 'GET',
p_source_type => ORDS.source_type_plsql,
p_source => 'BEGIN get_emp_json; END;',
p_items_per_page => 0);
ORDS.define_template(
p_module_name => 'rest-v4',
p_pattern => 'employees/:empno');
ORDS.define_handler(
p_module_name => 'rest-v4',
p_pattern => 'employees/:empno',
p_method => 'GET',
p_source_type => ORDS.source_type_plsql,
p_source => 'BEGIN get_emp_json(:empno); END;',
p_items_per_page => 0);
COMMIT;
END;
/
3.Call the REST WEB SERVICE
http://yourhost:yourport/ords/hr/rest-v4/employees/
Conclusion
ORDS is a great tool to create web services using REST to retrieve in JSON format data from your database. Adapt it to your own needs. Normally the collection can be derived from a table or a type. In my example I use a SYS_REFCURSOR object to retrieve the JSON data.
The following articles possess great examples and guides step-by-step
https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-create-basic-rest-web-services-using-plsql#create-get-web-services
https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-restful-web-services-handling-complex-json-payloads
#RobertoHernandez gave a basic overview of the ORDS service which is not exactly what I was searching for, but thanks!
The function which fills the collection and creates the JSON object:
CREATE OR REPLACE FUNCTION f_get_data RETURN CLOB
AS
cst_key CONSTANT VARCHAR(32) := 'KEY';
cst_value CONSTANT VARCHAR(32) := 'VALUE';
TYPE r_summary IS RECORD (
key VARCHAR2(255),
value NUMBER
);
TYPE t_summary IS TABLE OF r_summary INDEX BY BINARY_INTEGER;
r_s r_summary;
tab_s t_summary;
json_clob CLOB;
i INTEGER;
BEGIN
-- insert some dummy data to the collection
FOR i IN 1..10 LOOP
r_s.key := dbms_random.string('A', 10);
r_s.value := ROUND(dbms_random.value(1,10), 2);
tab_s(tab_s.COUNT + 1) := r_s;
END LOOP;
-- write data to a JSON object
APEX_JSON.initialize_clob_output;
APEX_JSON.open_object;
APEX_JSON.open_array('data');
IF tab_s.COUNT > 0 THEN
FOR i IN tab_s.FIRST..tab_s.LAST LOOP
IF tab_s.EXISTS(i) THEN
APEX_JSON.open_object;
APEX_JSON.write(cst_key, tab_s(i).key);
APEX_JSON.write(cst_value, tab_s(i).value);
APEX_JSON.close_object;
END IF;
END LOOP;
END IF;
APEX_JSON.close_all;
json_clob := APEX_JSON.get_clob_output;
APEX_JSON.free_output;
RETURN json_clob;
END;
Create the web service as:
BEGIN
ORDS.DEFINE_MODULE(
p_module_name => 'test',
p_base_path => '/data/',
p_items_per_page => 25,
p_status => 'PUBLISHED',
p_comments => NULL);
ORDS.DEFINE_TEMPLATE(
p_module_name => 'test',
p_pattern => 'all',
p_priority => 0,
p_etag_type => 'HASH',
p_etag_query => NULL,
p_comments => NULL);
ORDS.DEFINE_HANDLER(
p_module_name => 'test',
p_pattern => 'all',
p_method => 'GET',
p_source_type => 'resource/lob',
p_items_per_page => 25,
p_mimes_allowed => '',
p_comments => NULL,
p_source =>
'SELECT
''application/json'',
f_get_data
FROM
sys.dual'
);
COMMIT;
END;
Finally call the ORDS:
http://<host>:<port>/ords/<db>/<schema>/data/all/
For more details read the following article which gave me the idea (credis to #thatjeffsmith ):
https://www.thatjeffsmith.com/archive/2017/09/ords-returning-raw-json/
This technique, returning a refcursor will also work for an autorest situation when you want to return an JSON array as an out parameter.
You will have to declare the record and the type at the schema or package level to get it to work.
FUNCTION f_get_data
RETURN SYS_REFCURSOR AS
cst_key CONSTANT VARCHAR(32) := 'KEY';
cst_value CONSTANT VARCHAR(32) := 'VALUE';
r_s r_summary;
tab_s t_summary;
json_clob SYS_REFCURSOR;
i INTEGER;
BEGIN
-- insert some dummy data to the collection
FOR i IN 1 .. 10
LOOP
r_s.key := DBMS_RANDOM.string('A', 10);
r_s.VALUE := ROUND(DBMS_RANDOM.VALUE(1, 10), 2);
tab_s(tab_s.COUNT + 1) := r_s;
END LOOP;
OPEN json_clob FOR SELECT * FROM TABLE(tab_s);
RETURN json_clob;
END;

An Issue with saving SalesOrders data from REST API call to Exact Online

I have been using PHP Client library for Exact Online for a long time.
After saving the customer Accounts, Addresses, Contacts and then filtering out the PaymentConditions based on WooCommerce orders, items are successfully reflecting in the Exact Online dashboard.
But unfortunately calling the SalesOrders post request API. I'm unable to store into the Exact Online dashboard,
even though in order to store only OrderedBy itself is enough which is given in the official documentation
$ordersn = $order->save();
Picqer\Financials\Exact\ApiException : Error 403: Forbidden
$order = new SalesOrder($connection);
$lines = new SalesOrderLine($connection);
....
echo'<pre>'; print_r($order);
$order->SalesOrderLines = $lines;
$ordersn = $order->save();
if ($ordersn->ID)
{
$orderitem['sync_flag'] = true;
}
Here is the details of an order array
Picqer\Financials\Exact\SalesOrder Object
(
...
[attributes:protected] => Array
(
[WarehouseID] => 26ca2016-453f-499a-8a34-c986009bc78d
[OrderID] => FC290B7D-766B-4CBB-B7A2-47327AA3841F
[OrderedBy] => 764a4f6d-4b39-43b4-a86c-265e5478afbd
[DeliverTo] => 764a4f6d-4b39-43b4-a86c-265e5478afbd
[OrderDate] => 2019-02-17T19:29:53
[YourRef] => 75591901YP220320G
[OrderedByName] => Peter Kerner
[Description] => 16031_PayPal/Lastschrift/Kreditkarte
[Remarks] => Order is processing
[PaymentReference] => 16031
[PaymentCondition] =>
[SalesOrderLines] => Picqer\Financials\Exact\SalesOrderLine Object
(
[attributes:protected] => Array
(
[OrderID] => FC290B7D-766B-4CBB-B7A2-47327AA3841F
[VATAmount] => 5,58
[Description] => Goodies Box
[Quantity] => 1,00
[UnitPrice] => 29,37
[Item] => 418d43d6-55fe-410a-8df2-b05cbb72cea5
)
...
)
)
...
)
Do we need to upload VAT code or Am I missing something else data to be resided first shown from the above order-array or what else should we need to call appropriate API. Since in-order to reflect on the Exact Online dashboard. what should we need to follow?
From the built-In function call addItem() below snippets of code:
$soLines = array(
'OrderID' => $lines->OrderID,
'Item' => $lines->Item,
'Description' => $lines->Description,
'Quantity' => $lines->Quantity,
'UnitPrice' => $lines->UnitPrice,
'VATAmount' => $lines->VATAmount,
'VATCode' => $lines->VATCode
);
$order->addItem($soLines);
Generates the results with LineNumber to be included in SalesOrderLines array
[attributes:protected] => Array
(
[WarehouseID] => 26ca2016-453f-499a-8a34-c986009bc78d
[OrderID] => 65F93F56-97A8-4D54-AE37-C0BDDE774E67
[OrderedBy] => 9b048b81-f729-413a-b196-526436f11fe7
[DeliverTo] => 9b048b81-f729-413a-b196-526436f11fe7
[OrderDate] => 2019-02-17T20:45:34
[YourRef] => 9Y9593859V795183K
[OrderedByName] => Katrin Lenk
[Description] => 16033_PayPal Express
[Remarks] => Order is processing
[PaymentReference] => 16033
[PaymentCondition] =>
[SalesOrderLines] => Array
(
[0] => Array
(
[OrderID] => 65F93F56-97A8-4D54-AE37-C0BDDE774E67
[Item] => 5c415369-615c-4953-b28c-c7688f61cfaa
[Description] => ABC Classic
[Quantity] => 2,00
[UnitPrice] => 15,08
[VATAmount] => 5,73
[VATCode] =>
[LineNumber] => 1
)
)
)
Also note I haven't created Journals, GLAccounts, Documents & DocumentAttachments API. Does this actually affects storing of SalesOrders
EDIT:
In much simpler
$salesOrder = new \Picqer\Financials\Exact\SalesOrder($connection);
$salesOrder->WarehouseID = '26ca2016-453f-499a-8a34-c986009bc78d';
$salesOrder->OrderID = '65F93F56-97A8-4D54-AE37-C0BDDE774E67';
$salesOrder->OrderedBy = '9b048b81-f729-413a-b196-526436f11fe7';
$salesOrder->DeliverTo = '9b048b81-f729-413a-b196-526436f11fe7';
$salesOrder->OrderDate = '2019-02-17T20:45:34';
$salesOrder->YourRef = '9Y9593859V795183K';
$salesOrder->OrderedByName = 'Katrin Lenk';
$salesOrder->Description = '16033_PayPal Express';
$salesOrder->Remarks = 'Order is processing';
$salesOrder->PaymentReference = '16033';
$salesOrder->PaymentCondition = 'PP';
$soLines = array(
'Item' => '5c415369-615c-4953-b28c-c7688f61cfaa',
'Description' => 'ABC Classic',
'Quantity' => '1,00',
'UnitPrice' => '29,37',
'OrderID' => '65F93F56-97A8-4D54-AE37-C0BDDE774E67'
);
echo '<pre>'; print_r($soLines);
$salesOrder->addItem($soLines);
echo '<pre>'; print_r($salesOrder);
$salesOrder->save();
Resulting value stored from the soLines array
[attributes:protected] => Array
(
[WarehouseID] => 26ca2016-453f-499a-8a34-c986009bc78d
[OrderID] => 65F93F56-97A8-4D54-AE37-C0BDDE774E67
[OrderedBy] => 9b048b81-f729-413a-b196-526436f11fe7
[DeliverTo] => 9b048b81-f729-413a-b196-526436f11fe7
[OrderDate] => 2019-02-17T20:45:34
[YourRef] => 9Y9593859V795183K
[OrderedByName] => Katrin Lenk
[Description] => 16033_PayPal Express
[Remarks] => Order is processing
[PaymentReference] => 16033
[PaymentCondition] =>
[SalesOrderLines] => Array
(
[0] => Array
(
[OrderID] => 65F93F56-97A8-4D54-AE37-C0BDDE774E67
[Item] => 5c415369-615c-4953-b28c-c7688f61cfaa
[Description] => ABC Classic
[Quantity] => 2,00
[UnitPrice] => 15,08
[VATAmount] => 5,73
[VATCode] =>
[LineNumber] => 1
)
)
)
Actual Result:
Picqer\Financials\Exact\ApiException : Error 403: Forbidden
The reason was OrderID value was included twice in the SalesOrderLine as well as in SalesOrder for the two REST API calls and removing the OrderID entry from SalesOrder worked perfectly and reflecting in the Exact Online Dashboard
You cannot assign $order->SalesOrderLines = $lines; directly resulting in a collection to array error.
The only way to do this was to call via in-built function called addItem() passing array objects into it.

Yii2 - Create Migration with LONGBLOB field

I want to create a table with a LONGBLOB field in it.
'image' => $this->binary(),
produces BLOB field in the table.
Is there any other way to produce LONGBLOB field except using raw SQL syntax for the specific field.
Below is my full code for creating the table.
$this->createTable('edition_images', [
'image_id' => $this->bigPrimaryKey()->unsigned(),
'embed_url' => $this->string()->notNull(),
'image_type' => $this->string(),
'image_md5' => $this->string(),
//'image' => $this->binary(),
'`image` longblob NULL',
'title_en' => $this->string(),
'title_bg' => $this->string(),
'title_ro' => $this->string(),
'order' => $this->bigInteger(20)->unsigned()->null(),
'edition_id' => $this->bigInteger(20)->unsigned()->notNull(),
'created_by' => $this->bigInteger(20)->unsigned()->notNull(),
'created_at' => $this->timestamp()->notNull()->defaultExpression('CURRENT_TIMESTAMP'),
'updated_by' => $this->bigInteger(20)->unsigned()->null(),
'updated_at' => $this->timestamp()->null()->defaultValue(null)->append('ON UPDATE CURRENT_TIMESTAMP'),
'deleted_by' => $this->bigInteger(20)->unsigned()->null(),
'deleted_at' => $this->timestamp()->null(),
'deleted' => $this->integer(1),
]);
You can pass the exact column type as text:
'image' => 'LONGBLOB'
You should be able to specify the length as a parameter in the binary method. Since the longblob is 4GB you have to specify this in bytes:
'image' => $this->binary(4294967295),
However, $length is being ignored. The code
$this->db->createCommand()->createTable("test_blob", [
"id" => $this->integer(),
"datum" => $this->binary(429496729),
"txt" => $this->string()
])->getSql();
returns the following SQL:
CREATE TABLE `test_blob` (
`id` int(11),
`datum` blob,
`txt` varchar(255)
);
I've added an issue on Github

insert array data to mysql codeigniter 3

How can I insert array data to mysql using code igniter ??
I tried example from CI documentation like this
$data = array(
'id_kls' => 'id_kls',
'fk__id_kls' => 'fk__id_kls',
'id_reg_pd' => 'id_reg_pd',
'nm_pd' => 'nm_pd',
'asal_data' => 'asal_data',
'nilai_angka' => 'nilai_angka',
'nilai_huruf' => 'nilai_huruf',
'nilai_indeks' => 'nilai_indeks',
);
$this->db->insert('master_nilai', $data);
// Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')
But not working ..
I have array data like this
Array
(
[error_code] => 0
[error_desc] =>
[result] => Array
(
[0] => Array
(
[id_kls] => f77294f7-2a5a-4876-860b-824d227d5b19
[fk__id_kls] => 02
[id_reg_pd] => 001be76b-4e58-4cea-96cf-fee2d8e0abdc
[nm_pd] => SUYATNO
[asal_data] => 9
[nilai_angka] =>
[nilai_huruf] => B
[nilai_indeks] => 3.00
)
Make sure you've enable config/autoload.php/$autoload['libraries'] = array('database');
and config/database.php/your hostname,username,dbname!

Get multiple array in Codeigniter and insert to database

I have multiple array to insert into database but i don't fix the field name because can select format table data and insert into database but can check field name with $id_template.
This my format table(example)
So i want to know how can i get data from multiple array to insert into database
This my code in controller
$column = $this->m_rate_template->get_column($id_template);
$colum_detail = implode(",", $column);
$column_cut = explode(",", $colum_detail); //example data get format is Array ( [0] => min [1] => max)
foreach ($column_cut as $key => $val){
$a = $this->input->post($column_cut[$key]);
foreach ($a as $key1 => $val1){
echo $val1;
$child_data = array(
'id' => $this->m_rate_template->generate_id_in_template($template_name),
'id_rate' => $id_rate,
$column_cut[$key] => $val1
);
$this->m_rate_template->insert_rate($child_data, $template_name);
}
}
My data it show like this
Array ( [id] => 4ae665037e [id_rate] => 7f881e02bb [min] => 1 )
Array ( [id] => bc3e60157f [id_rate] => 7f881e02bb [min] => 2 )
Array ( [id] => 082de3ad82 [id_rate] => 7f881e02bb [max] => 1 )
Array ( [id] => ee135ecd8a [id_rate] => 7f881e02bb [max] => 2 )
actually, data should be like this
Array ( [id] => 4ae665037e [id_rate] => 7f881e02bb [min] => 1 [max] => 2)
Array ( [id] => 082de3ad82 [id_rate] => 7f881e02bb [max] => 1 [max] => 2)
Update
$array = array(
[0] => array(
'min' => '2500',
'max' => '5000'
),
[1] => array(
'min' => '5001',
'max' => '7000'
)
)
You can use batch insert to insert multiple
$this->db->insert_batch();
first parameter is table name and second is array of arrays(records)
if you have want to insert multiple record in table then you can also use codeigniter inbuilt insert_batch function without make query in loop.
so i thing your execution will be fast.
you have want to array in below format.
$array = array(
[0] => array(
'column 1' => 'value 1',
'column 2' => 'value 1'
),
[1] => array(
'column 1' => 'value 2',
'column 2' => 'value 2'
)
)
$this->db->insert_batch('tbl_name',$array)
so please make your code and generate your array as above in loop and simply pass your array in insert_batch function.