I am attempting to rename a column on a table which it looks like someone misspelled, but Oracle doesn't like the command I am sending.
ALTER TABLE VW_SUBSTANCE_FULL RENAME COLUMN SV_CHARATERISTICS TO SV_CHARACTERISTICS;
Error report -
ORA-23291: Only base table columns may be renamed
23291. 00000 - "Only base table columns may be renamed"
*Cause: Tried to rename a column of a non-base table, like object table/
nested table/ materialized view table.
*Action: None. This is not allowed.
Obviously it is not allowed, but I've researched and can't find the alternative.
Here is the table SQL:
CREATE TABLE "M_INFO"."VW_SUBSTANCE_FULL"
( "SUBSTANCE_ID" NUMBER(20,0),
"BARCODE" VARCHAR2(765 BYTE),
"BCODE" VARCHAR2(765 BYTE),
"LOT" NUMBER(10,0),
"FW" NUMBER(28,6),
"CORE_MOLECULAR_WEIGHT" NUMBER(28,6),
"EXACT_MASS" NUMBER(28,6),
"SV_CHARATERISTICS" VARCHAR2(720 BYTE),
"PROJECT" VARCHAR2(765 BYTE),
"VENDOR_CAT_ID" VARCHAR2(765 BYTE),
"REGISTRATION_DATE" DATE,
"EXTERNAL_CODE" VARCHAR2(720 BYTE),
"COMMON_NAME" VARCHAR2(765 BYTE),
"SCAFFOLD" VARCHAR2(765 BYTE),
"SUBSCAFFOLD" VARCHAR2(765 BYTE),
"CRO_CODE" VARCHAR2(720 BYTE)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "M_INFO_D" ;
Any assistance or direction is appreciated.
Attempted to rename a column, but Oracle does not like that action.
If VW_SUBSTANCE_FULL is actually a materialized view, as the name hints and the error suggests, then you can't just change the name. The materialized view will need to be recreated.
You could potentially drop the view while retaining the base table, rename the column in the base table as you'd already attempted, and then recreate the view using the existing table. That might save a bit of rebuild time.
I'd previously said you could change the target of the rename from the base table to the view itself:
ALTER MATERIALIZED VIEW VW_SUBSTANCE_FULL RENAME COLUMN SV_CHARATERISTICS TO SV_CHARACTERISTICS;
... but that doesn't work in Oracle; it seems to in PostgreSQL, which doesn't help.
Related
So I created a database in Oracle SQL Developer and wrote up all the table definitions by hand using Notepad ++ and just did a bulk create tables statement.
Silly me forgot to save this file so now I have all the definitions on SQL developer but none locally.
I have made some major changes to the design however there are some definitions that I can still use that are on there.
Is there a way I can export all the tables in a database to a file? I know I can grab the definitions individually however the time constraint would be massive. This way I don't have to go about manually writing it all again. Any searches that I conduct looking for an answer are just giving answers on how to select all tables in a database and not how to export table definitions.
Just to note, I had a look in my temp data for Notepad ++ however the file is not there anymore.
Tools, Database Export
Uncheck 'data'
Pick your output options, you want one file for everything or one file for each object.
Then pick your schema and objects - if you pick 'nothing' it will dump out the entire schema by default.
Sure, you can - using the DBMS_METADATA package and its GET_DDL function.
For example - in which I'm doing it in SCOTT's schema for two tables only - it would be like this:
SQL> set pagesize 0
SQL> set linesize 200
SQL> set long 20000
SQL> set longchunksize 20000
SQL> set feedback off
SQL> set verify off
SQL> set trimspool on
SQL>
SQL> select dbms_metadata.get_ddl ('TABLE', table_name, 'SCOTT')
2 from user_tables
3 where table_name in ('EMP', 'DEPT');
CREATE TABLE "SCOTT"."DEPT"
( "DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14),
"LOC" VARCHAR2(13)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
CREATE TABLE "SCOTT"."EMP"
( "EMPNO" NUMBER(4,0) NOT NULL ENABLE,
"ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
SQL>
You've noticed some SET commands at the beginning - I ran it in SQL*Plus, but they work in SQL Developer as well.
I have the following procedure in Oracle:
create procedure clone_tables
(current_table_name varchar2, cloned_table_name varchar2);
I have to clone a table, but I receive only it's name.
In this case, I think I have to get it's structure, so describe table_name command would be enough.
Now, execute immediate or dbms_sql.execute() use only SQL statements.
Is there another way I can do that?
If you need to build a clone of a table, you can use:
create or replace procedure clone_tables (current_table_name varchar2,
cloned_table_name varchar2
) as
begin
execute immediate
'create table ' || cloned_table_name ||
' as select * from ' || current_table_name
' where 1 = 0 ' ; /* to avoid copying records */
end;
/
This will build a table with exactly the same columns of the starting one, with no need for scanning all the columns. This way you will not copy the records of the starting table; if you want to copy records, simply remove the WHERE condition.
As correctly said by Alex Poole, this will only create the clone table, but will not create any trigger, index, foreign key, ... existing on the cloned table.
Query USER_TAB_COLUMNS to get a list of columns and their types.
Since you mention DESCRIBE (...), you must be using SQL*Plus - or a graphical program that understands SQL*Plus commands, like Toad or SQL Developer. Unfortunately, you CAN'T execute the DESCRIBE command in SQL or in PL/SQL, because DESCRIBE is a SQL*Plus command, it is NOT a SQL or PL/SQL command.
If you do use SQL Developer or Toad, they have a feature where you bring up a table and it gives you the SQL (not PL/SQL - that is not needed, plain and very fast SQL is all that's needed) to re-create the tables, INCLUDING constraints and comments. Below I am reproducing the output of using this feature in SQL Developer, on a practice SQL table. This only creates the table structure, not its data; you will still have to copy the data over, for example with
INSERT INTO (new_table) (SELECT * FROM old_table)
The advantage over Alexsej's solution is that the data type will be copied exactly; in Aleksej's solution the columns will not necessarily be EXACTLY the same - [for example, in the old table you may have a VARCHAR2(300) column; the width, 300, will not be copied with his method, and instead the width of the actual data present in the table will be used.] Edit: As Alex Poole pointed out in a comment, what I said here (in square brackets) is INCORRECT, cloning a table with Aleksej's solution WILL preserve column widths and such. (Also, his method will not copy the constraints, like NOT NULL and UNIQUE.)
The method I am recommending still doesn't re-create triggers, but it does re-create constraints and indexes.
Here is an example of what SQL Developer can do for you, with NO EFFORT on your part:
CREATE TABLE "INTRO"."COURSES"
( "CODE" VARCHAR2(6 BYTE) NOT NULL ENABLE,
"DESCRIPTION" VARCHAR2(30 BYTE) NOT NULL ENABLE,
"CATEGORY" CHAR(3 BYTE) NOT NULL ENABLE,
"DURATION" NUMBER(2,0) NOT NULL ENABLE,
CONSTRAINT "COURSES_PK" PRIMARY KEY ("CODE")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ENABLE,
CONSTRAINT "COURSES_CAT_CHK" CHECK (CATEGORY in ('GEN','BLD','DSG')) ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ;
COMMENT ON COLUMN "INTRO"."COURSES"."CODE" IS 'Unique course code';
COMMENT ON COLUMN "INTRO"."COURSES"."DESCRIPTION" IS 'Course description (title)';
COMMENT ON COLUMN "INTRO"."COURSES"."CATEGORY" IS 'Course category (GEN, BLD or DSG)';
COMMENT ON COLUMN "INTRO"."COURSES"."DURATION" IS 'Course duration (in days)';
Good luck!
In Oracle 11gR2 (v11.2.0.4.0)
I have a simple table;
CREATE TABLE "CLAIMS_PATIENT"
( "CLAIMS_PATIENT_ID" NUMBER NOT NULL ENABLE,
"NAME_LASTNAME" VARCHAR2(60 BYTE),
"NAME_FIRSTNAME" VARCHAR2(35 BYTE),
"NAME_MIDDLENAME" VARCHAR2(25 BYTE),
"ADDR_LINE" VARCHAR2(55 BYTE),
"ADDR_CITY" VARCHAR2(30 BYTE),
"ADDR_STATE" VARCHAR2(3 BYTE),
"ADDR_ZIP" VARCHAR2(15 BYTE),
"GENDER" VARCHAR2(1 BYTE),
"DOB" DATE,
"SSN" VARCHAR2(9 BYTE),
"MATCH_PID" NUMBER,
"MATCH_SCORE" NUMBER DEFAULT -1,
"MATCH_DATE" DATE,
"PACS_STATUS" VARCHAR2(1 BYTE) DEFAULT NULL,
CONSTRAINT "CLAIMS_PATIENT_PK" PRIMARY KEY ("CLAIMS_PATIENT_ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "MYDATA" ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "CLAIMS" ;
Which I have populated with some data. using a stored procedure. Now when I attempt to do any select on the table;
select * from claims_patient;
select count(*) from claims_patient;
select ssn from claims_patient;
It returns an ora-00904 error at the last character before the semi-colon. I created this table empty on my test db, using the ddl from live db, where everything works swimmingly. I have tried using both sqldeveloper and sqlplus.
At this point I suspect something crashed and corrupted the table in my test environment, but I have never seen a corrupt table in Oracle, and I have been working with it since 1995.
Before I wipe the table and start again, what should I do to uncover the underlying cause of this problem? At this point I am curious, in case I ever see it in production, it might be useful to know what the issue is.
As requested, the results of;
select table_name, dump(table_name) from user_tables where table_name like 'CLAIM%ENT';
is;
Typ=1 Len=14: 67,76,65,73,77,83,95,80,65,84,73,69,78,84
Well, I did find the answer. 'Twas in an unlikely place. One of the indices, which I did not include the DDL for, was a function based index. The function became inaccessible (grant revoked) over night.
So if anyone ever finds this thread and has a table with a function based index, where the function (after the table and indices are built) becomes inaccessible, dropped, execute permissions changed, or whatever, you may get an ora-00904 when trying to access any data in the table.
It sure would be nice if Oracle were to define a more specific error that would point you in the general direction of an answer.
I have a very huge DDL script in Oracle of our existing Application,
It has no Stored Procedures.
Just Tables, Sequences and constraints.
What is the best way to convert it to Postgres?
Some people say its better to do it by hand, and some say there are free tools for it.
Can anyone suggest me the best way to do it?
If it is by hand,
please suggest me what changes have to be made.
Example of Oracle DDL is given below,
Please notify the changes to be made while converting to Postgres for the below DDL.
- DDL for Table ACTOR_ROLE_INFO
--------------------------------------------------------
CREATE TABLE "PAYTM_RELEASE1"."ACTOR_ROLE_INFO"
( "ACTOR_ROLE_ID" NUMBER,
"ACTOR_ID" NUMBER,
"ROLE_ID" NUMBER,
"STATUS" NUMBER,
"CREATED_BY" NUMBER,
"CREATED_ON" TIMESTAMP (6) WITH TIME ZONE,
"MODIFIED_BY" NUMBER,
"MODIFIED_ON" TIMESTAMP (6) WITH TIME ZONE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ;
--------------------------------------------------------
-- DDL for Table ACTOR_TYPES
--------------------------------------------------------
CREATE TABLE "PAYTM_RELEASE1"."ACTOR_TYPES"
( "ACTOR_TYPE_ID" NUMBER,
"ACTOR_TYPE" VARCHAR2(100 BYTE),
"ACTOR_DESCRIPTION" VARCHAR2(100 BYTE),
"CREATED_BY" NUMBER,
"CREATED_DATE" TIMESTAMP (6) WITH TIME ZONE,
"MODIFIED_BY" NUMBER,
"MODIFIED_DATE" TIMESTAMP (6) WITH TIME ZONE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ;
Use Ora2PG http://sourceforge.net/projects/ora2pg/ to get started, but don't blindly use the resulting schema. As Craig suggested, take a look at the data types. The NUMBER to NUMERIC conversion while simple, leads to a much bigger footprint on disk. It also leads to much bigger index sizes which will slow the whole app down. Your resulting schema shouldn't contain any NUMERIC columns unless your app really needs the abritrary percision and it should be the exception, not the rule.
Is it possible, and if so, how, to tell Oracle SQL Developer to escape single quotes whenn exporting a table to inserts? It seems like an obvious thing to want to do, escape the character being used to quote fields when it occurs within the field, but I cannot find the option to do it.
Update: version 2.1.1.64, export method is. Context menu>export data>insert...
I just tried it using SQL Developer 3.0.04, and it appears that the single quotes in data are escaped by default:
--------------------------------------------------------
-- File created - Wednesday-June-01-2011
--------------------------------------------------------
--------------------------------------------------------
-- DDL for Table T3
--------------------------------------------------------
CREATE TABLE "THEUSER"."T3"
("C1" VARCHAR2(20 BYTE),
"C2" VARCHAR2(20 BYTE)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
REM INSERTING into THEUSER.T3
Insert into THEUSER.T3 (C1,C2) values ('C1','C''2');
I just had one row in the table, consisting of the values C1 and C'2.