I try to execute this but it gives an error at the default tablespace. I want to give a default tablespace to the users I create but how?
BEGIN
FOR USERNAME IN (SELECT studentname from students)
LOOP
EXECUTE IMMEDIATE 'CREATE USER ' || USERNAME.studentname || ' IDENTIFIED BY ' || USERNAME.studentname;
EXECUTE IMMEDIATE 'DEFAULT TABLESPACE "USERS"';
EXECUTE IMMEDIATE 'TEMPORARY TABLESPACE "TEMP"';
EXECUTE IMMEDIATE 'GRANT STUDENT TO ' || USERNAME.studentname ;
END LOOP;
END;
Error report - ORA-00900: invalid SQL statement ORA-06512: at line 5 00900. 00000 - "invalid SQL
You need to combine the first three statements into one and add in appropriate spaces. You don't need the double-quotes around the tablespace names since you're using case-insensitive identifiers.
BEGIN
FOR USERNAME IN (SELECT studentname from students)
LOOP
EXECUTE IMMEDIATE 'CREATE USER ' || USERNAME.studentname || ' IDENTIFIED BY ' || USERNAME.studentname ||
' DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP';
EXECUTE IMMEDIATE 'GRANT UNLIMITED TABLESPACE TO ' || USERNAME.studentname;
EXECUTE IMMEDIATE 'GRANT STUDENT TO ' || USERNAME.studentname ;
END LOOP;
END;
Personally, I'd always generate a string with the SQL statement and pass that string to EXECUTE IMMEDIATE. That makes it easy to do things like log the SQL statements that are executed or to log which statement failed. That's going to make debugging far easier.
Related
In the procedure, in the ALTER command, I need to dynamically substitute the name of the trigger that needs to be activated.
declare
v_trg_name varchar2(25) := 'article_comment_audit';
begin
execute immediate 'ALTER TRIGGER' || v_trg_name || 'ENABLE';
end;
I try to run this code, but it returns an error ORA-00940 invalid ALTER command
Please tell me what is the problem?
You'll get 'ALTER TRIGGERarticle_comment_auditENABLE'.
Insert Blanks:
'ALTER TRIGGER ' || v_trg_name || ' ENABLE';
in order to get 'ALTER TRIGGER article_comment_audit ENABLE'.
I am trying to write a script that will end sessions. I get the SQL command not properly ended when trying to EXECUTE IMMEDIATE and I can't figure out what I am doing wrong and why I am getting the error message. I have removed the ; form the line cur_show_connection and that didn't work as well.
|| ''' IMMEDIATE' sqlstatement
Here is my full code
declare
cursor cur_show_connections is
SELECT 'ALTER SYSTEM DISCONNECT SESSION '''
|| SID
|| ','
|| SERIAL#
|| ''' IMMEDIATE;' sqlstatement
FROM v$session
WHERE machine = 'XXXXX';
sqlstr varchar2(3200) :='';
begin
for rec_show_connections in cur_show_connections loop
sqlstr := sqlstr || rec_show_connections.sqlstatement || chr(13) || chr(10);
--Tried here and this didnt work either
--EXECUTE IMMEDIATE sqlstr;
end loop;
dbms_output.put_line(sqlstr);
EXECUTE IMMEDIATE sqlstr;
--This seems to work hardcoding the values
--EXECUTE IMMEDIATE q'[ALTER SYSTEM DISCONNECT SESSION '425,7516' IMMEDIATE]';
end;
Any help would be appreciated.
Don't end your ALTER SYSTEM command with a semi-colon. The EXECUTE IMMEDIATE command will take care of that.
cursor cur_show_connections is
SELECT 'ALTER SYSTEM DISCONNECT SESSION '''
|| SID
|| ','
|| SERIAL#
|| ''' IMMEDIATE' sqlstatement
FROM v$session
WHERE machine = 'XXXXX';
You're also concatenating your commands into a single EXECUTE IMMEDIATE statement. That won't work the way you're doing it: EXECUTE IMMEDIATE can only run one command or PL/SQL block at a time.
for rec_show_connections in cur_show_connections loop
dbms_output.put_line(rec_show_connections.sqlstatement);
EXECUTE IMMEDIATE rec_show_connections.sqlstatement;
end loop;
OR
sqlstr = 'BEGIN ';
for rec_show_connections in cur_show_connections loop
sqlstr := sqlstr || dbms_output.put_line(rec_show_connections.sqlstatement) || '; ';
end loop;
sqlstr := sqlstr || ' END;'
EXECUTE IMMEDIATE sqlstr;
Depending on how many sessions you might need to disconnect, the first option is less likely to have issues with character string size limitations. PL/SQL has a 32K limitation that could affect how big a single PL/SQL concatenated block could get, potentially throwing an error if you tried to kill too many sessions at once.
I just want to add column using execute immediate but I am getting an error. Please let me know the this PL/SQL block is correct or not?
create or replace procedure add_column (xyz in varchar2, abc in varchar2) is
begin
EXECUTE IMMEDIATE 'alter table ' || 'xyz add abc varchar2(20)';
dbms_output.put_line('New column added');
end;
exec add_column ('students', 'time');
error: Error starting at line : 8 in command -
BEGIN add_column ('students', 'time'); END;
ORA-00942: table or view does not exist
ORA-06512: at "HR.ADD_COLUMN", line 4
ORA-06512: at line 1
You need to use string concatanation as:
EXECUTE IMMEDIATE 'alter table ' || xyz || ' add ' || abc || ' varchar2(20)';
Also, DBMS_ASSERT can be used to check for the valid names of the table and column as follows.
EXECUTE IMMEDIATE 'alter table ' || sys.DBMS_ASSERT.SQL_OBJECT_NAME(xyz)
|| ' add ' || sys.DBMS_ASSERT.SQL_OBJECT_NAME(abc) || ' varchar2(20)';
Here, xyz and abc will be replaced with the input parameter names.
I am a beginner when it comes to PL/SQL coding. I am trying to do some simple administrative work using PL/SQL. Can someone point out what I am doing wrong?
Here is my code:
prompt Enter a value for the Schema that you just refreshed:
define owner=&1
BEGIN
FOR x_rec IN (
SELECT table_name FROM dba_tables WHERE owner='&&owner'
)
LOOP
EXECUTE IMMEDIATE ''GRANT SELECT ON ' ||&&owner|| '.''||x_rec.table_name||'' to ' ||&&owner|| '_RO_ROLE'';
END LOOP;
END;
You have too many quotes, for one thing. SQL*Plus uses a '.' to optionally terminate a substitution variable. If you want an actual dot as well, just use two.
Try this:
accept owner char prompt "Enter the name of the schema that you have just refreshed: "
begin
for r in (
select table_name from dba_tables where owner = upper('&&owner')
)
loop
dbms_output.put_line('grant select on &&owner..' || r.table_name || ' to &&owner._ro_role');
execute immediate 'grant select on &&owner..' || r.table_name || ' to &&owner._ro_role';
end loop;
end;
/
Getting an ORA-04020: deadlock detected while trying to lock object and I believe the source of the error could be these statements:
v_sql := 'DELETE FROM ' || in_table_name || ' SUBPARTITION (' || v_subpart_name || ')';
EXECUTE IMMEDIATE v_sql;
v_sql := 'ALTER TABLE ' || in_table_name || ' TRUNCATE SUBPARTITION ' || v_subpart_name;
EXECUTE IMMEDIATE v_sql;
Any ideas on how to resolve this issue? Could it be the ALTER statement is throwing the error since the DELETE is right before it? Not sure, I thought the ALTER would execute only once the DELETE if finished. Or could it be the procedure doesn't wait for the ALTER to complete before exiting and re-executing?
if your already doing TRUNCATE SUBPARTITION then why you need to delete . TRUNCATE would be much efficient way to delete data from table.
other wise you have to do commit after delete , then only truncate is allowed.
Regards
Ramki