Convert VARBINARY to Int or BigInt - sql-server

My question is very simple and I understand that few Old days DB design is not good as we espect these days.
My legacy table does not have Primary key to perform Delta load. Hence, I'm trying to use Hashing concept to create Unique key. As "HASHBYTES" return VarBinary and I can not use VarBinary type as
primay key (not sure about this)
Ref URL on MSDN:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/94231bb4-ccab-4626-a9fb-325264bb883f/can-varbinary700-column-be-used-as-primary-key?forum=transactsql
hence, I'm converting this to INT or BigInt. The problem is it gives both negative as well as positive value(due to the range).
My Question is:
How can I convert VARBINARY(100) type to integer or BigInt (+ve value) and Set this as a Primary key in one of my table?
Edit Note:
I tried to use VARBINARY as Primary key for Delta load in SSIS Lookup task. I got the error:
"Violation of PRIMARY KEY constraint 'PK__DMIN__607056C02FB7E7DE'. Cannot insert duplicate key in object 'dbo.DMIN_'. The duplicate key value is (0x00001195764c40525bcaf6baa922091696cd8886).".
However, when I checked for duplicate key from the table. Table does not have duplicate key. Then why this error is showing up?
Please note that, the 1st time of SSIS execution worked fine. However, it shows error during 2nd execution [during "lookup match output"].
Please help. Thanks.

In projects I've worked on before we've always used GUIDs as our primary keys, utilising the unique identifier type in SQL Server.
The main problem with this however, is that using a uniqueidentifier type as your clustered index can degrade the performance of your database after some time, so recently we've taken the following approach (based on this article):
Create column: guid, uniqueidentifier, nonnull, default value newsequentialid(), PK
Create column: id, bigint, nonnull, identity(1,1)
Create a non clustered index on the guid column, unique
Create a clustered index on the id column, unique
That way when you insert into this new table, you don't have to worry about the keys or identities.
If you need some form of reference between the old database and the new and you CAN modify the structure of the old database, you can create a uniqueidentifier column in that (or char(36) if it doesn't support uniqueidentifier) and assign a guid to each of those and THEN create an additional uniqueidentifier column in the new database so you have that reference and insert that value into it. If that makes sense.

Related

Adding a primary key column to an existing table in SQL Server?

I need to add a new column and make it the primary key in SQL Server; the table in question does not yet have a unique key column.
Here is the sample table http://www.sqlfiddle.com/#!18/8a161/1/0
My goal is simply to have a column ID and insert values from 1 to 1160 (total number of records in this table) and make that the primary key. Also is there a way to automatically add the numbers from 1-1160 without adding each record one by one since there are 1000+ rows in this table?
Thank you!
Simply alter the table and add the column with the appropriate characteristics.
alter table x add id smallint identity(1,1) not null primary key;
Thrown together quickly and you probably should get in the habit of naming constraints. fiddle. I will note that you may or may not want to use an identity column - think carefully about your actual goal and how you want to continue using this table after the alteration.

Why is Entity Framework ignoring existing GUIDs on insert?

I have a table defined in Sql Server with a GUID primary key and a default of newsequentialid():
CREATE TABLE [dbo].[mything](
[id] [uniqueidentifier] NOT NULL,
[foo] [varchar][32] NULL,
CONSTRAINT [PK_mything] PRIMARY KEY CLUSTERED
(
[id] ASC
)
)
GO
ALTER TABLE [dbo].[mything]
ADD CONSTRAINT [DF_mything_id]
DEFAULT (newsequentialid()) FOR [id]
GO
And when I add an entity with the guid primary key already set, it ends up as a record in the database with a new guid primary key.
var anEntity = new mything
{
id = "17870C25-FC04-EB11-80E9-000C29F38B54",
foo = "Some stuff",
}
dbContext.mythings.Add(anEntity);
dbContext.SaveChanges();
EF seems to ignore the guid that was provided in the record and writes the record with a new Guid.
What I would expect is that the record provided had a null guid, it would be populated with a new guid, and if it was not null it would be used unchanged. But that's not what I'm seeing happen.
I'm seeing duplicate records, with different GUIDs, instead of primary key violation exceptions, because the GUIDs I'm providing in my EF entities are being ignored.
Why could this be happening?
Please tell me this isn't by design!
===
OK, this does seem to be by design.
First, this isn't in SQL server. If I try to insert a record with the id field set, it inserts, or fails with a primary key failure if there is already a record with that id. It only creates a new GUID for the id field if the provided id field is null.
But in EF, the value in the id field is ignored, and a new GUID is generated every time.
It was suggested to me that EF was behaving this way so as to follow the same pattern as when using autoincrement keys. And that does seem to be the case.
In SQL Server, if you try to provide a value to an autoincrement key field on an insert, you get an error:
Cannot insert explicit value for identity column in table
But in EF, the value you provide is ignored, and a new value is generated.
So in this respect, Entity Framework is consistent. Consistently wrong, but consistent.
First step I'd look at to narrow this down is to capture a Profiler/Extended Event trace at the database to see exactly what EF is sending to the database.
Your expectation of the database behaviour is correct - so I'd want to understand where it is breaking down first

How do you add a unique primary key field automatically in SQL Server?

I am using SQL Server 2012 and need to add a column with a unique primary key. I am about to load several hundred thousand records BULK and just discovered repetition in the field I was going to use. Have seen SEQUENCE and GUID. Need some guidance on the best choice and how to go about setting this up so that the key field is populated during the bulk load.
When you create your table in which you want to insert information create an IDENTITY column. That will serve as an auto-populating column with a unique number for each record.
Here is a link that might help you.
If you have already created your table just change this query to what suits to your table name and run it in order to add the new column you requested.
ALTER TABLE mytable
ADD COLUMN unique_id IDENTITY (1,1)
Just a slight update on what’s already posted that includes details for adding primary key constraint
alter table database.schema.table_t
add ID_column int identity(1,1)
primary key (ID_column)
If you already set the primary key on this table just go and remove it before you execute this statement.

Auto increment primary key in SQL Server Management Studio 2012

How do I auto increment the primary key in a SQL Server database table? I've had a look through the forum but can't see how to do this.
I've looked at the properties but can't see an option. I saw an answer where you go to the Identity specification property and set it to yes and set the Identity increment to 1, but that section is grayed out and I can't change the no to yes.
There must be a simple way to do this but I can't find it.
Make sure that the Key column's datatype is int and then setting identity manually, as image shows
Or just run this code
-- ID is the name of the [to be] identity column
ALTER TABLE [yourTable] DROP COLUMN ID
ALTER TABLE [yourTable] ADD ID INT IDENTITY(1,1)
the code will run, if ID is not the only column in the table
image reference fifo's
When you're creating the table, you can create an IDENTITY column as follows:
CREATE TABLE (
ID_column INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
...
);
The IDENTITY property will auto-increment the column up from number 1. (Note that the data type of the column has to be an integer.) If you want to add this to an existing column, use an ALTER TABLE command.
Edit:
Tested a bit, and I can't find a way to change the Identity properties via the Column Properties window for various tables. I guess if you want to make a column an identity column, you HAVE to use an ALTER TABLE command.
You have to expand the Identity section to expose increment and seed.
Edit: I assumed that you'd have an integer datatype, not char(10). Which is reasonable I'd say and valid when I posted this answer
Expand your database, expand your table right click on your table and select design from dropdown.
Now go Column properties below of it scroll down and find Identity Specification, expand it and you will find Is Identity make it Yes. Now choose Identity Increment right below of it give the value you want to increment in it.
CREATE TABLE Persons (
Personid int IDENTITY(1,1) PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
The MS SQL Server uses the IDENTITY keyword to perform an auto-increment feature.
In the example above, the starting value for IDENTITY is 1, and it will increment by 1 for each new record.
Tip: To specify that the "Personid" column should start at value 10 and increment by 5, change it to IDENTITY(10,5).
To insert a new record into the "Persons" table, we will NOT have to specify a value for the "Personid" column (a unique value will be added automatically):
Perhaps I'm missing something but why doesn't this work with the SEQUENCE object? Is this not what you're looking for?
Example:
CREATE SCHEMA blah.
GO
CREATE SEQUENCE blah.blahsequence
START WITH 1
INCREMENT BY 1
NO CYCLE;
CREATE TABLE blah.de_blah_blah
(numbers bigint PRIMARY KEY NOT NULL
......etc
When referencing the squence in say an INSERT command just use:
NEXT VALUE FOR blah.blahsequence
More information and options for SEQUENCE
When you're using Data Type: int you can select the row which you want to get autoincremented and go to the column properties tag. There you can set the identity to 'yes'. The starting value for autoincrement can also be edited there. Hope I could help ;)
I had this issue where I had already created the table and could not change it without dropping the table so what I did was:
(Not sure when they implemented this but had it in SQL 2016)
Right click on the table in the Object Explorer:
Script Table as > DROP And CREATE To > New Query Editor Window
Then do the edit to the script said by Josien; scroll to the bottom where the CREATE TABLE is, find your Primary Key and append IDENTITY(1,1) to the end before the comma. Run script.
The DROP and CREATE script was also helpful for me because of this issue. (Which the generated script handles.)
You can use the keyword IDENTITY as the data type to the column along with PRIMARY KEY constraint when creating the table.
ex:
StudentNumber IDENTITY(1,1) PRIMARY KEY
In here the first '1' means the starting value and the second '1' is the incrementing value.
If the table is already populated it is not possible to change a column to IDENTITY column or convert it to non IDENTITY column. You would need to export all the data out then you can change column type to IDENTITY or vice versa and then import data back.
I know it is painful process but I believe there is no alternative except for using sequence as mentioned in this post.
Be carefull like if you want the ID elements to be contigius or not. As SQLSERVER ID can jump by 1000 .
Examle: before restart ID=11
after restart , you insert new row in the table, then the id will be 1012.
You could do the following: New Table Creation:
-- create new table with Column ID which is Primary Key and Auto Increment --
CREATE TABLE titles(
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY, --Primary Key with Auto-Increment --
keyword VARCHAR(260),
status VARCHAR(10),
);
If you Table Already exists and need to make the changes to ID column to be auto-increment and Primary key, then see below:
ALTER TABLE table DROP COLUMN id; // drop the existing ID in the table
ALTER TABLE table ADD id int IDENTITY(1, 1) NOT NULL; // add new column ID with auto-increment
ALTER TABLE table ADD CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id); // make it primary key

Creating New Foreign Key (SQL Server)

I am having a bit of trouble creating a foreign key in my DB. Here is a paraphrased model of what my tables look like:
NOTE
* (PK) NOTE_ID BIGINT
* TITLE VARCHAR(200)
* DATE DATETIME
* SERIES_ID BIGINT
SERIES
* (PK) SERIES_ID BIGINT
* TITLE VARCHAR(200)
* DESCR VARCHAR(1000)
I am trying to create a "has a" relationship between NOTE and SERIES by SERIES_ID. I thought that setting up a foreign key between the two tables by SERIES_ID would be the solution, but when I attempt to create it I get the following error:
ERROR: There are no primary or candidate keys in the referenced table 'dbo.SERIES' that match the referencing column list in the
foreign key 'FK_SERIES_NOTE'. Could not create constraint
I'm using the web database manager that comes with the GoDaddy SQL Server I set up, so I'm not sure what the underlying query it's trying to use or I would post it.
At the end of the day, this is all to create a relationship so that the NHibernate mappings for my Note object will contain a one-to-one relationship to a Series object. I may not even be trying to tackle this the correct way with the foreign key, though.
Am I going about this the correct way?
EDIT:
In an attempt to pair down the tables to a more simple example, I removed what I thought to be several non-critical columns. However, I ended up leaving a field that was actually a part of the composite primary key on the series table. So, because I was trying to assign the foreign key to only one part of the composite key, it was not allowing me to do so.
In the end, I have taken another look at the structure of my table and found that I don't actually need the other piece of the composite key - and after removing, the assignment of the foreign key works great now.
If you can, you may try running the following statement in a query analyzer and see the resulting error message (I guess #Damien_The_Unbeliever is right ) :
ALTER TABLE NOTE ADD CONSTRAINT FK_SERIES_NOTE
FOREIGN KEY (SERIES_ID) REFERENCES SERIES(SERIES_ID)
--ON DELETE CASCADE
-- uncomment the preceding line if you want a delete on a serie
-- to automatically delete all notes on this serie
Hope this will help

Resources