ORDS 18.4 Why am I getting an empty :body_text (CLOB)? - rest

Tell me, please, why does the empty value come?
To send a request, I use SoapUI 5.5.
But :body is not null.
Do I need to do something in the settings of ORDS?
DECLARE
--b_body BLOB := :body;
c_body CLOB := :body_text;
BEGIN
if :body_text is null then
htp.print('EMPTY');
end if;
END;

As it says in documentation https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/18.3/aelig/implicit-parameters.html#GUID-76A23568-EA67-4375-A4AA-880E1D160D27, for each implicit parameter :body and :body_text "if it is dereferenced more than once, then the second and subsequent dereferences will appear to be empty."
So, change your code like this:
DECLARE
--b_body BLOB := :body;
c_body CLOB := :body_text;
BEGIN
if c_body is null then
htp.print('EMPTY');
end if;
END;

If I remember correct it's not a good idea to use both binds in 1 code block...
If ORDS checks that you're using :body, :body_text is not populated (I think because of the overall performance of converting a blob to clob).
So just use :body_text and you should be fine!

This symptom may result from creating RESTful Services via older versions of the APEX SQL Workshop interface. APEX 5.1 certainly exhibits this behaviour, possibly others. If you are unable to upgrade APEX, use SQL Developer to create your ORDS modules.

Related

Getting error in Postgres trigger creation

I'm trying to create this trigger in my PostgresSql environment:
CREATE TRIGGER MYTRIGGER
BEFORE INSERT
ON MYTABLE
FOR EACH ROW
BEGIN
IF( LENGTH( :NEW.VAL ) > 10 )
THEN
RAISE_APPLICATION_ERROR( -20003,
'Cannot exceed 10 chars' );
END IF;
IF :NEW.FQN_ID IS NULL THEN
:NEW.FQN_ID :=
CASE :NEW.SUBTYPECODE
WHEN NULL THEN 'A:'
WHEN 0 THEN 'B:'
WHEN 1 THEN 'C:'
WHEN 2 THEN 'D:'
ELSE 'Z:' || :NEW.SUBTYPECODE || '::'
--END || :NEW.OBJECTID;
END || STRUCTURE_FQNID_SEQ.NEXTVAL;
END IF;
END;
But I get this error:
ERROR: syntax error at or near "BEGIN"
LINE 5: BEGIN
^
SQL state: 42601
Character: 79
I think I'm missing something but I can't get it.
Any suggestion would be greatly appreciated.
Thank you.
Here are my notes about triggers in several DBMSs: https://github.com/iwis/SQL-notes. I marked the differences between the DBMSs in orange. I think that the notes are quite complete, so you don't have to read about triggers in Postgres documentation.
I see the following changes that need to done in your example:
Change Oracle :NEW to Postgres NEW.
Instead of a BEGIN ... END block, write EXECUTE FUNCTION my_trigger_function();, where my_trigger_function is a function that needs to be created like in the example given by a_horse_with_no_name.
This function should return NEW in your case - the reason is described here.
If a more complicated code is fired by a trigger, then you also need to understand the differences between PL/SQL and PL/pgSQL languages. These languages ​​are quite similar, though there are some differences. Your code is simple so the differences are small. It's probably enough to:
Write Postgres RETURNS in the function definition instead of Oracle RETURN.
Write $$ before BEGIN, and $$ LANGUAGE plpgsql; after END.
Write Postgres RAISE 'Cannot exceed 10 chars'; instead of Oracle RAISE_APPLICATION_ERROR(-20003, 'Cannot exceed 10 chars');.
I don't know if sequences work in the same way in PostgreSQL - I haven't read about them yet.
Let me know if my notes are understandable - I'm not sure about it because they are super compact so you need to decipher the markings used by me.

How to get Postgresql procedure warning messages?

While running a stored procedure, the procedure can raise warning messages.
Is there any way to get these messages using Postgresql driver(https://github.com/lib/pq) in Golang ?
For lib/pq driver, the answer is "still no".
See open issue and sources for details.
Meanwhile, another driver, https://github.com/jackc/pgx has support for messages in current (v4) version, see https://godoc.org/github.com/jackc/pgconn#Notice and earlier (see https://github.com/jackc/pgx/blob/v3/conn.go#L54)
Update: According to PR #932 which has been merged at Jan-2020, lib/pq supports NoticeHandler now. See example.
The answer appears to be no.
In my tests the Postgres server did not appear to send the warning with the results. Even if it did, returning an error along with the sql.Result would be confusing at best and would require lib/pq modifications. Raising an error in the function did return an error, but (obviously) no result.
If this is a critical requirement (and your function can support it) you might consider using a notification channel. Bear in mind that this would tie your code to Postgres.
--
Here is the function I used:
CREATE OR REPLACE function fugo()
RETURNS bool as $$
BEGIN
RAISE WARNING 'My function notice.' USING errcode = '01000';
return TRUE;
END;$$
language 'plpgsql';

Can't call Postgresql function which should return text value

I have a little problem when calling a Postgresql function in Delphi with FireDAC.
The Postgresql function has the following definition:
CREATE OR REPLACE FUNCTION public."pgpDecryptMe" (
todecode text
)
RETURNS text AS
$body$
DECLARE
PGPPrivate TEXT;
BEGIN
...
So it expects a "text" value and returns a "text" value.
I can call it with a long text parameter (over 900 character) and it returns the correct value in any sql admin tool without any problems.
select "pgpDecryptMe"('c1c04c030...a378624e6a659a20765') as Decrypt
But calling it in Delphi with the following code:
PGQuery.SQL.Text := 'select "pgpDecryptMe"(:test) as testvalue';
PGQuery.ParamByName('test').AsString := 'c1c04c030...a378624e6a659a20765';
PGQuery.Open();
Gives me the following error message:
[FireDAC][DatS]-2. Object [id] is not found
I googled and searched here but can't find any solution for the problem.
It is probably something very small I can't see :-(
I am working with Delphi XE7 and PostgreSQL 9.3
Ok, now I got it working.
It looks like it needed an additional index field name which doesn't really make sense because it just returned one value...
So it worked when I changed my code to the following:
PGQuery.SQL.Text := 'select "pgpDecryptMe"(:test) as testvalue';
PGQuery.ParamByName('test').AsString := 'c1c04c030...a378624e6a659a20765';
PGQuery.IndexFieldNames := 'testvalue';
PGQuery.Open();

I can create a stored procure with invalid user defined function names in it

I just noticed that I could alter my stored procedure code with a misspelled user defined function in it.
I noticed that at 1st time I execute the SP.
Is there any way to get a compile error when an SP include an invalid user-defined function name in it?
At compile time? No.
You can, however, use some of SQL's dependency objects (if using MS SQL) to find problems just after deployment, or as part of your beta testing. Aaron Bertran has a pretty nice article rounding up the options, depending upon the version of SQL Server.
Here is an example using SQL Server 2008 sys object called sql_expression_dependencies
CREATE FUNCTION dbo.scalarTest
(
#input1 INT,
#input2 INT
)
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE #ResultVar int
-- Add the T-SQL statements to compute the return value here
SELECT #ResultVar = #input1 * #input2
-- Return the result of the function
RETURN #ResultVar
END
GO
--Fn Works!
SELECT dbo.ScalarTest(2,2)
GO
CREATE PROCEDURE dbo.procTest
AS
BEGIN
SELECT TOP 1 dbo.scalarTest(3, 3) as procResult
FROM sys.objects
END
GO
--Sproc Works!
EXEC dbo.procTest
GO
--Remove a dependency needed by our sproc
DROP FUNCTION dbo.scalarTest
GO
--Does anything have a broken dependency? YES
SELECT OBJECT_NAME(referencing_id) AS referencing_entity_name,
referenced_entity_name, *
FROM sys.sql_expression_dependencies
WHERE referenced_id IS NULL --dependency is missing
GO
--Does it work? No
EXEC dbo.procTest
GO

Trigger and missing option

I'm developing a trigger that has to check the correctness of a date. I'm have big time trouble creating one, becase no matter how I try to simplify my code, Oracle returns me the same error: ORA-00922: missing or invalid option. I have checked the code over and over again and I really can't figure out where my issue is!
The following is an over-simplified version of the trigger, which gets the same error too.
CREATE OR REPLACE checkDateValidity
BEFORE INSERT
ON Event
FOR EACH ROW
BEGIN
IF :new.month>12
THEN
RAISE_APPLICATION_ERROR(-20101, 'Error: wrong month');
END IF;
END;
I really hope you can help me because at this point I really have no idea of what I am doing wrong.
You are missing the TRIGGER keyword:
CREATE OR REPLACE TRIGGER checkDateValidity
.... ^^^^^^^