Validation on mobile number - sql

What is the logic when I want to validate one mobile number field i.e mobile no should be numeric,10 digits as well as not start from 0,1,2,3,4,5.??
I am using SQL Developer.
Thanks

Well, you can use constraints. In your case, you want that the field is 10 digits and that it does not start with 0,1,2,3,4,5.
For complex formats is better to use regular expressions, but in your requirement is not needed.
SQL> create table t ( mobile number(10) ) ;
Table created.
SQL> alter table t add constraint chk_mob_phn check ( SUBSTR(TO_CHAR(mobile),1,1) not in ( 0,1,2,3,4,5) ) ;
Table altered.
SQL> alter table t add constraint chk_mob_len check ( length(mobile) = 10 ) ;
Table altered.
SQL> insert into t values ( 0298338383 ) ;
insert into t values ( 0298338383 )
*
ERROR at line 1:
ORA-02290: check constraint (SYS.CHK_MOB_PHN) violated
SQL> insert into t values ( 99999 ) ;
insert into t values ( 99999 )
*
ERROR at line 1:
ORA-02290: check constraint (SYS.CHK_MOB_LEN) violated
SQL> insert into t values ( 6987838322 ) ;
1 row created.

I strongly dissuade you from storing the mobile number as a number. Although you don't want leading zeros, that might change in the future. Plus, the value is not really a number -- arithmetic is not defined on it.
So:
create table t (
mobile_number varchar2(10),
check (regexp_like(mobile_number, '^[6-9][0-9]{9}$')
)

Related

How to avoid space(s) while inserting data in a table in oracle

I want to avoid leading and trailing spaces in a column of a table. I tried using below check constraints but showing error - "invalid relational operator".
alter table employee add (CONSTRAINT trm_name check(trim(name)));
alter table employee add (CONSTRAINT trm_name check(trim(dept)));
Suppose, I have a table employee, and want no leading and trailing spaces on both columns(name and dept). Could anyone please help me.
Regards,
Tarak
You can use a trigger:
CREATE OR REPLACE TRIGGER EMPLOYEE_BIU
BEFORE INSERT OR UPDATE ON EMPLOYEE
FOR EACH ROW
BEGIN
:NEW.DEPT := TRIM(:NEW.DEPT);
END EMPLOYEE_BIU;
I assume, in particular, you don't want to allow non-empty strings made up entirely of spaces in those columns.
If so, I would write the constraints with decode, which handles NULL the way needed for constraints (in which an equality like NULL=something is treated the same as TRUE - unlike the same equality in WHERE clauses or join conditions, where it is treated the same as FALSE).
For example:
alter table employee
add (CONSTRAINT trm_name check(decode(name, trim(name), 1, 0) = 1));
decode returns 1 if and only if name is NULL or name is non-NULL and it has no leading or trailing spaces. It returns 0 in all other cases - if name is all spaces, then trim(name) is NULL, name is not NULL, so decode returns 0 and the constraint is FALSE.
Note that often we write conditions in the form decode(a, b, 1) = 1 (the default return value of decode is NULL, so this suffices in WHERE clauses and in join conditions). In constraints, NULL = 1 is handled the same as TRUE, so this shorthand will not work; we must give a non-NULL value in decode when a and b are not the same.
You can use the CHECK constraint as follows:
SQL> CREATE TABLE ABC (
2 NAME VARCHAR2(100) CHECK ( NAME = TRIM(NAME) ), -- use CHECK constraint
3 DEPT VARCHAR2(100) CHECK ( DEPT = TRIM(DEPT) ) -- use CHECK constraint
4 );
Table created.
SQL> -- space in name
SQL> INSERT INTO ABC VALUES (' TEJASH ','SO');
INSERT INTO ABC VALUES (' TEJASH ','SO')
*
ERROR at line 1:
ORA-02290: check constraint (TEJASH.SYS_C0014819) violated
SQL> -- space in department
SQL> INSERT INTO ABC VALUES ('TEJASH1',' SO');
INSERT INTO ABC VALUES ('TEJASH1',' SO')
*
ERROR at line 1:
ORA-02290: check constraint (TEJASH.SYS_C0014820) violated
SQL> -- valid record
SQL> INSERT INTO ABC VALUES ('TEJASH1','SO');
1 row created.
SQL>

Oracle Database unsigned integer

I want too know ,If Oracle Database support unsigned int(number) how I can use it or if not what is alternative of this?
I don't need way to put condition for SQL syntax because all my data is positive and it's important unsigned int for performance and storage.
There's no unsigned integer as native datatype in Oracle. There's the NUMBER datatype. However, you can use INT, e.g.
SQL> create table test (id int);
Table created.
SQL> insert into test (id) values (-1);
1 row created.
SQL> insert into test (id) values (25.335);
1 row created.
SQL> select * From test;
ID
----------
-1
25
SQL>
As you can see, it accepts both positive and negative values (decimals are truncated).
In order to make it positive, add a constraint:
SQL> truncate table test;
Table truncated.
SQL> alter table test add constraint ch_id_pos check (id >= 0);
Table altered.
SQL> insert into test (id) values (-1);
insert into test (id) values (-1)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_ID_POS) violated
SQL>
I don't think that Oracle provides a specific datatype for unsigned integers. It provides a single datatype to store fixed numeric values, called NUMBER, whose precision and scale can be adjusted as needed.
In Oracle, the so-called INT datatype is a syntactical sugar provided for ANSI compatibility, which internaly maps to NUMBER.
I would recommend a number with a 0 scale (that's an integer), and a check constraint to ensure that it is positive:
create table mytable (
id number(20, 0) check (id >= 0)
);

Syntax check for constraint thats checks value of col1 = col2 * col3

Might be something very simple regarding syntax that I've been doing wrong but for the past 2 hours i've been trying multiple statements when defining this constraint at both table and column levels as part of CREATE TABLE and tried the same separately using ALTER TABLE however haven't had any success:
Create table tb1 (
tb1_quantity number,
tb1_price number,
tb1_total number constraint tb1_total_CK
CHECK(tb1_total = SUM(tb1_quantity * tb1_price))
);
The other way i've been trying is:
Create table tb1 (
tb1_quantity number,
tb1_price number,
tb1_total number constraint tb1_total_CK
CHECK(SUM(tb1_quantity * tb1_price))
)
;
Seems to be something with the way i'm declaring the functions methinks since im constantly getting the usual ORA-00934 Group function not allowed here message. I have read multiple alternative ways using triggers and views but i'm eager to get it to work using a constraint, am I along the correct lines with this syntax or just not wording it properly ?
you need to define this as an out of line constraint..i.e.:
Create table tb1 (
tb1_quantity number,
tb1_price number,
tb1_total number,
constraint tb1_total_CK CHECK(tb1_total = tb1_quantity * tb1_price)
);
eg:
SQL> Create table tb1 (
2 tb1_quantity number,
3 tb1_price number,
4 tb1_total number,
5 constraint tb1_total_CK CHECK(tb1_total = tb1_quantity * tb1_price)
6 );
Table created.
SQL> insert into tb1 values (1, 1, 1);
1 row created.
SQL> insert into tb1 values (1, 1, 2);
insert into tb1 values (1, 1, 2)
*
ERROR at line 1:
ORA-02290: check constraint (DTD_TRADE.TB1_TOTAL_CK) violated

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

SQLPlus AUTO_INCREMENT Error

When I try and run the following command in SQLPlus:
CREATE TABLE Hotel
(hotelNo NUMBER(4) NOT NULL AUTO_INCREMENT,
hotelName VARCHAR(20) NOT NULL,
city VARCHAR(50) NOT NULL,
CONSTRAINT hotelNo_pk PRIMARY KEY (hotelNo));
I get the following error:
(hotelNo NUMBER(4) NOT NULL AUTO_INCREMENT,
*
ERROR at line 2:
ORA-00907: missing right parenthesis
What am I doing wrong?
Many will gripe about this not being a standard feature in Oracle, but when it’s as easy as two more commands after your CREATE TABLE command I can’t see any good reason to use fancy SQL on every insert.
First let’s create a simple table to play with.
SQL> CREATE TABLE test
(id NUMBER PRIMARY KEY,
name VARCHAR2(30));
Table created.
Now we’ll assume we want ID to be an auto increment field. First we need a sequence to grab values from.
SQL> CREATE SEQUENCE test_sequence
START WITH 1
INCREMENT BY 1;
Sequence created.
Now we can use that sequence in a BEFORE INSERT trigger on the table.
CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT
ON test
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT test_sequence.nextval INTO :NEW.ID FROM dual;
END;
/
SQL> INSERT INTO test (name) VALUES ('Jon');
1 row created.
SQL> INSERT INTO test (name) VALUES (’Bork’);
1 row created.
SQL> INSERT INTO test (name) VALUES (’Matt’);
1 row created.
SQL> SELECT * FROM test;
ID NAME
———- ——————————
1 Jon
2 Bork
3 Matt
Oracle has no auto_increment, you need to use sequences.
Or - starting with Oracle 12.1 - you can simply have:
CREATE TABLE employee
(
id NUMBER GENERATED by default on null as IDENTITY
....
)