Oracle Database unsigned integer - sql

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)
);

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>

Validation on mobile number

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}$')
)

Insert Into Oracle Table with single, autoincrement Column

Imagine the following (fictional) situation:
You have a table with only one column id that is the primary key, autoincremented by using a typical sequence + trigger combination.
How would you create a new row there as you have to specify the values keyword for the insert query?
INSERT INTO table () VALUES () is not valid as far as I understood.
ATTENTION:
This is not a discussion about the sense of such a table! It is out of pure technical interest.
In any current Oracle version (12.1, 12.2, 18) I would not use a trigger but an identity column - then use the default keyword during insert:
create table x (id integer generated by default as identity);
insert into x (id) values (default);
How about
INSERT INTO theTable (id) VALUES (null);
and your before insert trigger would be like:
if :NEW.id is NULL Then
SELECT id_sequence.NEXTVAL INTO :NEW.id FROM dual;
end if;

How to enforce a constraint violation when inserting non-integer number to integer column?

As you can see from the example below I know how to enforce a range with a check constraint and how to enforce a column to contain only an integer.
What puzzles me is when inserting non-integer number Oracle doesn't raise constraint violation error but instead silently rounds the number to an integer.
How do I prevent insertion of non-integer number values ? Instead of the insertion I'd like to have a constraint violation.
In working on 11g but if the answer is different for 12c (and future releases) those answers are also welcome.
Example:
create table so59_t (
id number(38)
,a number(38)
,constraint a_ch check (a > 0)
);
--
-- the following values raise a constraint violation as expected
--
SQL> insert into so59_t values(1, -1);
insert into so59_t values(1, -1)
*
ERROR at line 1:
ORA-02290: check constraint (TEST.A_CH) violated
SQL> insert into so59_t values(2, 0);
insert into so59_t values(2, 0)
*
ERROR at line 1:
ORA-02290: check constraint (TEST.A_CH) violated
--
-- the following values are silently rounded and successfully inserted
-- however I'd like to have a constraint violation instead
--
SQL> insert into so59_t values(3, 1.4);
1 row created.
SQL> insert into so59_t values(4, 1.5);
1 row created.
SQL> select * from so59_t;
ID A
---------- ----------
3 1
4 2
SQL>
Create Check
constraint a_int check (a = ROUND(a))
EDIT: one should read the syntax diagram BEFORE posting...
EDIT: create the column as number(38,1) like sanjay radadiya suggested
Using regular expression on constraint you can do validation for numeric number
create table so59_t (
id number(38)
,a number
,constraint a_ch check (REGEXP_COUNT(a, '^[1-9]\d*$')<>0 and length(a)<=38)
);
This might be in fact impossible. Let's study the fine manual.
How an integer is specified:
Specify an integer using the following form:
NUMBER(p)
This represents a fixed-point number with precision p and scale 0 and is equivalent to NUMBER(p,0).
So here we've precision = 38 and scale = 0. And the manual says following (emphasis mine):
It is good practice to specify the scale and precision of a fixed-point number column for extra integrity checking on input. Specifying scale and precision does not force all values to a fixed length. If a value exceeds the precision, then Oracle returns an error. If a value exceeds the scale, then Oracle rounds it.
Based on the trials in this question the rounding takes place before constraints and triggers (not shown here but a print statement in before-insert-trigger printed the rounded value).
My conclusion at the moment is that there is no way to get an access to the non-rounded value. This is the "correct" answer until someone proves otherwise.

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
....
)