How to prevent inserting same Name and NricNo data in a table? - c#

Table
ID | Name | NricNo
1 | Joshua | S1234567A
2 | Joshua | S1234567A
I have a problem for this table. ID is the primary key of this table, but I need to make Name,NricNo to be unique too. It means that table cannot have duplicate value of Name and NricNo. I am doing this in visual studio 2010, help needed . Thanks :)

You can simply alter your table with this query.
ALTER TABLE
ADD CONSTRAINT UNIQUE ();
GO
--Example :
ALTER TABLE MyTable
ADD CONSTRAINT AK_MyTable UNIQUE (Name, NricNo);
GO

This all depends on how you're doing your database interactions. If you're using Entity Framework, as long as you're not creating a new object with the same values, you should be fine.
Either way, you could help yourself by adding an ID field to your data object. If you're using ADO.NET, then check the ID in your save method. If it's not equal to a default value (you should default it to -1 to be safe), then Update, otherwise Insert. Have your saving in a try/catch block because with the UNIQUE constraint on the table, if you try to insert a record that conflicts with the UNIQUE key, then it will throw an error. If you use Entity Framework, most of that would be handled for you, but you should still have the try/catch in your save method.

Related

How to overcome duplicate ID while making transactions?

I have a live web application(.NET), in which I have a facility for making transactions. When more no. of users make any transactions at the same time, duplicate/same transaction ID gets generated for all the users who're all making transactions. Is there any way to avoid creating same ID ? I tried the following solutions but nothing helps.
1.Mutex
2.Table lock(SQL)
3.Generating Transaction ID at the time of inserting into the table.
Use a database to generate the ID. Some possible examples:
SQL Server has an auto increment feature. Oracle has a sequence feature
This will ensure your ID to be unique.
You mention SQL, so you have a database accessible.
Option 1
SQL Server already has an auto-increment feature that is both guaranteed to generate a unique ID and is efficient.
If you want to "add letters to that ID", the simplest solution is to add a separate varchar field that contains those letters, and then format them for display as a single number in your application (either by using a SQL query to do so or string.Format.
ID | IDText Application Display
------------------ -----------------------
1 | MyLabel 1-MyLabel
2 | MyLabel 2-MyLabel
3 | FooBar 3-FooBar
4 | SomeText 4-SomeText
So, in the above, ID would be an auto-increment int field and IDText would be a varchar (or char if you want a fixed length).
As you can see, even if the same string such as "MyLabel" were added at the same time, you would get a different ID to append to it so you in effect have a unique ID.
Option 2
Use a stored procedure to contain the following logic in a single transaction with BEGIN TRANSACTION/END TRANSACTION:
Query for the highest ID
Add 1 to that ID
Create a new record with the new ID
Return that ID
The transaction will guarantee that the number cannot be duplicated. This is less efficient for creating IDs, but more efficient at looking them up than the 2-column approach.

How do I remove unique constraints from tables without hard coding rows?

I am not sure if this is a duplicate or not as there have been several how to's for removing unique constraint. I feel like my question is just different enough to warrant a new question. I have C# code which builds up mysql queries. They end out looking like this:
CREATE table_B like table_A;
I then alter each of the newly created tables to add history details similar to this:
ALTER TABLE table_B
MODIFY COLUMN primary_column int(11) NOT NULL,
DROP KEY `PRIMARY`,
ENGINE = MyISAM,
ADD db_action_type VARCHAR(8) DEFAULT 'insert' FIRST,
ADD revision INT(6) NOT NULL AUTO_INCREMENT AFTER db_action_type,
ADD dt_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER revision,
ADD PRIMARY KEY(revision);
Essentially, I am creating history tables. The trouble I am having is that I cannot add additional rows if the table has a unique constraint. I could do some queries to get a list of unique constraint columns for each table and alter each column individually or as part of this alter table. I am just wondering if there is an easy way which does not require knowing any of the column names. Is there any sort of blanket effect drop unique attribute without caring about specifics?

Migrating from Nhibernate to EF6

I currently have an .NET application that has a SQL Sever database with GUIDs for Primary Keys. We are using NHinbernate for the ORM but want to switch to the latest version of Entity Framework and use Identities(INTs) as our Primary Keys.
Does anyone have any experience or references that will help me in making this transition? Whats the easiest way to migrate the data and implement the new ORM?
If you are choosing to use int keys because of migrating to EF, you actually don't need to change it, and you can keep the existing data, have a look at this.
But if you need to move to int keys for some other reason, it's going to be hard and not that easy. One thing about GUID is it's never duplicate, so you can do something like this,
Export all the GUID's in the current structure (assume table name as key_table) and insert into a table in the new database with auto generated id. Something like this,
--------------------------------------------------
| Id | OldKey |
--------------------------------------------------
| 1| 3d09565d-eb84-4e9c-965c-d530c1be8cf2 |
--------------------------------------------------
| 2| 54a93dbc-7ce8-4c88-a8e0-70cc48a84073 |
--------------------------------------------------
When you do insert, you can fetch the key from this table using a select statement. wherever you need a primary key or a foreign key, something like this,
SET IDENTITY_INSERT User_Table ON;
Insert into User_Table (Id,RoleId,UserName,...)
VALUES (select id from key_table where OldKey = '3d09565d-eb84-4e9c-965c-d530c1be8cf2'),(select id from key_table where OldKey = '54a93dbc-7ce8-4c88-a8e0-70cc48a84073'),'User 1',...);
SET IDENTITY_INSERT User_Table OFF;
this would be the easiest way of doing it, but the id columns would not be linear in your new database with this approach.
This is a breaking change and there is no tools available to help you with this kind of migration. Your best bet would be to stick to NHibernate. If you must change, you'll need to manually write a data migration tool yourself.

Check for duplicate column values (not a key) in SQL

Is there a way for SQL to enforce unique column values, that are not a primary key to another table?
For instance, say I have TblDog which has the fields:
DogId - Primary Key
DogTag - Integer
DogNumber - varchar
The DogTag and DogNumber fields must be unique, but are not linked to any sort of table.
The only way I can think of involves pulling any records that match the DogTag and pulling any records that match the DogNumber before creating or editing (excluding the current record being updated.) This is two calls to the database before even creating/editing the record.
My question is: is there a way to set SQL to enforce these values to be unique, without setting them as a key, or in Entity Frameworks (without excessive calls to the DB)?
I understand that I could group the two calls in one, but I need to be able to inform the user exactly which field has been duplicated (or both).
Edit: The database is SQL Server 2008 R2.
As MilkywayJoe suggests, use unique key constraints in the SQL database. These are checked during inserts + Updates.
ALTER TABLE TblDog ADD CONSTRAINT U_DogTag UNIQUE(DogTag)
AND
ALTER TABLE TblDog ADD CONSTRAINT U_DogNumber UNIQUE(DogNumber)
I'd suggest setting unique constraints/indexes to prevent duplicate entries.
ALTER TABLE TblDog ADD CONSTRAINT U_DogTag UNIQUE(DogTag)
CREATE UNIQUE INDEX idxUniqueDog
ON TblDog (DogTag, DogNUmber)
It doesn't appear as though Entity Framework supports it (yet), but was on the cards. Looks like you are going to need to do this directly in the database using Unique Constraints as mentioned in the comments.

Mapping a single row table without primary key using Nhibernate

I'm working with a legacy table which I cannot change. The database have a settings table which consists of a lot of columns (one for each setting) and only one row:
Columns: Setting1 | Setting2 | Setting3 | etc...
----------+--------------+-----------+-------------
Row1: SomeValue | AnotherValue | LastValue | etc...
Now, this would be all fine if it wasn't for the fact that the table lacks a primary key. Obviously, the original developer didn't think it was necessary, as there's only one single row.
Is there any way of mapping this with Nhibernate? I've already implemented a SQL based solution, but I'd love to have the flexibility and simplicity gained with Nhibernate.
I'm fearing the worst but, any ideas?
You could map a view that adds a dummy PK column:
select 1 as SettingsId, Setting1, etc....
or load the object from a stored procedure.
Well, just pick any setting (column) as the Id. The only inconvenience is that if you need to change the setting that is the PK you'll have to delete and re-insert the row...

Categories