create table in sybase with auto_increment primary key,after truncate the table the primary key is not zero - primary-key

I used below SQL to create a table with auto_increment primary key,but found after truncate the table the primary key is not reset to zero ,because after insert data to it the primary key continues to increase from the last time truncate. I believe the primary will be too large to cause the overflow. how to solve it?
CREATE TABLE dbo.BM_SM_ERR
(
SMCWBM int identity, -- primary key
SMCWDM varchar(10) NOT NULL,
PRIMARY KEY CLUSTERED (SMCWBM)
)
with identity_gap=1
sybase version Adaptive Server Enterprise 15.7

The identity does not reset after a delete, truncate table or shutdown. You have to reset it manually if you want it with the sp_chgattribute procedure:
1> insert into BM_SM_ERR(SMCWDM) values ('x')
2> go
(1 row affected)
1> insert into BM_SM_ERR(SMCWDM) values ('y')
2> go
(1 row affected)
1> insert into BM_SM_ERR(SMCWDM) values ('z')
2> go
(1 row affected)
1> select * from BM_SM_ERR
2> go
SMCWBM SMCWDM
----------- ----------
1 x
2 y
3 z
(3 rows affected)
1> truncate table BM_SM_ERR
2> go
1> insert into BM_SM_ERR(SMCWDM) values ('v')
2> go
(1 row affected)
1> select * from BM_SM_ERR
2> go
SMCWBM SMCWDM
----------- ----------
4 v
(1 row affected)
1> truncate table BM_SM_ERR
2> go
1> exec sp_chgattribute BM_SM_ERR, 'identity_burn_max', 0, '0'
2> go
DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
'identity_burn_max' attribute of object 'BM_SM_ERR' changed to 0.
(return status = 0)
1> insert into BM_SM_ERR(SMCWDM) values ('q')
2> go
(1 row affected)
1> select * from BM_SM_ERR
2> go
SMCWBM SMCWDM
----------- ----------
1 q
(1 row affected)

Related

Turn ON OFF IDENTITY INSERT equivalent in Oracle

I have the following ProductCategory dimension in my DWH design to not lose data :
ProductSK ProductID ProductName BI_StartDate BI_EndDate
-1 -1 Undefined 99991231 99991231
The ProductSK is an identity column.
I am used to use Turn ON/OFF Identity Insert in SQL Server, how can I do the same in Oracle?
This is my dimension DDL :
CREATE TABLE ProductCategory (
ProductSK NUMBER GENERATED ALWAYS AS IDENTITY,
ProductID NUMBER NOT NULL,
ProductName VARCHAR2(100) NOT NULL,
BI_StartDate NUMBER NOT NULL,
BI_EndDate NUMBER NOT NULL,
);
The equivalent in SQL Server :
SET IDENTITY_INSERT sometableWithIdentity ON;
SET IDENTITY_INSERT sometableWithIdentity OFF;
In SQL Server
set identity on Allows explicit values to be inserted into the
identity column of a table.
Basically you turn on and off the possibility to insert into an identity column which is defined as a sequence of numbers based on an interval.
In Oracle, you have the option to use IDENTITY GENERATED BY DEFAULT
GENERATED BY DEFAULT: Oracle generates a value for the identity column
if you provide no value. If you provide a value, Oracle will insert
that value into the identity column. For this option, Oracle will
issue an error if you insert a NULL value into the identity column.
Example
SQL> create table x ( c1 number generated by default as identity start with 1 increment by 1 , c2 number ) ;
Table created.
SQL> insert into x ( c2 ) values ( 1 ) ;
1 row created.
SQL> insert into x ( c1, c2 ) values ( 2, 2 ) ;
1 row created.
SQL> select * from x ;
C1 C2
---------- ----------
1 1
2 2
This option allows you to either insert or not ( which is kind of turning on / off ) in a sense very similar to the SQL Server turn on/off.

Check for constraints before deletion

I have a very similar question to this one here, but it was asked 12 years ago and I'm sure things have changed since then.
Basically, I would like to be able to check for foreign key constraints before deleting. I don't want to just do a try/catch or rollback, because I'd like to present the information on the front end to the user to tell them what they need to do in order to be able to delete the item they're trying to remove.
I would like it to be able to continue to work going forward, if new constraints are added.
In a perfect world, I would like to be able to get back a list of primary keys from the rows in the other tables that are dependent on the row being deleted.
Well, why would you complicate things for users? As far as I understood, you'd want to inform them that the can't delete a master record until they delete detail records first. If that's so, why wouldn't you let the database do it for you (them, that is)? Hint: on delete cascade.
This is what you have now (a very simplified example):
SQL> create table tmaster
2 (id_mas number constraint pk_mas primary key);
Table created.
SQL> create table tdetail
2 (id_det number constraint pk_det primary key,
3 id_mas number constraint fk_det_mas references tmaster (id_mas));
Table created.
SQL> insert all
2 into tmaster values (1)
3 into tmaster values (2)
4 --
5 into tdetail values (100, 1) -- references master 1
6 into tdetail values (101, 1) -- references master 1
7 into tdetail values (200, 2) -- references master 2
8 select * from dual;
5 rows created.
Deleting master whose details exist won't work:
SQL> delete from tmaster where id_mas = 1;
delete from tmaster where id_mas = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_DET_MAS) violated - child record
found
SQL>
You'd have to
SQL> delete from tdetail where id_mas = 1;
2 rows deleted.
SQL> delete from tmaster where id_mas = 1;
1 row deleted.
SQL>
But, as I said, let the database work. Note line #4 in create table tdetail:
SQL> create table tmaster
2 (id_mas number constraint pk_mas primary key);
Table created.
SQL> create table tdetail
2 (id_det number constraint pk_det primary key,
3 id_mas number constraint fk_det_mas references tmaster (id_mas)
4 on delete cascade); --> this
Table created.
SQL> insert all
2 into tmaster values (1)
3 into tmaster values (2)
4 --
5 into tdetail values (100, 1) -- references master 1
6 into tdetail values (101, 1) -- references master 1
7 into tdetail values (200, 2) -- references master 2
8 select * from dual;
5 rows created.
OK, let's delete master (and master only):
SQL> delete from tmaster where id_mas = 1;
1 row deleted.
Whoa, it works! I don't have to do anything about it:
SQL> select * from tmaster;
ID_MAS
----------
2
SQL> select * from tdetail;
ID_DET ID_MAS
---------- ----------
200 2
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.

Cannot insert duplicate key in object 'dbo.Countries'. The duplicate key value is (1)

I am trying to copy data from one table to another and i get the error Cannot insert duplicate key in object 'dbo.Countries'. The duplicate key value is (1). I understand what this means, but how do i remove it?
This is my sql server query:
SET IDENTITY_INSERT [dbo].[countries] ON
----Create TestTable
CREATE TABLE TestTable (FirstName VARCHAR(100), LastName VARCHAR(100))
----INSERT INTO TestTable using SELECT
INSERT INTO [dbo].[Countries] (countryID, countryName)
SELECT countryId, countryName
FROM [dbo].[Sheet1]
----Verify that Data in TestTable
SELECT countryID, countryName
FROM [dbo].[Countries]
----Clean Up Database
DROP TABLE TestTable
SET IDENTITY_INSERT [dbo].[countries] OFF
The error message is:
Msg 2627, Level 14, State 1, Line 6
Violation of PRIMARY KEY constraint 'PK_dbo.Countries'. Cannot insert duplicate key in object 'dbo.Countries'. The duplicate key value is (1).
The statement has been terminated.
(26 row(s) affected)
Try this...
INSERT INTO [dbo].[Countries] (countryID, countryName)
SELECT countryId, countryName
FROM [dbo].Sheet1
WHERE NOT EXISTS (SELECT 1
FROM [dbo].[Countries]
WHERE Sheet1.countryId = [Countries].countryID)
And since you are inserting into an Identity field I would also execute the following lines of code once I am done inserting data
DBCC CHECKIDENT ('[dbo].[Countries]', RESEED, 0)
DBCC CHECKIDENT ('[dbo].[Countries]', RESEED)
GO
This will reseed the identity value to next highest available identity value, otherwise you might get duplicate errors when Identity column tries to generate an identity value that you have already explicitly inserted into identity column.

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