I have been developing one application to register the student's details for admission. In SQL Server, I have to save the records and generate one reference number. That registration should be unique.
At the present, I am taking max number from the table and insert into the table. Duplicate records inserted in milliseconds. How to avoid duplicate records in the reference number column? In my application, 1000 concurrent users register at the same time.
Ex. IRCTC Ticket booking. They are generating PNR without duplicate.
There is no reason why a regular auto increment primary key column should not suffice here:
CREATE TABLE students (
id INT NOT NULL IDENTITY PRIMARY KEY,
...
)
SQL Server would never generate a duplicate value for the above id column. If, for some reason, this would not meet your expectations, then you could consider using a UUID for each student record, using the NEWID() function.
Related
I'm working on a SQL database, and I have the following table:
Workout Routine
id serial PRIMARY KEY,
user_id integer
REFERENCES users (id)
ON DELETE CASCADE
NOT NULL,
name varchar(255) NOT NULL,
active boolean DEFAULT TRUE,
UNIQUE(user_id, name)
Currently, the combination of user_id, and name are supposed to be unique, meaning that a user cannot have two workout routines with the same name. However, this is not quite what I want.
Instead, I would want the combination user_id and name to be unique only in cases where active = true. In other words, a user should be able to have multiple workouts with the same name that are inactive, but should not be allowed to have duplicates that are active.
Is there a way to enforce this in this table?
A partial index can be used for this:
CREATE UNIQUE INDEX ON table_name (user_id, name) WHERE active;
The fiddle
You can use a partial index to achieve this. The index will only be used for queries that include the active column, and will only be used for queries that include the active column with a value of true. This means that queries that do not include the active column will not use the index, and queries that include the active column with a value of false will not use the index.
CREATE UNIQUE INDEX workout_routine_user_id_name_active
ON workout_routine (user_id, name)
WHERE active = true;
I'm an Oracle guy - but perhaps I can be of help here. Yes, you can model what you want in several ways.
One way is to create two tables, one historical, the other current. The historical would have no unique index other than the PK on the surrogate key ID, whereas the current would also have a unique index on user_id and name.
The second way, using a single table, is to add a nullable date field that represents the closed/inactive date. NULL means active, non-NULL (a date value) would mean inactive. Create a unique index (not a PK) on user_id,name,inactive_date. If SQL Server is like Oracle and allows NULL values in a unique constraint but not multiple NULL values, that will enforce that there can be only one instance of a name for a user_id that is current (having a NULL inactive_date), but allows there to be many inactive rows since they would all have different date values.
If SQL Server acts differently than Oracle then check out the "NULLS NOT DISTINCT" option.
I have created a table that will create a ID for customers that is a number starting at 101 and increasing by 1 for each customer. So the first customer will have the ID 101, the second will have 102 and so on. In addition to the ID I have other information namely First and Last names. I have also added a constraint that applies to the first and last name columns that will force the entries to be made up by letters.
Here is the SQL statement:
CREATE TABLE tblcustomer
(
CUST_ID INT NOT NULL IDENTITY(101,1) PRIMARY KEY,
FIRST_NAME VARCHAR(15) NOT NULL,
LAST_NAME VARCHAR(15) NOT NULL,
CONSTRAINT firstlet CHECK (FIRST_NAME NOT LIKE '%[^a-zA-Z]%'
AND LAST_NAME NOT LIKE '%[^a-zA-Z]%')
);
This works as intended except for one small issue. When I try to insert say a number for the first name, the constraint will work and not enter anything to the table. But then when I insert the first and last name correctly, it will add the information to the table but the CUST_ID will skip a number.
Example Inserts:
insert into tblcustomer(FIRST_NAME,LAST_NAME) values ('Bob','Smith');
insert into tblcustomer(FIRST_NAME,LAST_NAME) values ('Greg','Johns');
insert into tblcustomer(FIRST_NAME,LAST_NAME) values ('Todd','123');
insert into tblcustomer(FIRST_NAME,LAST_NAME) values ('Todd','Howe');
Output:
CUST_ID FIRST_NAME LAST_NAME
-----------------------------
101 Bob Smith
102 Greg Johns
104 Todd Howe
So where the CUST_ID shows 104 should actually be 103.
Skipping a number is fine. It's normal behavior in any database, and you shouldn't expect the numbers to remain consecutive forever. If this bothers you, try using a GUID key instead.
An identity column value gets updated the moment it receives a request. Hence even when the insertion fails due to validation constraints, the number is already taken.
If your business case requires exact sequence of ID being generated (preserving order of insertion), you will need to set the value of ID column manually using identity_insert as on, then increment the max ID. Do note that if multiple such request come, there can be race conditions where 2 records with same ID are tried to be inserted, and second fails due to primary की constraint.
If all you want with the primary key being unique automatically, use a Guid field. That will save you from all this effort.
Simple example, you are using sequence for an auto increment. With begin transaction inserting a record into the table. But any how you just rollback that transaction.
so next insert will skip that transaction, because it will not hold or place the lock on the sequence.
Sequence will just raise the identity, its job done, If you want to use it or not. and as best practice its good and healthy for performance purpose.
Database is Postgresql. For an simplified example I will insert measurement data in various tables. Example DDL for one example table looks like this:
CREATE TABLE
measurement
(
id_meas BIGINT NOT NULL,
...
PRIMARY KEY (id_meas)
);
The process of inserting data currently works like this:
Select max id value from table
Increment id value
Insert next data row using incremented id value
This works as long as there is only one client inserting data. But what if there are > 1 client's inserting so that two clients may select 567 as max id value and both increment this to 568 as next id value to insert. In that case the second client executing the insert command will receive an duplicate key error. Is there a way to prevent those errors other than re-executing the insertion process after an error occurred?
You are looking for a serial column:
CREATE TABLE measurement (
id_meas bigserial primary key,
...
);
bigserial is a bigint that auto-increments (see here). You can also just use serial if an int is big enough.
This puts the database in charge of incrementing the value, rather than the application. You are guaranteed that race conditions will not result in the same value in different records. It is possible that gaps in the value will appear under some circumstances.
I have application using JPA and Postgresql. I have exisiting database, and I need to add a field to exsiting table, which should be auto incremented. I need to provide that values for new record will be always greater than the previous record. Also I need to add values for the record that exists...
I've thought that id field will suite my requirements, but it doesn't... I have a primary key which is generated by sequence in PostgreSQL, but values aren't always greater. Application is used by many concurrent clients.
The following SQL will create a sequence, alter the table and use the sequence to generate and set the default value in the new column:
CREATE SEQUENCE myid_seq;
ALTER TABLE mytable ADD COLUMN myid bigint NOT NULL DEFAULT nextval('myid_seq');
So the number will be set by the database when a new row is inserted. (i.e. no problem if you have many concurrent insert).
Existing rows will be updated with a unique value for myid.
You can add a unicity constraint if you need it.
I am newbie to MSSQL Server and don't have any knowledge about it.
i have below question.
I have added nine records with same value as show per below image in SQL Server 2005.
i Have not given any primary key to Table.
Now when i selecting one record or multiple record and hit the delete key it does not delete the records from table instead it gives me error.
You need to add a primary key to uniquely identify each record, otherwise the SQL server has no way of distinguishing the records, and therefore no way of knowing which one to delete, causing an error.
That's because you don't have any primary key and server doesn't know which row to remove. Clear the table ( DELETE * FROM dbo.Patient ) and create new Id column as a primary key.
In MSSQL you need to have a primary key for the table. This will uniquely identify each row of that particular table.
For example in Oracle you don't need this as there you can use ROWID (meaning every row from every table has a unique ID in the database). Once you know this ID you Oracle knows for sure from which table it is.
So now you can add a primary key to the table and you can make it be auto-increment - ensuring uniqueness.