oracle pl sql function having errors - plsql

I want to create a function that returns the number of rows in a table called Rating with a where clause.Where am i going wrong before the declare statement and the end statement?
create or replace
FUNCTION get_movies(user IN NUMBER) RETURN NUMBER
IS
DECLARE cnt NUMBER;
BEGIN
SELECT count(*)
INTO cnt
FROM rating
where userid= user;
RETURN cnt;
END;
I will appreciate help.Thanks.

You should not have the DECLARE keyword. You only need that for an anonymous block (or a sub-block).
create or replace
FUNCTION get_movies(p_userid IN NUMBER) RETURN NUMBER
IS
cnt NUMBER;
BEGIN
...
user is a reserved word so I'd suggest not using that as your parameter name. In the where clause I'm not sure if it will use your parameter value, or the name of the user executing the function; which would error as that string value couldn't be implicitly converted to a number.

Related

Procedure created with compilation errors. payment_count(l_p_count); *

Create a procedure named 'payment_count' which accepts one output parameter p_count with number as its data type. This procedure should print the count of successful payments (response_msg as 'Successful') with alias name as 'successful_payment_count'.
Hints: Procedure name : payment_count
Output parameter : p_count
Table used : payment_authorization
Function used : count
create or replace procedure payment_count(p_count output number)
as
begin
select count(response_msg='Successful') into successful_payment_count from payment_authorization;
return successful_payment_count;
end;
/
schema payment_authorization
Is this a task in an exam?
Sounds so... anyway:
You have to change keyword output to OUT, change the COUNT(response_msg='Successful') to COUNT(*) and add response_msg='Successful' to the where clause of the query.
create or replace procedure payment_count(p_count out number)
as
begin
select count(response_msg) as successful_payment_count
into p_count
from payment_authorization
where response_msg = 'Successful';
end;
/

mariadb user defined aggregate function

I am using mariadb 10.3.9, and have created a user defined aggregate function (UDAF) and placed in a common_schema. This schema contains my utility functions to be used by other schema/databases on the same server.
The issue is that when calling the UDAF while using any other schema, it always return NULL!
The following is to demonstrate the issue:
CREATE SCHEMA IF NOT EXISTS common_schema;
DELIMITER $$
DROP FUNCTION IF EXISTS common_schema.add_ints $$
CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
BEGIN
RETURN int_1 + int_2;
END $$
DROP FUNCTION IF EXISTS common_schema.sum_ints $$
CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
BEGIN
DECLARE result INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
LOOP FETCH GROUP NEXT ROW;
SET result = common_schema.add_ints(result, int_val);
END LOOP;
END $$
DELIMITER ;
Now, calling it this way, returns the result as expected:
USE common_schema;
SELECT common_schema.sum_ints(seq)
FROM (SELECT 1 seq UNION ALL SELECT 2) t;
-- result: 3
Calling it using any other schema, it returns NULL:
USE other_schema;
SELECT common_schema.sum_ints(seq)
FROM (SELECT 1 seq UNION ALL SELECT 2) t;
-- result: null
Am I missing something here? Is there any configuration that is missing?
Appreciate your help.
Reported as a Bug https://jira.mariadb.org/browse/MDEV-18100.
As a workaround, create the UDAF in every schema.

PL/SQL Function_get total balance has errors

I was trying to create a function that given a customer name, get the total balance of that customer's accounts from the account table(A#, CNAME, BAL).
When compiling in command, I got errors:
line "SELECT SUM(bal) INTO total_a_bal FROM account" ignored
and line "WHERE account.cname = v_acname" SQL cmd not properly ended.
Please help correct the errors. Any help would be greatly appreciated!
My function is :
CREATE OR REPLACE FUNCTION totbal
(v_acname IN account.cname%type)
RETURN NUMBER
IS
total_a_bal NUMBER;
BEGIN
SELECT SUM(bal) INTO total_a_bal FROM account
group by account.cname
WHERE account.cname = v_acname;
RETURN total_a_bal;
END;
/
This may not be the only problem with your function, but the WHERE clause always precedes the GROUP BY clause in a SQL query. Hence, your function should look like this:
CREATE OR REPLACE FUNCTION totbal
(v_acname IN varchar2) -- a type should follow IN, e.g. varchar2
RETURN NUMBER
IS
total_a_bal NUMBER;
BEGIN
SELECT SUM(bal) INTO total_a_bal
FROM account
WHERE account.cname = v_acname; -- WHERE always precedes GROUP BY
GROUP BY account.cname
RETURN total_a_bal;
END;
Oracle not only works with the parameter definition "account.cname%type" that is preferred method. What it does is to bind the parameter definition to the column in the database. If the column definition is changed the procedure automatically gets the changed.
This concept of defining in terms of data base columns can (and perhaps should) be extended into the variables and return types of the procedure/function itself.
This function then becomes:
CREATE OR REPLACE FUNCTION totbal
(v_acname IN account.cname%type)
RETURN account.bal%type
IS
total_a_bal account.bal%type;
BEGIN
SELECT SUM(bal) INTO total_a_bal FROM account
group by account.cname
WHERE account.cname = v_acname;
RETURN total_a_bal;
END;

Convert stored proc to table to be able to use in select statement

I have to use existing stored procedure which returns REF CURSOR. I need to insert that resultset into a temporary table.
Spec of procedure is:
TYPE cur IS REF CURSOR;
PROCEDURE get(p_one NUMBER ,p_two OUT cur);
How can I insert the resultset of this procedure into a table.
I just re-read the title of your question. Do you actually need to be able to select from a procedure?
If so, this can be achieved by using pipelined functions.
The process for this is:
Create an object type to represent the record-type you require.
Create a nested table type of the object.
Create a pipelined function which returns the nest table.
You can then select from this function.
This example should get you on your way:
create or replace type to_test as object (
val1 varchar2(32),
val2 varchar2(32)
);
create or replace type tt_test as table of to_test;
create or replace function demo_pipe return tt_test pipelined
is
v_test to_test;
begin
for rec in (select * from user_tables) loop
v_test := to_test(rec.table_name, rec.tablespace_name);
pipe row (v_test);
end loop;
end;
/
select * from table(demo_pipe);

How to convert VARCHAR2 to BLOB inside Oracle 11g PL/SQL after ORA-06502

I have a function, that calculates hash value of big string! First of all I wrote a cursor T1_CUT, which can include variable count of SELECT statements, something like:
SELECT T1.COL1||T1.COL2||...||T1.COLn FROM T1 WHERE id=documentid
SELECT T2.COL1||T2.COL2||...||T2.COLn FROM T2 WHERE id=documentid
...
SELECT Tn.COL1||Tn.COL2||...||Tn.COLn FROM Tn WHERE id=documentid
Each SELECT can contain one or more rows. So, I concat ALL values in rows in each SELECT and ALL SELECTs values in one big string V_RESULT with type VARCHAR2(32767). After that I get hash value (S_HASH_RESULT) of this big string using MD5. It works fine about 8 monthes, but few days ago I've got ORA-06502 (no surprise). It means, that my final big string have more than 32K symbols (we use 1byte character set - CL8MSWIN1251).
Friends, how can I rewrite my function for using BLOB data type to V_RESULT variable, not VARCHAR2(32767).
Below, text of my function:
FUNCTION CALC_HASH (P_PARTAB_ID IN NUMBER, P_DOC_ID IN NUMBER)
RETURN VARCHAR2
IS
S_HASH_RESULT VARCHAR2(1000);
V_RESULT VARCHAR2(32767);
CURSOR T1_CUT IS
...
/*BIG COMPLAIN SELECT*/
...
T1 T1_CUT%ROWTYPE;
TYPE VALUES_T IS TABLE OF VARCHAR2(32767);
L_VALUES VALUES_T;
BEGIN
OPEN T1_CUT;
FETCH T1_CUT INTO T1;
WHILE T1_CUT%FOUND
LOOP
EXECUTE IMMEDIATE
T1.TEXT
BULK COLLECT INTO L_VALUES;
FOR INDX IN 1 .. L_VALUES.COUNT
LOOP
V_RESULT := V_RESULT || '' ||TO_CHAR(L_VALUES (INDX));
END LOOP;
FETCH T1_CUT INTO T1;
END LOOP;
CLOSE T1_CUT;
S_HASH_RESULT := DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=>V_RESULT);
RETURN S_HASH_RESULT;
END CALC_HASH;
Thanks in advance!
there is a function called utl_raw.cast_to_raw(vc) which transforms a varchar2 into a BLOB value.
However, I recommend to use CLOB to store string values. BLOB has no character semantics at all, i.e., NLS_LANG settings are ignored.
EDIT:
if you want to transform VARCHAR2 to CLOB, simply use TO_CLOB

Resources