Error report - ORA-00900: invalid SQL statement - ora-00900

I am new to oracle, I am trying to grant the roles to the users via a procedure. I am receiving the following error. can someone please help me with this?
declare stmnt2 varchar(10000);
p_user_name varchar2(20);
v_role_name varchar2(20);
begin
v_role_name := 'ROLE';
p_user_name := 'TOM';
stmnt2 := 'grant '||v_role_name||' to '
||v_user_name||'; '
||' grant connect to '
||v_user_name ;
execute immediate stmnt2;
end;
/
Error report -
ORA-00900: invalid SQL statement
ORA-06512: at line 10
00900. 00000 - "invalid SQL statement"
Thank you

You don't have spaces in your statement:
stmnt2 := 'grant '||v_role_name||' to '||p_user_name;
This must work better.

Related

how to resolve error while using grant admin option in execute immediate

I am trying to run the below script. My script works fine without ' WITH ADMIN OPTION' in EXECUTE IMMEDIATE. But when using ' WITH ADMIN OPTION' i get below error.
"Error report - ORA-00900: invalid SQL statement ORA-06512: at line 17
00900. 00000 - "invalid SQL statement"".
SET SERVEROUTPUT ON;
DECLARE
v_Model_UserName VARCHAR2(30) := UPPER('&Model_UserName');
v_Cloned_UserName VARCHAR2(30) := UPPER('&Cloned_UserName');
v_dba_role_privs VARCHAR2(3000); -- for dba_role_privs
--- selecting the roles from model user (from dba_role_privs table)
CURSOR c_role_privs (var01 Varchar2 )is
SELECT granted_role from dba_role_privs where grantee = var01;
BEGIN
--- granting the roles from model user to cloned user (from dba_role_privs table)
OPEN c_role_privs (v_Model_UserName);
LOOP
FETCH c_role_privs INTO v_dba_role_privs;
EXIT WHEN c_role_privs%NOTFOUND;
EXECUTE IMMEDIATE 'grant'||v_dba_role_privs||' to '||v_Cloned_UserName||' WITH ADMIN OPTION';
END LOOP;
CLOSE c_role_privs;
END;
/
Try to add a space after grant keyword:
EXECUTE IMMEDIATE 'grant '||v_dba_role_privs||' to '||v_Cloned_UserName||' WITH ADMIN OPTION';

How to use dynamic where clause in EXECUTE IMMEDIATE

I have a table with columns insert,select,where clause,dynamic where clause,group by clause.
Using procedure i need to execute insert into statement and also use dynamic where clause.
I tried the following one however it is giving me an error missing expression.
create or replace PROCEDURE dynamicWhereClause(Datee IN DATE,processId IN NUMBER)
IS
processName VARCHAR2(100);
tablePrefix CONFIG_DETAILS.SOURCE_TABLE%Type;
sourceTableType CONFIG_DETAILS.SOURCE_TABLE_TYPE%Type;
insertClause CONFIG_DETAILS.INSERT_CLAUSE%Type;
selectClause CONFIG_DETAILS.SELECT_CLAUSE%Type;
whereClause CONFIG_DETAILS.WHERE_CLAUSE%Type;
onUpdateClause CONFIG_DETAILS.ON_UPDATE_CLAUSE%Type;
groupByClause CONFIG_DETAILS.GROUP_BY_CLAUSE%Type;
orderByClause CONFIG_DETAILS.ORDER_BY_CLAUSE%Type;
isDynamicWhereClause CONFIG_DETAILS.IS_DYNAMIC_WHERE_CLAUSE%Type;
tableName VARCHAR2(50);
Process_Date DATE;
processQuery VARCHAR2(6000 BYTE);
CURSOR Process_Report IS
select NAME,SOURCE_TABLE,SOURCE_TABLE_TYPE,INSERT_CLAUSE,SELECT_CLAUSE,WHERE_CLAUSE,ON_UPDATE_CLAUSE,GROUP_BY_CLAUSE,ORDER_BY_CLAUSE,IS_DYNAMIC_WHERE_CLAUSE FROM
CONFIG_DETAILS where ID=processId;
BEGIN
OPEN Process_Report;
LOOP
FETCH Process_Report INTO processName,tablePrefix,sourceTableType,insertClause,selectClause,whereClause,onUpdateClause,groupByClause,orderByClause,isDynamicWhereClause;
EXIT when Process_Report%NOTFOUND;
tableName := getSourceTableName(tablePrefix,sourceTableType,processDate);
Process_Date := processDate;
processQuery := insertClause || selectClause ||' from ' || tableName ||' ' ||
nvl(whereClause,'') ||''||nvl(groupByClause,'') ||''||nvl(orderByClause,'') ||''||nvl(onUpdateClause,'');
dbms_output.put_line(processQuery);
IF isDynamicWhereClause = 'Y'
THEN
dbms_output.put_line(processQuery);
EXECUTE IMMEDIATE processQuery USING Process_Date;
ELSE
EXECUTE IMMEDIATE processQuery;
END IF;
END LOOP;
CLOSE Process_Report;
END;
While executing the proc it is giving me the below error.
Error report -
ORA-00936: missing expression
ORA-06512: at "Mytest.dynamicWhereClause", line 44
ORA-06512: at line 1
00936. 00000 - "missing expression"
Please assist me further
Thanks
Your questions is not 100% clear . you saying after DATEE is being empty, are you assigning a variable after date ? the below is example of how using execute immediate with a variable. Note how is the bind variable :i is showing in the print.
set serveroutput on size 1000
/
declare t number(4) :=10;
txt varchar2(100);
begin
txt :='INSERT INTO TAB (ID) values (:i)';
dbms_output.put_line(t || ' ' || txt);
execute immediate txt using T;
end;
/
PL/SQL procedure successfully completed
10 INSERT INTO TAB (ID) values (:i)

Grant statements not running in Oracle

I wrote this script to grant execute on functions on the source DB so that they are accessible from another DB using the DBlink. The scripts runs without issues, but I still cannot access the functions.
DECLARE
FNC_STRNG VARCHAR2(4000);
CURSOR CUR IS
SELECT * FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'FUNCTION';
BEGIN
FOR I IN CUR LOOP
BEGIN
FNC_STRNG := 'GRANT EXECUTE ON schema_name.' || I.OBJECT_NAME || ' TO
DB_LNK';
EXECUTE IMMEDIATE FNC_STRNG;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END LOOP;
END;
Once I run this script...
PL/SQL procedure successfully completed.
Then when I try to access the functions using this script:
SELECT schema_name.func_name#db_link(param1, param2) FROM schema_name.table_name#db_link;
And I get this error:
00904. 00000 - "%s: invalid identifier"

Incomplete/Malformed cursor

I have a PL/SQL script to perform some aggregation tasks. I am having compilation errors, logic is not top priority at this moment as that can be changed once the errors are resolved. The script is as follows :
SET SERVEROUTPUT ON;
ALTER SESSION SET NLS_DATE_FORMAT = 'dd-MON-yy';
CREATE OR REPLACE PROCEDURE updateFeaturePerformanceTable
(noOfDays IN NUMBER, runDate IN DATE, timeSpan IN VARCHAR2)
AS
CURSOR c_feature_performance IS
SELECT distinct mkt_id,dow,device_type,feature_name
FROM gfmdev.feature_performance
WHERE timespan = 'ONE_DAY'
AND feature_performance_day >= TO_DATE('17-AUG-15','dd-MON-yy');
rowsExtracted c_feature_performance%ROWTYPE;
extractDate DATE;
timespan_test varchar2(20);
BEGIN
OPEN c_feature_performance;
extractDate := runDate - noOfDays;
timespan_test := timeSpan;
LOOP
FETCH c_feature_performance INTO rowsExtracted;
EXIT WHEN c_feature_performance%NOTFOUND;
dbms_output.put_line(extractDate || ' ' || timespan_test);
INSERT INTO gfmdev.feature_performance
SELECT
rowsExtracted.mkt_id,
rowsExtracted.dow,
rowsExtracted.device_type,
rowsExtracted.feature_name,
SUM(OPS),
SUM(GV_COUNT),
runDate,
timespan_test
FROM gfmdev.feature_performance
WHERE feature_performance_day BETWEEN extractDate AND runDate
AND timespan = 'ONE_DAY'
AND mkt_id = rowsExtracted.mkt_id
AND dow = rowsExtracted.dow
AND device_type = rowsExtracted.device_type
AND feature_name = rowsExtracted.feature_name
group by mkt_id, dow, device_type, feature_name, timespan;
END LOOP;
CLOSE c_feature_performance;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Trying to insert too many rows in SELECT...INTO');
ROLLBACK;
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No rows returned in SELECT...INTO');
ROLLBACK;
WHEN STORAGE_ERROR THEN
dbms_output.put_line('Too much data to handle! Storage error');
ROLLBACK;
WHEN OTHERS THEN
dbms_output.put_line('Oops! Something went wrong');
ROLLBACK;
RAISE;
END updateFeaturePerformanceTable;
Show compilation errors:
SHOW ERRORS PROCEDURE updateFeaturePerformanceTable;
Run the procedure:
DECLARE
runDate DATE;
BEGIN
FOR j IN 0 .. 5 LOOP
SELECT (TO_DATE('17-AUG-15','dd-MON-yy') + j) INTO runDate FROM dual;
updateFeaturePerformanceTable(6,runDate, 'ONE_WEEK');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' WEEKLY RECORDS UPDATED ');
FOR j IN 0 .. 28 LOOP
SELECT (TO_DATE('17-AUG-15','dd-MON-yy') + j) INTO runDate FROM dual;
updateFeaturePerformanceTable(29,runDate, 'ONE_MONTH');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' MONTHLY RECORDS UPDATED ');
COMMIT;
END;
/
When I execute it I get the following error message :
Errors for PROCEDURE UPDATEFEATUREPERFORMANCETABLE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9 PLS-00341: declaration of cursor 'C_FEATURE_PERFORMANCE' is
incomplete or malformed
5/3 PL/SQL: SQL Statement ignored
6/15 PL/SQL: ORA-00942: table or view does not exist
8/16 PL/SQL: Item ignored
16/3 PL/SQL: SQL Statement ignored
16/36 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
21/3 PL/SQL: SQL Statement ignored
LINE/COL ERROR
-------- -----------------------------------------------------------------
36/22 PL/SQL: ORA-00904: "ROWSEXTRACTED"."FEATURE_NAME": invalid
identifier
36/22 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
updateFeaturePerformanceTable(6,runDate, 'ONE_WEEK');
*
Any help on where I am going wrong is highly appreciated?
PL/SQL is a framework for running SQL statements programmatically. So often we find that PL/SQL errors are caused by the SQL errors in our code.
That is the case here. You have several PL/SQL errors indicating that the Cursor declaration is invalid. And why is it invalid? This line holds the answer:
6/15 PL/SQL: ORA-00942: table or view does not exist
So the problem is, the owner of the procedure UPDATEFEATUREPERFORMANCETABLE (ugly name by the way) does not have rights on gfmdev.feature_performance.
To solve, the table owner GFMDEV needs to grant SELECT and INSERT directly to the account which owns this procedure.
SQL> conn gfmdev/password
SQL> grant select, insert on feature_performance to whoever;
Note that granting privileges through a view won't cut it. The Oracle security model only permits us to build objects - PL/SQL programs, views - with privileges granted directly to our user.

Execute immediate throws error when using record attribute in dynamic statement

I am executing the following snippet of code
set serveroutput on;
DECLARE
TYPE emp_rec_type IS record (emp_id NUMBER,salary NUMBER);
emp_rec emp_rec_type;
l_out number;
l_statement varchar2(1000);
BEGIN
emp_rec.emp_id := 1;
emp_rec.salary := 1000;
SELECT emp_rec.salary INTO l_out FROM dual WHERE 1=1;
dbms_output.put_line(l_out);
l_statement := 'select emp_rec.salary from dual where 1=1';
execute immediate l_statement into l_out;
dbms_output.put_line(l_out);
END;
I am getting the below output
Error report:
ORA-00904: "EMP_REC"."SALARY": invalid identifier
ORA-06512: at line 23
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
1000
I am expecting the output to be
1000
1000
Why is it that the dynamic statement execution insists on emp_rec.salary being an invalid identifer while the Select into statement works fine?
Is there something else I need to do to make it work?
The content of the EXECUTE IMMEDIATE statement is running in a completely different scope to the rest of your PL/SQL code - you can't reference PL/SQL variables directly.
If you want to use the contents of emp_rec.salary in the dynamic statement, you should bind in the value like so:
l_statement := 'SELECT :1 FROM dual WHERE 1=1';
EXECUTE IMMEDIATE l_statement INTO l_out USING emp_rec.salary;