I'm getting this error in Oracle:
ORA-00933: SQL command not properly ended
for
DROP SEQUENCE IF EXISTS ownername.seq_name;
Why am I seeing this?
the IF EXISTS clause doesn't exist in the DROP SEQUENCE command in Oracle.
You could use a PLSQL block to ignore the error:
SQL> DECLARE
2 sequence_doesnt_exist EXCEPTION;
3 PRAGMA EXCEPTION_INIT(sequence_doesnt_exist, -2289);
4 BEGIN
5 EXECUTE IMMEDIATE 'DROP SEQUENCE seq_name';
6 EXCEPTION
7 WHEN sequence_doesnt_exist THEN NULL;
8 END;
9 /
PL/SQL procedure successfully completed
The problem is "if exists" does not work in Oracle. Use:
drop sequence ownername.seq_name;
As others mentioned, the IF EXISTS doesn't work on the DROP SEQUENCE command.
To test for the existence of a sequence, you need to check the appropriate view:
USER_SEQUENCES
SELECT *
FROM USER_SEQUENCES
WHERE sequence_name = ?
DBA_SEQUENCES
SELECT *
FROM DBA_SEQUENCES
WHERE sequence_name = ?
ALL_SEQUENCES
SELECT *
FROM ALL_SEQUENCES
WHERE sequence_name = ?
Example:
BEGIN
FOR i IN (SELECT sequence_name
FROM USER_SEQUENCES
WHERE sequence_name = ?)
LOOP
EXECUTE IMMEDIATE ('DROP SEQUENCE '|| i.sequence_name);
END LOOP;
END;
Try this:
DECLARE
iNum NUMBER DEFAULT 0;
BEGIN
SELECT COUNT(1)
INTO iNum
FROM ALL_SEQUENCES
WHERE SEQUENCE_OWNER='<OWNER_NAME>'
AND SEQUENCE_NAME = '<YOUR_SEQUENCE_NAME>';
IF iNum> 0 THEN
EXECUTE IMMEDIATE 'DROP SEQUENCE <OWNER_NAME>.<YOUR_SEQUENCE_NAME>';
END IF;
END;
Related
I want to get a result: table name, count amount for each table from AS_TABLE_LIST.
create procedure AtRowCount
as
declare
TableCount NUMBER(1);
TableName VARCHAR2(100);
BEGIN
SelectQuery1:= 'SELECT count(*) FROM ' || TableName || ' INTO ' || TableCount;
FOR TableName IN (select table_name from AS_TABLE_LIST)
LOOP
EXECUTE IMMEDIATE SelectQuery1;
END LOOP;
select TableName, TableCount into AT_ROW_COUNT from dual;
END AtRowCount;
I get two errors:
[Error] PLS-00306 (7: 19): PLS-00306: wrong number or types of
arguments in call to '||'
[Error] ORA-00904 (9: 8): PL/SQL: ORA-00904: "TABLENAME": invalid
identifier
I've been trying many times to fix this but still got same errors.
any advice?
I'm not exactly sure what you're trying todo, but it might be the following:
CREATE PROCEDURE AtRowCount AS
DECLARE
l_count NUMBER;
BEGIN
FOR c IN (SELECT table_name from AS_TABLE_LIST) LOOP
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||c.table_name INTO l_count;
INSERT INTO AT_ROW_COUNT(TableName, TableCount )
VALUES (c.table_name, l_count);
END LOOP;
END AtRowCount;
If you want you're procedure to return the list instead of inserting the result in a new table, you have to use a pipelined function instead (see https://oracle-base.com/articles/misc/pipelined-table-functions for an example on how to use it).
You can get all rows count against table name in oracle by:
select owner, table_name, nvl(num_rows,-1)
from all_tables
order by nvl(num_rows,-1) desc
https://livesql.oracle.com/apex/livesql/file/content_EPJLBHYMPOPAGL9PQAV7XH14Q.html
Hope this will work for you
CREATE PROCEDURE atrowcount
IS
selectquery1 VARCHAR2(2000);
tablecount NUMBER;
BEGIN
selectquery1:= 'SELECT count(1) FROM :TableName';
FOR i IN (select table_name from AS_TABLE_LIST)
LOOP
EXECUTE IMMEDIATE selectquery1 INTO tablecount USING i.table_name;
INSERT INTO table_list VALUES(i.table_name,TableCount);
END LOOP;
COMMIT;
END AtRowCount;
I'm trying to create a table if it doesn't exist already. I'm currently checking to see if it exists in DBA_TABLES first and if that query returns nothing then insert. Is there a way to just check in the same statement so I don't have to break it up into separate queries?
This is what I have currently.
BEGIN
SELECT COUNT(*)
INTO lvnTableExists
FROM DBA_TABLES
WHERE Table_Name = 'SOME_TABLE';
IF lvnTableExists = 0 THEN
EXECUTE IMMEDIATE 'CREATE TABLE SOME_TABLE AS (SELECT * FR0M OTHER_TABLE)';
END IF;
END;
This is something that I'm going for.
DECLARE
sql VARCHAR2(100000);
BEGIN
sql := 'CREATE TABLE SOME_TABLE ' ||
'AS (SELECT * FROM OTHER_TABLE) ' ||
'WHERE NOT EXISTS (SELECT NULL ' ||
'FROM DBA_OBJECTS d WHERE d.Object_Name = 'SOME_TABLE' AND ' ||
'd.Owner = 'SOME_TABLE')';
EXECUTE IMMEDIATE sql;
END;
The problem is that, you can't put a WHERE NOT EXISTS in a CREATE TABLE AS statement.
Yes, that's really a shame that Oracle doesn't have that functionality. I'm sure it will come some day. Until then, if you want to write a PL/SQL wrapper, why not do it like that:
DEClARE
table_exists_already exception;
pragma exception_init(table_exists_already, -955 );
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE SOMETABLE...';
EXCEPTION WHEN table_exists_already THEN
DBMS_OUTPUT.PUT_LINE('Table sometable already exists');
END;
/
Can some one please guide me what's wrong with this query? In SQL Server we just check the presence of the Object_ID of a table to drop it and re-create it. I am new to Oracle and wrote this query:
declare Table_exists INTEGER;
BEGIN
Select count(*) into Table_exists from sys.all_tables where table_name='TABLENAME1';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
Table_Exists :=0;
if(table_exists)=1
Then
Execute Immediate 'Drop Table TABLENAME1;'
'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('Table Dropped and Re-Created!');
Else
Execute Immediate 'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('New Table Created!');
END IF;
END;
I get the output - ANONYMOUS BLOCK COMPLETED, but the table is not created. The table was previously existing, so I dropped it to check if the PL/SQL is actually creating the table, but NO. What is wrong here? What am I missing? Please guide.
When you are using all_tables filter the results for your
schema by adding where owner = 'your_schema'
or use sys.user_tables
ALL_TABLES describes the relational tables accessible to the current user
USER_TABLES describes the relational tables owned by the current user.
When use execute_emmidiate remove the ; from the query;
Modified query;
DECLARE
Table_exists INTEGER;
BEGIN
Select count(*) into Table_exists from sys.user_tables where table_name='TABLENAME1';
--or
--Select count(*) into Table_exists from sys.all_tables
--where table_name='TABLENAME1' and owner = 'your_DB';
if table_exists = 1 Then
Execute Immediate 'Drop Table TABLENAME1';
Execute Immediate 'Create Table TABLENAME1(num number)';
DBMS_OUTPUT.PUT_LINE('Table Dropped and Re-Created!');
Else
Execute Immediate 'Create Table TABLENAME1(num number)';
DBMS_OUTPUT.PUT_LINE('New Table Created!');
END IF;
END;
First note:
Select count(*) into Table_exists
from sys.all_tables
where table_name = 'TABLENAME1';
will always return one row. You don't need the exception handling.
My best guess is that you have more than one table called TABLENAME1. Run this query to find out:
Select *
from sys.all_tables
where table_name = 'TABLENAME1';
Oracle stores tables from all owners that you can access. You might also want to check OWNER_NAME in the where clause.
However, you seem to understand exception handling. So, just drop the table, ignore any errors, and then recreate the table.
The EXCEPTION clause lasts till the next END and not just the next statement. If you want to continue after catching the exception you need to add an additional BEGIN/END:
declare
Table_exists INTEGER;
BEGIN
BEGIN
Select count(*) into Table_exists from sys.all_tables where table_name='TABLENAME1';
EXCEPTION
WHEN NO_DATA_FOUND THEN
Table_Exists :=0;
END;
if(table_exists)=1 Then
Execute Immediate 'Drop Table TABLENAME1;'
Execute Immediate 'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('Table Dropped and Re-Created!');
Else
Execute Immediate 'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('New Table Created!');
END IF;
END;
As pointed out by Gordon, the EXCEPTION clause is not really needed in this case since count(*) will always return one row. So the following is sufficient:
declare
Table_exists INTEGER;
BEGIN
Select count(*) into Table_exists from sys.all_tables where table_name='TABLENAME1';
if(table_exists)=1 Then
Execute Immediate 'Drop Table TABLENAME1;'
Execute Immediate 'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('Table Dropped and Re-Created!');
Else
Execute Immediate 'Create Table TABLENAME1;';
DBMS_OUTPUT.PUT_LINE('New Table Created!');
END IF;
END;
QUERY
BEGIN
FOR R IN (SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'ONAME')
LOOP
GRANT SELECT ON R.TABLE_NAME TO UNAME;
END LOOP;
END;
/
I want to grant read access of tables in ONAME to UNAME. But, I've the following errors:
PLS-00103: Encountered the symbol "GRANT" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with
<<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
Please help me. Thanks in advance.
In Oracle, you can't do any DDL statements directly in PL/SQL. You have to use EXECUTE IMMEDIATE to execute them, e.g.:
FOR R IN (SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'ONAME')
LOOP
EXECUTE IMMEDIATE 'GRANT SELECT ON '||R.TABLE_NAME||' TO UNAME';
END LOOP;
I am trying to write a very simple sql script:
select * from table_X;
and I would like to see the results in oracle sqlplus, if there are any. These results are important for further analysis.
Also to mention, it depends, how many tables were created originally, so chances are that table_X may not be in the database at all. However I want to avoid getting an error, when parsing, that table_X doesn't exist, while running that script above.
So I was trying to wrap that SQL into some PLSQL dynamic code, like this:
Define table_X="MY_TAB"
DECLARE
stmt_ VARCHAR2(2000);
exist_ number := 0;
CURSOR table_exist IS
SELECT 1
FROM user_tables
WHERE table_name = '&table_X';
BEGIN
OPEN table_exist;
FETCH table_exist INTO exist_;
CLOSE table_exist;
IF exist_ = 1 THEN
stmt_ := 'SELECT * FROM &table_X';
EXECUTE IMMEDIATE stmt_;
ELSE
dbms_output.put_line('This functionality is not installed.');
END IF;
END;
/
Why I cannot see any result (records), if there is data in MY_TAB? Do I really need to bind some columns and use ex. dbms_output to be able to see some information?
Is there any simple way to query a table without getting 'ORA-00942: table or view does not exist'
if that table doesn't exist (ideally using SQL only)?
Thanks in advance
like this if you want it in sqlplus:
SQL> var c refcursor;
SQL> create or replace function get_table(p_tab in varchar2)
2 return sys_refcursor
3 is
4 v_r sys_refcursor;
5 NO_TABLE exception;
6 pragma exception_init(NO_TABLE, -942);
7 begin
8 open v_r for 'select * from ' || dbms_assert.simple_sql_name(p_tab);
9 return v_r;
10 exception
11 when NO_TABLE
12 then
13 open v_r for select 'NO TABLE ' || p_tab as oops from dual;
14 return v_r;
15 end;
16 /
Function created.
SQL> exec :c := get_table('DUAL2');
PL/SQL procedure successfully completed.
SQL> print c
OOPS
-----------------------------------------
NO TABLE DUAL2
SQL>
SQL> exec :c := get_table('DUAL');
PL/SQL procedure successfully completed.
SQL> print c
D
-
X
Instead of execute immediate 'query' you could use execute immediate 'query' bulk collect into and then loop over it and use dbms_output to print it.
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/executeimmediate_statement.htm