Oracle => PostgreSQL: Array of %ROWTYPE? - arrays

Is there any way in PostgreSQL to declare local type "TABLE OF ..%ROWTYPE INDEX BY BINARY_INTEGER" inside a function like in Oracle?
CREATE OR REPLACE FUNCTION FNC
RETURN NUMBER
AS
TYPE TYPE_TB IS TABLE OF ADM_APPLICATIONS%ROWTYPE
INDEX BY BINARY_INTEGER;
TB_VAR TYPE_TB;
BEGIN
return 1;
END;

For every table there is also a corresponding type (with the same name) available.
So you can do the following:
CREATE OR REPLACE FUNCTION fnc()
RETURNs integer
AS
$$
declare
tb_var adm_applications[];
begin
return 1;
end;
$$
language plpgsql;

Related

Creating ISNUMBER function in Snowflake

ISNUMBER is not a in-built function in Snowflake.
I want to create ISNUMBER function in Snowflake as an user-defined function.
Below is the user-defined function of ISNUMBER in oracle:
CREATE OR REPLACE FUNCTION is_number (p_string IN VARCHAR2)
RETURN INT
IS
v_num NUMBER;
BEGIN
v_numĀ := TO_NUMBER(p_string);
RETURN 1;
EXCEPTION
WHEN VALUE_ERROR THEN
RETURN 0;
END is_number;
I have tried in this way in Snowflake to create the function:
create or replace function ISNUMBER(p_string in varchar2)
returns int
language sql
as
$$
declare
v_num number;
begin
v_num := TO_NUMBER(p_string);
return 1;
exception
when statement_error then
return 0;
end;
$$;
Help me by correcting the above code.
Snowflake Scripting does not support UDFs for now.
https://docs.snowflake.com/en/developer-guide/snowflake-scripting/index.html
I think it's easier to do it like this:
create or replace function ISNUMBER(p_string varchar2) returns int as
'iff( try_to_number(p_string) is null, 0, 1 )';
select isnumber( '232323'); -- returns 1
select isnumber( 'A343'); -- returns 0

How to loop from an array received as a parameter in plpgsql function?

I'm kinda new into pgplsql and so far I have to create a function that loops an array that is received as a function.
The main idea of the function is to insert new records into a table that maps each id contained in the array received with a new formatted id, the format depends on the second parameter received and return the table "idsTable".
The problem is that when I try to create the function it sends me an error:
ERROR: loop variable of FOREACH must be a known variable or list of variables
LINE 38: FOREACH objectid IN ARRAY idsList LOOP
I'm not sure if I have to declare the objectid variable cause in the examples that I have seen they didn't.
So far I have this:
CREATE OR REPLACE FUNCTION createId(idsList varchar[], objectType varchar)
RETURNS TABLE(original_id varchar, new_id char) as
$$
BEGIN
IF LOWER(objectType) = 'global' THEN
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'GID'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
ELSE
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'ORG'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
END IF;
END;
$$ LANGUAGE plpgsql;
Any ideas of what could be wrong?
edit: I haven't add the part where the idsTable is returned.
Unrelated, but: you don't really need a loop for that. And you can simplify the function by only writing the INSERT once. You also forgot to return something from your function. As it is declared as returns table that is required:
CREATE OR REPLACE FUNCTION createid(idslist varchar[], objecttype varchar)
RETURNS TABLE(original_id varchar, new_id varchar) as
$$
declare
l_prefix text;
BEGIN
IF LOWER(objectType) = 'global' THEN
l_prefix := 'GID';
ELSE
l_prefix := 'ORG';
END IF;
RETURN QUERY --<< return the result of the insert
INSERT INTO idstable(original_id, new_id)
select t.x, l_prefix||nextval('mapSquema.globalid')::TEXT
from unnest(idslist) as t(x)
returning *
END;
$$ LANGUAGE plpgsql;

initialize object type constructor oracle

i'm developing a database in oracle.
I've created a supertype, answer, and a subtype, closed_answer. I've added a field "type" to distinguish them, but i want that this field is initialized in a constructor, in order to don't insert this field when i'm inserting a tuple in that table. i've tried, but when i insert a tuple in the table closed_answer, i have to specify the type, but i shouldn't. Where am i wrong?
create type answertyp as object(
id integer,
text varchar2(50),
type varchar2(25),
constructor function answertyp(self in out nocopy answertyp, text varchar2) return self as result) not final;
create type body answertyp is
constructor function answertyp(self in out nocopy answertyp, text varchar2) return self as result is
begin
self.text := text;
self.type:= 'answer';
return;
end;
end;
/
create type closed_answertyp under closed_answer(
constructor function closed_answertyp(self in out nocopy closed_answertyp, text varchar2) return self as result
) final;
create type body closed_answertyp is
constructor function closed_answertyp (self in out nocopy closed_answertyp, text varchar2) return self as result is
begin
self.text := text;
self.type := 'closed_answer';
return;
end;
end;
Now, if i try this query, it says that the number of argument is wrong. Any help? thanks
insert into answer select closed_answertyp(1, 'ten') from dual;
The arguments in the SQL statement don't match the the arguments in the constructors.
Either add id to the constructor:
constructor function closed_answertyp (self in out nocopy closed_answertyp, id integer, text varchar2) return self as result is
Or remove the id from the SQL statement:
insert into answer select closed_answertyp('ten') from dual;

Find different in two jsonb , PostgreSQL trigger function

user
CREATE TABLE IF NOT EXISTS "user"(
"id" SERIAL NOT NULL,
"create_date" timestamp without time zone NOT NULL,
"last_modified_date" timestamp without time zone,
"last_modified_by_user_id" integer,
"status" integer NOT NULL,
PRIMARY KEY ("id")
);
user_track
CREATE TABLE IF NOT EXISTS "user_track"(
"date" timestamp without time zone,
"by_user_id" integer,
"origin_value" jsonb,
"new_value" jsonb
);
function
CREATE OR REPLACE FUNCTION user_track_insert()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO user_track(date, new_value)
VALUES(NEW.create_date, row_to_json(NEW)::jsonb);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION user_track_delete()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO user_track(date, by_user_id, origin_value)
VALUES(create_date, user_id, row_to_json(OLD)::jsonb);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION user_track_update()
RETURNS TRIGGER AS $$
DECLARE
js_new jsonb := row_to_json(NEW)::jsonb;
js_old jsonb := row_to_json(OLD)::jsonb;
BEGIN
INSERT INTO user_track(date, by_user_id, origin_value, new_value)
VALUES(NEW.create_date, OLD.id, js_old - js_new, js_new - js_old);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
trigger
CREATE TRIGGER user_track_insert_trigger AFTER INSERT ON "user"
FOR EACH ROW EXECUTE PROCEDURE user_track_insert();
CREATE TRIGGER user_track_delete_trigger AFTER DELETE ON "user"
FOR EACH ROW EXECUTE PROCEDURE user_track_delete();
CREATE TRIGGER user_track_update_trigger AFTER UPDATE ON "user"
FOR EACH ROW EXECUTE PROCEDURE user_track_update();
When I do update in pgadmin got error:
ERROR: operator does not exist: jsonb - jsonb
LINE 2: VALUES(NEW.create_date, OLD.id, js_old - js_new, js_n...
^
ERROR: operator does not exist: jsonb - jsonb
SQL state: 42883
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Context: PL/pgSQL function user_track_update() line 6 at SQL statement
I only want to save json data present changed column/value not whole row all column.
I can't find jsonb - jsonb in document, so seems there is no such operator ...
How to pass parameter into user_track_delete function, for example if I want to some other use.id who execute this action ?
PostgreSQL 9.5.2

How to select value of variable in ORACLE

Below is the SQL Server's syntax to select variable as a record
DECLARE #number AS INTEGER;
SET #number = 10;
SELECT #number;
How can I do this in ORACLE?
Thanks in advance.
Regards,
Sagar Nannaware
Edited based on comment:
One way you can access the variable value assigned by a procedure is through a function again.
Example:
CREATE OR REPLACE PROCEDURE your_procedure(out_number OUT number)
IS
BEGIN
out_number:=1;
END;
function to retrieve the procedure's output
CREATE OR REPLACE FUNCTION your_function
RETURN number
AS
o_param number;
BEGIN
o_param := NULL;
your_procedure(o_param);
RETURN o_param;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
return 0; --basically how you want to handle your errors.
END your_function;
Now you can select the output of the procedure
select your_function from dual;
Useful link how to access an Oracle procedure's OUT parameter when calling it?
If you are trying to create a variable to access anywhere in your application in oracle.
You can do it by creating function and calling it from dual.
SQL>create or replace function foo return number
as
x number;
begin
x:=1;
return 1;
end;
Function created.
SQL>select foo from dual;
FOO
----------
1
Please check following link for more details
[example link] (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1562813956388)

Resources