How to add a BIT column in SQL - sql

I want to add a BIT column to a table. I have provided the statement to do so, but an error declares the BIT in my statement as a invalid datatype. What would be the correct way to add a bit column?
ALTER TABLE Persons
ADD is_person BIT NULL

[You should specify database you use; this is Oracle example, see if it helps].
There's no such a datatype in Oracle, so you'd use NUMBER and constrain it:
SQL> create table persons
2 (id number,
3 bit number(1,0) check (bit in (0, 1)) --> this
4 );
Table created.
A few examples:
SQL> insert into persons (id, bit) values (1, 2);
insert into persons (id, bit) values (1, 2)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.SYS_C008434) violated
SQL> insert into persons (id, bit) values (1, 1);
1 row created.
SQL> insert into persons (id, bit) values (1, 0);
1 row created.
SQL> insert into persons (id, bit) values (1, 10);
insert into persons (id, bit) values (1, 10)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
SQL>
Or, if you'd want to add it (as table already exists), then
alter table persons add bit number(1, 0) check (bit in (0, 1));

Related

Oracle if value to be inserted in foreign key is -1, insert null instead

I have a xml script I'm reading from to populate my database with data. One of the nodes in the xml file don't have a idDirector field (the nodes are movies) and so the xml reads a -1 as idDirector and then my stored procedure tries to insert -1 into the fk field and this makes my database returna constraint error : director -1 doesn't exist in Director table. How can I make it so it inserts null instead and make my fk field nullable?
CREATE TABLE Film (
PRIMARY KEY (idFilm),
FOREIGN KEY (idDirector) REFERENCES Director
);
Thank you
Looks like CASE to me, e.g.
insert into film (id_film, id_director)
select id_film,
case when id_director = -1 then null
else id_director
end
from ...
Will it work? Yes:
SQL> create table director (id number primary key);
Table created.
SQL> create table film (id number primary key, id_director number references director);
Table created.
SQL> insert into director values (100);
1 row created.
Inserting -1 fails:
SQL> insert into film (id, id_director) values (1, -1);
insert into film (id, id_director) values (1, -1)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.SYS_C0065885) violated - parent key not
found
Inserting NULL works:
SQL> insert into film (id, id_director) values (1, null);
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.

How can I enforce uniqueness on a combination of two columns in a database table?

I have a simple database with two tables :
Catalog (id_catalog, name )
Product (id_product, name, quantity, id_catalog# )
None of those fields can be empty, so I put a NOT NULL constraint everywhere.
But I need that two products couldn't have the same name if they are in the same catalog. How could I do that?
I mean
1, chocolat, 5, 1
2, chocolat, 7, 2
those are OK because they are in two different catalogs, but :
1, chocolat, 5, 1
2, chocolat, 7, 1
should not be allowed, because I shouldn't accept chocolat twice in the same catalog.
You can create a unique index to avoid inserting more than one row with the same couple (name, id_catalog#).
Create the table:
SQL> create table Product(id_product number, name varchar2(10), quantity number, id_catalog# number);
Table created.
Add an index :
SQL> create unique index idx1 on Product (name, id_catalog#);
Index created.
This will work:
SQL> insert into Product (id_product, name, quantity, id_catalog#) values (1, 'chocolat', 5, 1);
1 row created.
This will not work:
SQL> insert into Product (id_product, name, quantity, id_catalog#) values (2, 'chocolat', 7, 1);
insert into Product (id_product, name, quantity, id_catalog#) values (2, 'chocolat', 7, 1)
*
ERROR at line 1:
ORA-00001: unique constraint (ALEK.IDX1) violated
But this will, due to different id_catalog#
SQL> insert into Product (id_product, name, quantity, id_catalog#) values (2, 'chocolat', 7, 2);
1 row created.
SQL>

Inserting into table

I have this table on an Oracle server with this structure:
Create table temp
(
input number(10),
str varchar(24),
constraint L_PK PRIMARY KEY(input, str)
)
I made one alteration on it:
alter table temp add userID number(10);
Now I am trying to do an insert:
insert into temp values (9, 7, 'sure.');
But I am getting a error saying:
ORA-01722: Invalid Number
Any ideas? I'm pretty sure its coming from the 'sure' but I can't say for sure.
Specify the column-names when you are inserting so the appropriate data is inserted into the columns.
insert into temp (input, userid, str)
values (9, 7, 'sure.');
So you created a table with two columns:
Create table temp(
input number(10),
str varchar(24),
constraint L_PK PRIMARY KEY(input,str),
Made one alteration to it:
alter table temp add userID number(10);
Which leaves you with a table with columns input, str, and userID in that order. You then try to insert
insert into temp values (9, 7, 'sure.');
which tries to insert 9 into input (fine), 7 into str (not fine), and sure into userID (again, not fine).
You need to either use the values in the proper order to match the column order:
insert into temp values (9, 'sure', 7);
or (much better and safer) specify the columns first, and then assign the values to match:
insert into temp (input, userID, str) values (7, 9, 'sure');
In your case:
insert into temp values (9, 7, 'sure.');
It means:
INSERT INTO temp (input, str, userId)
VALUES (9, 7, 'sure.');
As 'sure.' does not a number type, Oracle server certainly gets error.
If you don't change the insert order,you should change the alteration SQL:
alter table temp add userID number(10) after str;
Yes,'after str' is appended.
Or you could change the insert order like this:insert into temp values (9, 'sure', 7);
Whatever you must remember that column should match with the value,especially in datatype.
You added userID at the end of the table. Try
insert into temp values (9, 'sure.', 7);
After adding column,it is added at the end of the table
insert into temp values (9, 'sure.',7);
output:
input str userID
9 sure. 7

SQL unique constraint on either of 2 columns

I have a table in SQL that I would like to have a unique constraint so that any of two values cannot already exist.
for example if I have 2 columns, I would like it to not insert if the value in column B does not exist in column A or column B.
Is this possible and if so how is it done?
example:
Column A | Column B
--------------------
4 | 6
I would want any object that tries to insert 4 or 6 not to be allowed into the table
Trigger with ROLLBACK TRANSACTION is the way to go.
create trigger dbo.something after insert as
begin
if exists ( select * from inserted where ...check here if your data already exists... )
begin
rollback transaction
raiserror ('some message', 16, 1)
end
end
You can create a function which takes in these values & create a check constraint on it (referencing your functions return values) to your table.
create table t11 (Code int, code2 int)
create function fnCheckValues (#Val1 int, #Val2 int)
Returns int /*YOu can write a better implementation*/
as
Begin
DECLARE #CntRow int
IF(#Val1 IS NULL OR #Val2 IS NULL) RETURN 0
select #CntRow = count(*) from t11
where Code in (#Val1,#Val2 ) or Code2 in (#Val1,#Val2 )
RETURN #CntRow
End
GO
alter table t11 Add constraint CK_123 check ([dbo].[fnCheckValues]([Code],[code2])<=(1))
When one want to enforce a multi-row constraint that is not offered by the database engine, the obvious solution is use of a trigger or stored procedure. This often does not work because the database isolates the transactions the triggers and stored procedures run in, allowing violations in the presense of concurrency.
Instead turn the constraint into something that the database engine will enforce.
CREATE TABLE dbo.T (A INT, B INT)
GO
CREATE TABLE dbo.T_Constraint_Helper (ColumnName sysname PRIMARY KEY)
INSERT INTO dbo.T_Constraint_Helper (ColumnName)
VALUES ('A'), ('B')
GO
CREATE VIEW T_Constraint_VW
WITH SCHEMABINDING AS
SELECT CASE CH.ColumnName WHEN 'A' THEN T.A ELSE T.B END AS Value
FROM dbo.T
CROSS JOIN dbo.T_Constraint_Helper CH
GO
CREATE UNIQUE CLUSTERED INDEX FunnyConstraint_VW_UK ON dbo.T_Constraint_VW (Value)
GO
INSERT INTO T VALUES (1, 2)
-- works
INSERT INTO T VALUES (2, 3)
-- Msg 2601, Level 14, State 1, Line 1
-- Cannot insert duplicate key row in object 'dbo.T_Constraint_VW' with unique index 'T_Constraint_VW_UK'. The duplicate key value is (2).
INSERT INTO T VALUES (4, 4)
-- Msg 2601, Level 14, State 1, Line 1
-- Cannot insert duplicate key row in object 'dbo.T_Constraint_VW' with unique index 'T_Constraint_VW_UK'. The duplicate key value is (4).
INSERT INTO T VALUES (5, 6)
-- works