Insert statement with blank values without defining all columns - oracle

I have a need to insert 100+ rows of data into a table that has 25 text columns.
I only want to insert some data into those columns and the rest be represented by a white space.
(Note: Text fields on PeopleSoft tables are defined as NOT NULLABLE, with a single white space character used to indicate no data instead of null.)
Is there a way to write an insert statement that does not define all the columns along with the blank space. As an example:
INSERT INTO CUST.RECORD(BUSINESS_UNIT, PROJECT_ID, EFF_STATUS, TMPL, DESCR) VALUES('TOO1','PROJ1','A','USA00','USA00 CONTRACT');
For every other column in CUST.RECORD I'd like to insert ' ' without defining the column or the space in the insert.

One way is to set a Default value in table definition like this:
CREATE TABLE CUST.RECORD(
id NUMBER DEFAULT detail_seq.NEXTVAL,
master_id varchar2(10) DEFAULT ' ',
description VARCHAR2(30)
);
Edit: for your table you can use :
alter table CUST.RECORD modify( col2 varchar2(10) default ' ' );

You do not have to supply a value for a specific column IF either condition is true:
The column is defined as nullable. That is, it was NOT defined with the 'not null' clause.
or
The column is defined with a default value
SQL> create table my_test (my_id number not null,
2 fname varchar2(10), -- nullable
3 dob date default sysdate -- default value
4 )
5 ;
Table created.
SQL> --
SQL> -- only supplying value for my_id
SQL> insert into my_test(my_id) values (1);
1 row created.
SQL> --
SQL> -- and see the results
SQL> select *
2 from my_test;
MY_ID FNAME DOB
1 12-MAR-21
1 row selected.
SQL> --
SQL> select my_id,
2 nvl(fname,'NULL'),
3 dob
4 from my_test;
MY_ID NVL(FNAME, DOB
1 NULL 12-MAR-21
1 row selected.

Related

Creating List partition to an already Existing Table

I am trying to Create a list partition Based on the column "REFRESH_FLAG_Y" which has only Y and N as its Values, Below is the Alter Table used to Create the partition
ALTER TABLE "EDW"."LABOR_SCHEDULE_DAY_F" MODIFY
PARTITION BY LIST ("REFRESH_FLAG")
(PARTITION "REFRESH_FLAG_Y" VALUES ('Y') ,
PARTITION "REFRESH_FLAG_N" VALUES ('N')) ;
COMMIT;
But Whenever I execute the code I get an Error message
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
You did tag the question with Oracle 11g tag; do you really use it?
This is a 12c example; it works if everything is OK:
SQL> create table labor_schedule_day_f as
2 select 1 id, 'Y' refresh_flag from dual union all
3 select 2 id, 'N' refresh_flag from dual;
Table created.
SQL> alter table labor_schedule_Day_f modify
2 partition by list (refresh_flag)
3 (partition refresh_flag_y values ('Y'),
4 partition refresh_flag_n values ('N')
5 );
Table altered.
Error you reported means this:
SQL> drop table labor_schedule_day_f;
Table dropped.
SQL> create table labor_schedule_day_f as
2 select 1 id, 'Y' refresh_flag from dual union all
3 select 2 id, 'N' refresh_flag from dual;
Table created.
Insert a row whose REFRESH_FLAG isn't Y nor N (so it violates the rule you specified):
SQL> insert into labor_schedule_day_f values (3, 'X');
1 row created.
Using the same ALTER TABLE statement as previously:
SQL> alter table labor_schedule_Day_f modify
2 partition by list (refresh_flag)
3 (partition refresh_flag_y values ('Y'),
4 partition refresh_flag_n values ('N')
5 );
alter table labor_schedule_Day_f modify
*
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
SQL>
See? Error you got, which means that
which has only Y and N as its Values
isn't true.
P.S. You'd get the same result even if refresh_flag was NULL for some rows.

Altering table property to default when NULL only for new inserts

Is there any way in Oracle that we can set Default column value when NULL only for New inserts? I don't want to change the Existing records if they have NULL.
I want to do this at table level. Not with NVL insert logic.
As far as I know, if you alter the table and set a default value for a column, it should only affect new records which would come in via an insert, not existing records.
ALTER TABLE yourTable MODIFY (col VARCHAR(100) DEFAULT 'some value');
Using the above approach, col values which are already NULL should remain NULL, at least from the point of view of inserts not changing those NULL values. And newly inserted records which do not specify a value for col should receive the default value some value.
Here's a demonstration which shows what's going on.
First, a test table and some inserts:
SQL> create table test (id number, col varchar2(10));
Table created.
SQL> insert into test (id, col) values (1, null);
1 row created.
SQL> insert into test (id, col) values (2, 'Littlefoot');
1 row created.
SQL> select * from test;
ID COL
---------- ----------
1
2 Littlefoot
Alter the table so that newly added rows contain 'some value' for the COL column:
SQL> alter table test modify col default 'some value';
Table altered.
OK; and now, important part of the story: pay attention to following:
SQL> -- this won't work as you wanted, because I explicitly inserted NULL into COL
SQL> insert into test (id, col) values (3, null);
1 row created.
SQL> -- this will work, because COL is omitted from the INSERT statement
SQL> insert into test (id) values (4);
1 row created.
SQL> select * From test;
ID COL
---------- ----------
1
2 Littlefoot
3
4 some value
SQL>
See? If you explicitly put NULL into a column, it won't get the default value.
However, if you were on 12c (I know, you aren't - just saying, for future reference), there's yet another option: DEFAULT ON NULL. It goes like this:
SQL> alter table test modify col default on null 'some value';
alter table test modify col default on null 'some value'
*
ERROR at line 1:
ORA-02296: cannot enable (SCOTT.) - null values found
Ooops! Won't work if there are NULLs in the column. I know #2 that you don't want to modify existing rows, but - for this demonstration, I'll do that:
SQL> update test set col = 'x' where col is null;
2 rows updated.
SQL> alter table test modify col default on null 'some value';
Table altered.
OK; let's see how it behaves: I'm explicitly inserting NULL into the column. In the previous example, it didn't put 'some value' in there, but left it NULL. How about now?
SQL> insert into test (id, col) values (5, null);
1 row created.
SQL> select * From test;
ID COL
---------- ----------
1 x
2 Littlefoot
3 x
4 some value
5 some value
Nice; we have 'some value' in the column.
Now you have some more info about the issue; see if it helps.
As Littlefoot mentioned, If you explicitly put NULL into a column, it won't get the default value.
If no value is mentioned for the column in the insert query, it uses DEFAULT. But, an explicit NULL overrides the default expression.
For 12c and above you can use the DEFAULT ON NULL option.
For prior versions, only way as far as I can tell is to replicate that functionality through a TRIGGER
CREATE TABLE YOURTABLE ( yourcolumn VARCHAR(100) );
CREATE OR REPLACE TRIGGER trg_mod_yourtabcol BEFORE
INSERT ON yourtable
FOR EACH ROW
WHEN ( new.yourcolumn IS NULL )
BEGIN
:new.yourcolumn := 'SOME DEFAULT VALUE';
END;
/
INSERT INTO YOURTABLE(yourcolumn) VALUES(NULL);
select * from YOURTABLE;
Table YOURTABLE created.
Trigger TRG_MOD_YOURTABCOL compiled
1 row inserted.
YOURCOLUMN
----------------------------------------------------------------------------------------------------
SOME DEFAULT VALUE
1 row selected.

Number data type column is not behaving as number

I have a table in oracle which has column recid which is of number Datar type. The table is partition table and it has partition index on it.
When I query the partition like
select * from table partition (abc)
I am able to see value for rec id =50. But when I query
select * from table partition(abc) where rec id =50,
It doesn’t give any record .
If I do type casting as
select * from table partition(abc) where cast (recid as number ) =50
I am getting records.
Please let me know what might be the issue .?
The issue exist only for one partition and rest of the partition working normal.
If it's not behaving as a number, then it's not stored as a number.
Run a DESCRIBE (DESC) on your table in either SQL Developer, SQLcl, or SQL*Plus. It will show how the REC_ID column is defined.
If it's stored as a VARCHAR2, you wil get an error on your WHERE CLAUSE predicate for REC_ID, if not every REC_ID could be treated as also a number:
ORA-01722: invalid number
Like so:
SQL> DESC employees
Name Null? Type
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL>
SQL> SELECT * FROM employees WHERE first_name = 50;
Error starting at line : 4 in command -
SELECT * FROM employees WHERE first_name = 50
Error report -
ORA-01722: invalid number
SQL> select * from emps_copy_num where first_name = 50;
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
100 50 King SKING 515.123.4567 17-JUN-87 AD_PRES 24000 90
The first query fails - because not every value in that column can be simplicity cast as a number by the database.
The second query works, because I created a copy of the table where all of the first_name strings were values that COULD be cast as a number.
You probably have spaces in there somewhere, eg
SQL> create table t ( should_have_been_numeric varchar2(30));
Table created.
SQL>
SQL> insert into t values ('50 ');
1 row created.
SQL> insert into t values (' 50 ');
1 row created.
SQL> insert into t values (' 50');
1 row created.
SQL>
SQL> select * from t where should_have_been_numeric = '50';
no rows selected
SQL> select * from t where cast(should_have_been_numeric as number) = 50;
SHOULD_HAVE_BEEN_NUMERIC
------------------------------
50
50
50
3 rows selected.
but as already mentioned, if you are treating strings as numbers, then there is problems ahead in terms of spurious errors, not to mention potential performance issues because the optimizer also doesn't know that these are really numbers.

How to select column value from a nested table

I created 1 object.
create type tab_billing as object(invoice_no number,
customername varchar2(100)
);
Now i created a table with the object as a column.
CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Is there anyway I can ONLY select invoice_no from the tab1.
select col2 from tab1;
Is givng me both invoice_no and customername. Substr function is not working here.
You can query the column value's object field directly, but to avoid confusing the object name resolution steps you have to supply and use a table alias:
select t1.col2.invoice_no from tab1 t1;
This is mentioned in the documentation:
To avoid inner capture and similar problems resolving references, Oracle Database requires you to use a table alias to qualify any dot-notational reference to subprograms or attributes of objects.
Qualifying the column with the the table name isn't enough; using select tab1.col2.invoice_no from tab1 gets ORA-00904. You have to use a table alias - although, slightly bizarrely, it still works if the alias is the same as the table name, so select tab1.col2.invoice_no from tab1 tab1 (i.e. aliasing tab1 as tab1, which is normally redundant) works too.
Quick demo:
create type tab_billing as object(invoice_no number,
customername varchar2(100)
);
/
Type TAB_BILLING compiled
CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Table TAB1 created.
insert into tab1 values (1, tab_billing(42, 'Test'));
1 row inserted.
select t1.col2.invoice_no from tab1 t1;
COL2.INVOICE_NO
---------------------------------------
42
You can use TREAT:
SQL> create type tab_billing as object(invoice_no number,
2 customername varchar2(100)
3 );
4 /
Type created.
SQL> CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Table created.
SQL> insert into tab1 values (1, tab_billing(10, 'ten')) ;
1 row created.
SQL> select col1,
2 TREAT(col2 AS tab_billing).invoice_no as invoice_no,
3 TREAT(col2 AS tab_billing).customername as customername
4 from tab1;
COL1 INVOICE_NO CUSTOMERNAME
------ ---------- --------------------
1 10 ten

Not update existing records with default value of new column

I have a table with some records.
I want to add a TIMESTAMP type of column (LAST_MODIFIED) to this table. I want to set the DEFAULT value of this new column to SYSDATE.
But I want to make sure that when this column is added, existing records does not get this column value as SYSDATE. How to achieve this ?
You should do it as two separate actions: adding a column and setting default value.
SQL> create table some_data (id integer);
Table created
SQL> insert into some_data select rownum from dual connect by level <= 5;
5 rows inserted
SQL> alter table some_data add date_modified date;
Table altered
SQL> alter table some_data modify date_modified default sysdate;
Table altered
SQL> insert into some_data (id) values (6);
1 row inserted
SQL> select * from some_data;
ID DATE_MODIFIED
--------------------------------------- -------------
1
2
3
4
5
6 17.03.2015
6 rows selected

Resources