Function with Table_name as input and returns a number in Oracle - sql

I have a function that takes table_name as input and returns a number.
The function gets compiled properly but for some reason when I try test the function it throws error - missing keyword.
CREATE OR replace FUNCTION TEST_FUNCTION (name_table IN VARCHAR2) RETURN NUMBER
IS
rday NUMBER;
BEGIN
execute immediate
'select day_i into rday
FROM ' || name_table || '
WHERE day_i = 1 and rownum = 1';
return rday;
END TEST_FUNCTION;
This is how I am testing it Select TEST_FUNCTION ('FDR_REP') from dual;

The syntax for execute immediate is different for an into clause
try
CREATE OR replace FUNCTION TEST_FUNCTION (name_table IN VARCHAR2) RETURN NUMBER
IS
rday NUMBER;
BEGIN
execute immediate 'select day_i
FROM ' || name_table || '
WHERE day_i = 1 and rownum = 1' into rday;
return rday;
END TEST_FUNCTION;

Related

Multiple functions calling a same function. I need to create a flag

Multiple functions calling a same function. I need to create a flag.
Suppose I have 4 functions(f1,f2,f3 and f4) in a PLSQL package.
F1 is being called by F2,F3 and F4. All I want a flag in order to track which function call the F1.
For example . If f2 called f1 then flag=2,flag=3 when f3 called f1 and so on and this should be accessible in such way that I can this flag inside function F1.
You don't need to pass any flag, as PL/SQL can tell you the call stack.
create or replace package demo
as
function f1 return number;
function f2 return number;
function f3 return number;
function f4 return number;
end demo;
create or replace package body demo
as
function f1 return number
is
this_unit varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
caller varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(2));
begin
dbms_output.put_line(this_unit || ' called from ' || caller);
return 1;
end f1;
function f2 return number
is
this_unit varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
caller varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(2));
begin
dbms_output.put_line(this_unit || ' called from ' || caller);
return f1 * 2;
end f2;
function f3 return number
is
this_unit varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
caller varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(2));
begin
dbms_output.put_line(this_unit || ' called from ' || caller);
return f1 + f2;
end f3;
function f4 return number
is
this_unit varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
caller varchar2(257) := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(2));
begin
dbms_output.put_line(this_unit || ' called from ' || caller);
return f2 * 2;
end f4;
end demo;
Test:
declare
n number;
begin
n := demo.f3;
end;
/
DEMO.F3 called from __anonymous_block
DEMO.F1 called from DEMO.F3
DEMO.F2 called from DEMO.F3
DEMO.F1 called from DEMO.F2
You can adjust the calls to util_call_stack to exclude the package name if you only want the function names.

Adding output to function PL/SQL

I am trying to get my function to include the date and current user, but I keep getting an error that my function is in an invalid state. If I comment out or remove the two dbms_output... lines it works just fine. Any ideas of how to return that output? Using Oracle SQL Developer
CREATE OR REPLACE FUNCTION f_concatenate_strings(x VARCHAR2, y VARCHAR2)
RETURN VARCHAR2
AS
str1 VARCHAR2(10) := x;
str2 VARCHAR2(10) := y;
BEGIN
RETURN str1 || str2;
dbms_output.put_line('The result is ' || result);
dbms_output.put_line('Date: ' || SYSDATE || ' user: ' ||
SYS_CONTEXT('USERENV','OS_USER'));
END;
/
SELECT f_concatenate_strings('Crypto','Currency') FROM DUAL;
You have to declare the result Variable first, also enable the dbms_output on your SQL Developer.
This should work.
CREATE OR REPLACE FUNCTION f_concatenate_strings(x VARCHAR2, y VARCHAR2)
RETURN VARCHAR2
AS
str1 VARCHAR2(10) := x;
STR2 VARCHAR2(10) := Y;
result VARCHAR2(250);
BEGIN
result := str1 || str2;
dbms_output.put_line('The result is ' || result);
dbms_output.put_line('Date: ' || SYSDATE || ' user: ' ||
SYS_CONTEXT('USERENV','OS_USER'));
RETURN result;
END;
/
SELECT F_CONCATENATE_STRINGS('Crypto','Currency') FROM DUAL;
your function has some issues.
result is not declared
return statement should be the last statement in the function. it return a result and terminates the execution of the function
you should convert to char the sysdate
you can try this one:
CREATE OR REPLACE FUNCTION f_concatenate_strings(x VARCHAR2, y VARCHAR2)
RETURN VARCHAR2
AS
--str1 VARCHAR2(10) := x;
--str2 VARCHAR2(10) := y;
result VARCHAR2(20);
BEGIN
result := x || y;
dbms_output.put_line('The result is ' || result);
dbms_output.put_line('Date: ' || to_char(SYSDATE,'dd.mm.yyyy') || ' user: ' ||
SYS_CONTEXT('USERENV','OS_USER'));
RETURN result; -- move to the end of the function
END;
/
SELECT f_concatenate_strings('Crypto','Currency') FROM DUAL;

Postgres Type of Parameter does not match

I am having an odd problem with Postgres (10.5). I have a function, generate_unique_name which takes in three text values. It works fine; however, calling this function seems to be an issue. When I call the function using:
SELECT generate_unique_name('basic', 'seeds', 'project=' || 2)
It works without issue. I can make the same call several times. Now, when I try the same call, but change the second parameter as below:
SELECT generate_unique_name('basic', 'queue', 'project=' || 2)
Then it seems to fail with the error:
ERROR: type of parameter 9 (text) does not match that when preparing
the plan (character varying) CONTEXT: PL/pgSQL function
generate_unique_name(text,text,text) line 12 at assignment SQL state:
42804
I have tried changing the query to:
SELECT generate_unique_name('basic'::text, 'queue'::text, ('project=' || 2)::text)
But this also fails. If I then kill the connection to postgres DB, and create a new one, and instead start with the second query, it now works, but the first stops functioning.
It seems like postgres decides to stop treating the parameters as text part way through, for no apparent reason. Am I missing something?
EDIT: Code for generate_unique_name
CREATE OR REPLACE FUNCTION public.generate_unique_name(
proposed_name text,
table_name text,
condition text)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
unique_name text;
name_counter integer;
r record;
names_to_check text[];
BEGIN
unique_name = proposed_name;
name_counter = 0;
FOR r IN EXECUTE 'SELECT name FROM ' || table_name || ' WHERE ' || condition LOOP
names_to_check = array_append(names_to_check, r.name::text);
END LOOP;
WHILE unique_name = ANY(names_to_check) LOOP
name_counter = name_counter + 1;
unique_name = proposed_name || ' (' || name_counter || ')';
END LOOP;
RETURN unique_name;
END;
$BODY$;
My guess is there's a value in the name column of the queue table that causes an issue with
names_to_check = array_append(names_to_check, r.name::text)
As Joe mentioned, the issue was with the array_append, which I could not figure out a way to fix. Instead, the generate_unique_names functions was changed to just query the DB continuously.
CREATE OR REPLACE FUNCTION generate_unique_name (proposed_name text, table_name text, condition text) RETURNS text AS
$BODY$
DECLARE
unique_name text;
name_counter integer;
not_unique boolean;
BEGIN
unique_name = proposed_name;
name_counter = 0;
EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;
WHILE not_unique LOOP
name_counter = name_counter + 1;
unique_name = proposed_name || ' (' || name_counter || ')';
EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;
END LOOP;
RETURN unique_name;
END;
$BODY$ LANGUAGE plpgsql;

PostgreSQL : ERROR: function geta(integer, integer, unknown) does not exist

I am creating a dynamic query generation function which helped me out in my work. The CREATE FUNCTION script parsed successfully but i am not able execute it. While executing the function, it shows an error.
I have tried a lot.
Please look below for code.
CREATE OR REPLACE FUNCTION "public"."GetA" (headcategoriesid int4,cdfid int4,
colName text)
RETURNS varchar AS
$BODY$
DECLARE
sql1 text := 'select string_agg(answer, '','') as HeadName from
' || $3 || 'where cdfid = ' || $2 || ' and headcategoriesid = '|| $1;
BEGIN
-- RETURN QUERY
Execute sql1;
-- 'select string_agg(answer, '','') as HeadName from ' || $3 ||
'where cdfid = ' || $2 || ' and headcategoriesid = '|| $1;
-- RETURN QUERY EXECUTE format(
-- 'select string_agg(answer, '','') as HeadName from %I WHERE
cdfid = %L and headcategoriesid = %L', colName, 7, 96
-- );
END
$BODY$
LANGUAGE plpgsql;
Am using Postgresql 9.2.4
Call function as below:
SELECT "GetA"(7,96,'educationdetails'::text);
when you call the function GetA without ""(quotes) than it will be considerd as geta (small letter). but in your code you are using "" so it is created as GetA.

Finding specific data in Oracle Tables

I needed to find a value for a column in my oracle database but i don't know which
table or column it's stored in
How can I search for a specific or like %% data as I do in
select * from SYS.dba_source
is there a table like that
Column Name ID Data Type Null? Comments
OWNER 1 VARCHAR2 (30 Byte) Y
NAME 2 VARCHAR2 (30 Byte) Y Name of the object
TYPE 3 VARCHAR2 (12 Byte) Y
Type of the object:
"TYPE", "TYPE BODY", "PROCEDURE", "FUNCTION",
"PACKAGE", "PACKAGE BODY" or "JAVA SOURCE"
LINE 4 NUMBER Y Line number of this line of source
TEXT 5 VARCHAR2 (4000 Byte) Y Source text
LINK: pl/sq to find any data in a schema
Imagine, there are a few tables in your schema and you want to find a specific value in all columns within these tables. Ideally, there would be an sql function like
select * from * where any(column) = 'value';
Unfortunately, there is no such function.
However, a PL/SQL function can be written that does that. The following function iterates over all character columns in all tables of the current schema and tries to find val in them.
create or replace function find_in_schema(val varchar2)
return varchar2 is
v_old_table user_tab_columns.table_name%type;
v_where Varchar2(4000);
v_first_col boolean := true;
type rc is ref cursor;
c rc;
v_rowid varchar2(20);
begin
for r in (
select
t.*
from
user_tab_cols t, user_all_tables a
where t.table_name = a.table_name
and t.data_type like '%CHAR%'
order by t.table_name) loop
if v_old_table is null then
v_old_table := r.table_name;
end if;
if v_old_table <> r.table_name then
v_first_col := true;
-- dbms_output.put_line('searching ' || v_old_table);
open c for 'select rowid from "' || v_old_table || '" ' || v_where;
fetch c into v_rowid;
loop
exit when c%notfound;
dbms_output.put_line(' rowid: ' || v_rowid || ' in ' || v_old_table);
fetch c into v_rowid;
end loop;
v_old_table := r.table_name;
end if;
if v_first_col then
v_where := ' where ' || r.column_name || ' like ''%' || val || '%''';
v_first_col := false;
else
v_where := v_where || ' or ' || r.column_name || ' like ''%' || val || '%''';
end if;
end loop;
return 'Success';
end;