Add constraint unique column with null value - sql

I need to create a constraint of integrity that ensures that in a column of a table there is only one null valor. The classic UNIQUE is not good because it does not detect multiple nulls ...
how can I do?

CREATE TABLE qwe(
id int
);
CREATE UNIQUE INDEX qwe_idx ON qwe(
CASE WHEN id IS null THEN 'NULL' ELSE to_char(id) END
);
INSERT INTO qwe VALUES(1);
1 row inserted.
INSERT INTO qwe VALUES(1);
Error starting at line : 9 in command -
INSERT INTO qwe VALUES(1)
Error report -
ORA-00001: naruszono więzy unikatowe (TEST.QWE_IDX)
INSERT INTO qwe VALUES(NULL);
1 row inserted.
INSERT INTO qwe VALUES(NULL);
Error starting at line : 9 in command -
INSERT INTO qwe VALUES(NULL)
Error report -
ORA-00001: naruszono więzy unikatowe (TEST.QWE_IDX)
SELECT * FROM qwe;
ID
----------
1
(null)

Related

Want to create a database column with following checks on oracle database sql

Column should follow below validation needs to be implemented with constraints in oracle db
Should Be Only in Upper Case
Should Not Contain Leading and Trailing Spaces
Should Not Contain Extra Spaces Other Than One Space Between The Words
Should Not Contain Special Characters and Numbers Anywhere in The Text
See if this helps.
SQL> create table test
2 (col varchar2(20),
3 --
4 constraint ch1_upper check (col = upper(col)),
5 --
6 constraint ch2_letraspc check (col = trim(col)),
7 --
8 constraint ch3_wrdspc check (regexp_like(col, '^ *(\w+ ?)+ *$')),
9 --
10 constraint ch4_spec check (regexp_like(col, '^[[:alpha:] ]+$'))
11 );
Table created.
Testing:
SQL> insert into test values ('abc');
insert into test values ('abc')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH1_UPPER) violated
SQL> insert into test values (' DEF');
insert into test values (' DEF')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH2_LETRASPC) violated
SQL> insert into test values ('DEF ');
insert into test values ('DEF ')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH2_LETRASPC) violated
SQL> insert into test values (' DEF ');
insert into test values (' DEF ')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH2_LETRASPC) violated
SQL> insert into test values ('GHI23');
insert into test values ('GHI23')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH4_SPEC) violated
SQL> insert into test values ('GHI#');
insert into test values ('GHI#')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH4_SPEC) violated
SQL> insert into test values ('GHI JKL');
insert into test values ('GHI JKL')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH3_WRDSPC) violated
SQL> insert into test values ('GHI JKL MNO');
insert into test values ('GHI JKL MNO')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH3_WRDSPC) violated
SQL> insert into test values ('GHI JKL MNO');
1 row created.
SQL>

Restrict only '1' and '0' value in sql

I'm currently working in Oracle SQL and I am trying to constrain the integer datatype to only take the values 0 and 1 (for an active item or not).
This is what I currently have:
CREATE TABLE ACTIVE_EX (
ACTIVE int NOT NULL
CONSTRAINT check_active_ind CHECK (ACTIVE = 0 OR ACTIVE = 1)
);
SELECT * FROM ACTIVE_EX;
INSERT INTO ACTIVE_EX(ACTIVE)values(2);
When I enter this command and run the Select * from ACTIVE_EX line, the value 2 will still be entered into the table with no error.
How about this?
SQL> create table test
2 (active int not null
3 constraint ch_active check (active in (0, 1))
4 );
Table created.
SQL>
SQL> insert into test values (-1);
insert into test values (-1)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_ACTIVE) violated
SQL> insert into test values (2);
insert into test values (2)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_ACTIVE) violated
SQL> insert into test values (100);
insert into test values (100)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_ACTIVE) violated
SQL> insert into test values (0.3);
1 row created.
SQL> insert into test values (1.2);
1 row created.
SQL> insert into test values (3.8);
insert into test values (3.8)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_ACTIVE) violated
SQL> select * From test;
ACTIVE
----------
0
1
SQL>
As you can see, decimal values between 0 and 1 can be entered, but will be rounded so the final result will still be 0 or 1.

Import from .sql file Oracle SQL Developer excluding duplicates

I have exported a table from one database using Oracle SQL Developer as .sql file and want to import it into another database that has exactly the same table, but the problem is that some entries appear in both tables.
Is there a way when importing using Oracle SQL Developer to exclude entries that already exist in the destination table?
There are at least two ways:
You can use the SQLLDR tool or external table to load
You can load your sql file into the database and then remove duplicates.
Let's use this file:
data.sql
insert into test_table (id) values (1);
insert into test_table (id) values (1);
insert into test_table (id) values (2);
insert into test_table (id) values (2);
insert into test_table (id) values (2);
insert into test_table (id) values (3);
insert into test_table (id) values (3);
SQLLDR:
At first you create integrity constraints for your table for example:
SQL> create table test_table (
2 id number(10) primary key
3 );
Table created.
Then create a control file:
LOAD DATA
INFILE data.sql
INTO TABLE test_table
(
id position(37:37)
)
After running you will see:
SQL> select * from test_table;
ID
----------
1
2
3
And the bad file (This lines were rejected because of the integrity violation):
data.bad
insert into test_table (id) values (1);
insert into test_table (id) values (2);
insert into test_table (id) values (2);
insert into test_table (id) values (3);
You can generate the external table using this control file, so I don't show you how to use it.
Load and remove duplicates:
Let's recreate the test_table table:
SQL> create table test_table (
2 id number(10)
3 );
Table created.
Using SQL Developer load your sql file and check the content:
SQL> select * from test_table;
ID
----------
1
1
2
2
2
3
3
7 rows selected.
and then remove duplicates:
SQL> delete test_table where rowid not in (select min(rowid) from test_table group by id);
4 rows deleted.
SQL> select * from test_table;
ID
----------
1
2
3
I believe there is a way more ways to complete your tasks, I showed only ways that came in my head right away.

PL/SQL developer how to get the row that made the insert fail?

I'm doing a method that inserts into the table which has a unique column. What I don't know is if I can access the insert value that made the insert fail.
For example:
table1(id,name, phone);
name is unique.
insert (1,a,123);
insert (2,a,1234);
What I want is when I do the second insert I to return the id value '1' without having to recur to a query.
Thank you in advance.
From oracle 10g r2 you can use log errors clause of insert command to log errors in a separate table. Here is an example:
SQL> create table test_table(
2 id number primary key,
3 col1 varchar2(7)
4 )
5 ;
Table created
-- creates a table for logging errors (table name will be prefaced with err$_)
SQL> begin dbms_errlog.create_error_log('TEST_TABLE'); end;
2 /
PL/SQL procedure successfully completed
-- violates primary key constraint
SQL> insert into test_table(id, col1)
2 ( select 1, level
3 from dual
4 connect by level <= 3)
5 log errors reject limit unlimited;
1 row inserted
SQL> commit;
SQL> select * from test_table;
ID COL1
---------- -------
1 1
SQL> select * from err$_test_table;
ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ ID COL1
--------------- ------------------------------------------------------------------------------------------------------------
1 ORA-00001: unique constraint (HR.SYS_C008315) violated I 1 2
1 ORA-00001: unique constraint (HR.SYS_C008315) violated I 1 3
maybe you can write a trigger(before insert) on your table, on which insert about to happen. In this you can check if the column value(name) already exists in table.
In case it does you may insert this duplicate record in another table for further reference
Another approach is to write the insert in a procedure where the name may be checked and the duplicate name could be stored in a table.
Hope it helps

How do I add an integer that does not already exist?

If I have a table A with column INCREMENT_NUMBER. We will say that there are five rows.
1
2
3
4
4
If a user adds a new row to table A, the INCREMENT_NUMBER column of that row should be 5. (It could be anything, as long as it isn't a number 1-4.) Keep in mind
INCREMENT_NUMBER integer auto_increment primary key
will not work because I need to allow for duplicates in the table and I don't think
insert
If you want to allow duplicates, don't declare it as a PRIMARY KEY (and neither put a UNIQUE constraint on it).
In MySQL an AUTO_INCREMENT is allowed to have duplicates in that case - you just have to add a simple index on it:
CREATE TABLE test
( increment_number INTEGER NOT NULL AUTO_INCREMENT
, INDEX inc_index (increment_number)
) ;
INSERT INTO test
VALUES (1),(2),(3),(4),(4);
Test in SQL-Fiddle: test-1
INSERT INTO test
VALUES
(NULL);
SELECT *
FROM test ;
Results in:
increment_number
----------------
1
2
3
4
4
5
In SQL-Server, you'll have to toggle the IDENTITY_INSERT setting ON and OFF to have similar behaviour:
CREATE TABLE test
( increment_number INT IDENTITY(1,1) NOT NULL
, name varchar(20) NOT NULL
) ;
SET IDENTITY_INSERT test ON ;
INSERT INTO test (increment_number, name)
VALUES
(1, 'Alex'),
(2, 'Bill'),
(3, 'Cathy'),
(4, 'Diana'),
(4, 'Dean');
And then test-2:
SET IDENTITY_INSERT test OFF ;
INSERT INTO test (name)
VALUES
('Elaine') ;
SELECT *
FROM test ;
Results in:
increment_number | name
---------------------------
1 Alex
2 Bill
3 Cathy
4 Diana
4 Dean
5 Elaine