I have a table structured as such:
PrimaryKey int set as PK
SomeForeignKey int set as FK... linked to some other table's PK
SomeVarChar varchar
SomeDate datetime
When I right-click on Properties of my PK, I noticed that Identity is set to False, Identity Seed is set to 0 and Identity Icrement is set to 0.
However, I am unable to modify these properties. How can I change these values?
Here is a screen shot.
You change the table, not the constraint. Management Studio will take care of the other stuff for you (note that it has to drop the table and re-create it, so if the table is large, be prepared to grab a coffee and hurry up and wait).
Right-click the table in Object Explorer and choose Design
Right-click the column you want to be the identity and choose Properties
In the properties pane, under "Identity Column", choose the correct column:
Click the Save icon (or Ctrl+S):
Note that you may also have to un-check the option Tools > Designers > Table and Database Designers > Prevent saving changes that require table re-creation.
Normally I would suggest making changes to schema using DDL instead of the hokey and bug-ridden GUI, but this is one rare case where the GUI actually requires less work than typing the requisite commands would. Changing the IDENTITY property is one thing DDL just hasn't caught up with, and the nonsense it has to do to work around it is ridiculous (in this case I added a new column, and scripted out the change required to make that the identity column instead - and you can't even see all the nonsense here, because of the non-resizable dialog):
Here is the actual script (not something you probably want to run very often, never mind come up with on your own):
/* To prevent any potential data loss issues, you should review this script in detail
before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_foo
(
ID int NOT NULL,
[Foo INT] int NOT NULL IDENTITY (1, 1)
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_foo SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_foo OFF
GO
IF EXISTS(SELECT * FROM dbo.foo) EXEC('INSERT INTO dbo.Tmp_foo (ID)
SELECT ID FROM dbo.foo WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.foo
GO
EXECUTE sp_rename N'dbo.Tmp_foo', N'foo', 'OBJECT'
GO
ALTER TABLE dbo.foo ADD CONSTRAINT
PK__foo__3214EC274CF5691D PRIMARY KEY CLUSTERED
(ID) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
If you want to change this property in Management Studio, you right click on the table, select Design, and then select the primary key column, and see its properties in the bottom, where you can open the "Identity Specification" section. There, you can edit the setting "IsIdentity". Then save the changes.
Related
How to change the Data Type of column "Price" from int to float
I tried to change the data type directly from table to float but it didn't work.
I even deleted the column and added another column with same name but it's not working.
Got the following error:
USE [GarageDB]
GO
UPDATE [dbo].[Product]
SET [TypeId] = <TypeId, int,>
,[Name] = <Name, varchar(100),>
,[Price] = <Price, int,>
,[Description] = <Description, text,>
,[Image] = <Image, varchar(150),>
WHERE <Search Conditions,,>
GO
What command should I use to change the data type of price from int to float?
I want it into decimal number. Ex: 40.99
In development, we just enable this... Of course, in production you would not typically want to do this, since it can result in data loss or loss of metadata and other errors, especially if the system is under load.
Here are the steps:
Tools menu > Options.
In the navigation pane, click Designers.
Uncheck the prevent saving changes that require the table re-creation checkbox.
Click OK.
You could also look into the ALTER TABLE command if you want a more direct approach, or if you need to do this in production, but make sure you know what you're doing as this command is potentially destructive.
If you want to use the GUI, this is the way.
Use SQL, not the GUI. For example:
ALTER TABLE dbo.YourTable ALTER COLUMN YourColumn decimal(10,2) NULL;
Note that if you have constraints that reference the column, you will need to DROP these, and then recreate them.
I need to turn ANSI PADDING from ON to OFF on an existing field of a table without creating a new table. Is there a way to do this through an ALTER command?
Thanks!
No, there is no way to do this with just ALTER. Like the identity property, collation and some other bits, whether a column applies ANSI padding or not is not something that can be altered after the fact.
You can still do it without creating a new table altogether, but not without creating a new column:
BEGIN TRANSACTION;
SET ANSI_PADDING OFF;
ALTER TABLE T ADD C_badpad CHAR(16) NULL;
EXEC('UPDATE T SET C_badpad = C;')
EXEC sp_rename 'T.C', 'C_old';
EXEC sp_rename 'T.C_badpad', 'C';
EXEC('ALTER TABLE T DROP COLUMN C_old;')
ROLLBACK; -- COMMIT;
But, if you value your sanity, don't do this. Rewrite the client code that wants this so it does its own proper trimming, because the very ability to have ANSI_PADDING set to OFF is deprecated, with good reason. Almost everything expects ANSI_PADDING to be ON these days, so having it OFF for a specific column is likely to break clients that aren't expecting it. Even if you think you're solving a problem now, you're likely going to end up with bigger problems in the future.
ANSI_PADDING is only there as a compatibility tweak for very old software that just doesn't know any better (and will likely want the whole database to be created with ANSI_PADDING = OFF). Don't use it in new development, and certainly don't use it for just one column.
I'm trying to create and increment by one some values to put into an already existing (but empty) column. I'm currently using the identity function, but I wouldn't mind using a custom made function. Right now, SSMS is saying there's incorrect syntax near IDENTITY. Could anybody help me fix this syntax?
ALTER Table anthemID IDENTITY(1,1)
First, you can't make a column identity after the fact: it has to be set that way at creation time.
Second, I'm not quite sure what you mean by "increment the value of an already existing column by one." You can only increment the value of rows within a column--perform a DML (Data Modification Language) query. The script you suggested above is a DDL (Data Definition Language) query that actually modifies the structure of the table, affecting the entire column--all rows.
If you just want to increment all the rows by 1, you'd do this:
UPDATE dbo.YourTable SET anthemID = anthemID + 1;
On the other hand, if you want the anthemID column to acquire the identity property so that new inserts to the table receive unique, autoincrementing values, you can do that with some juggling:
Back up your database and confirm it is a good backup.
Script out your table including all constraints.
Drop all constraints on your table or other tables that involve anthemID.
ALTER TABLE dbo.YourTable DROP CONSTRAINT PK_YourTable -- if part of PK
ALTER TABLE dbo.AnotherTable DROP CONSTRAINT FK_AnotherTable_anthemID -- FKs
Rename your table
EXEC sp_rename 'dbo.YourTable', 'YourTableTemp';
Modify the script you generated above to make anthemID identity (add in identity(1,1) after int);
Run the modified script to create a new table with the same name as the original.
Insert the data from the old table to the new one:
SET IDENTITY_INSERT dbo.YourTable ON;
INSERT dbo.YourTable (anthemID, AnotherColumn, RestOfColumns)
SELECT anthemID, AnotherColumn, RestOfColumns
FROM dbo.YourTableTemp;
SET IDENTITY_INSERT dbo.YourTable OFF;
Re-add all constraints that were dropped.
Drop the original, renamed table after confirming you don't need the data any more.
You may be able to do this from SSMS's GUI table designer, and it will take care of moving the data over for you. However, this has bitten some people in the past and if you don't have a good database backup, well, don't do it because you might encounter some regret in the process.
UPDATE
Now that I know the column is blank, it's even easier.
ALTER TABLE dbo.YourTable DROP COLUMN anthemID;
ALTER TABLE dbo.YourTable ADD anthemID int identity(1,1) NOT NULL;
This does have the drawback of moving the column to the end of the table. If that's a problem, you can follow much the same procedure as I outlined above (to fix things yourself, or alternately use the designer in SQL Server Management Studio).
I recommend in the strongest terms possible that you use an identity column and do not try to create your own means of making new rows get an incremented value.
For emphasis, I'll quote #marc_s's comment above:
The SELECT MAX(ID)+1 approach is highly unsafe in a concurrent environment - in a system under some load, you will get duplicates. Don't do this yourself - don't try to reinvent the wheel - use the proper mechanisms (here: IDENTITY) that your database gives you and let the database handle all the nitty-gritty details!
I wholeheartedly agree with him.
Before changes I had a persisted computed field which used Checksum function and index to use it.
alter table Softs add TitleHash AS (CHECKSUM([Title])) PERSISTED;
All were fine until we found that Checksum produces poor hash and duplicates might occur. So we decided to use Hashbytes.
I tried both with binary result and char result
alter table Softs add TitleHashCBin AS (CONVERT(BINARY(16),hashbytes('MD4',[Title]))) PERSISTED;
or
alter table Softs add TitleHashCChar AS (CONVERT(CHAR(32),hashbytes('MD4',[Title]),2)) PERSISTED;
Unfortunately we found that a simple SELECT request does not use index for new field.
SELECT id FROM Softs WHERE TitleHashCBin = 0xC29939F6149FD65100A66AF5FD958D8B
It scans primary index which is build on Id column.
After that we created binary column, copied data from TitleHashCBin and also created index for new column.
alter table Softs add TitleHashBin AS Binary(16)
And used similar select statement.
SELECT id FROM Softs WHERE TitleHashBin = 0xC29939F6149FD65100A66AF5FD958D8B
And this one uses index by TitleHashBin field.
What a hell is going with calculated fields. Can somebody explain what I'm doing wrong or is it a bug?
P.S. Sql Server 2008 10.0.3798
Edit
I just removed char column from the table to investigate what does SSMS generate. It generated actually the same as you described.
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
--DROP INDEXes here
--GO
ALTER TABLE dbo.Softs DROP COLUMN TitleHashCChar, TitleHashChar
GO
ALTER TABLE dbo.Softs SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
So I think we can assume that table options are correct.
After that I repeated select statements but with the same execution plan as before...
Edit
I resolved to task using simple binary fields and Insert/Update triggers to update them. Works like a charm. But it is still unclear why it has so strange behavior?..
Make sure your set options are correct, from BOL Link
SET Option Requirements
The ANSI_NULLS connection-level option must be set to ON when the CREATE TABLE or ALTER TABLE statement that defines the computed column is executed. The OBJECTPROPERTY function reports whether the option is on through the IsAnsiNullsOn property.
The connection on which the index is created, and all connections trying INSERT, UPDATE, or DELETE statements that will change values in the index, must have six SET options set to ON and one option set to OFF. The optimizer ignores an index on a computed column for any SELECT statement executed by a connection that does not have these same option settings.
The NUMERIC_ROUNDABORT option must be set to OFF, and the following options must be set to ON:
ANSI_NULLS
ANSI_PADDING
ANSI_WARNINGS
ARITHABORT
CONCAT_NULL_YIELDS_NULL
QUOTED_IDENTIFIER
Setting ANSI_WARNINGS to ON implicitly sets ARITHABORT to ON when the database compatibility level is set to 90. If the database compatibility level is set to 80 or earlier, the ARITHABORT option must explicitly be set to ON. For more information, see SET Options That Affect Results.
Just recently, SQL 2005 Management Studio started throwing syntax errors while trying to save changes to tables. These are tables being made in Design view, not as TSQL scripts.
'Build_Group' table
- Unable to create index 'PK_Build_Group'.
Incorrect syntax near ','.
Based on the error, it seems that the recreation of the clustered index on the primary key is failing, but this is an entirely automated process by SQL, its own generated TSQL behind the scenes, and the change to the table was not to the key field, ie the clustered index that generated just fine before is now failing.
This install of SQL is more than a year old and I work in it every day with no problem. Nothing has changed to the environment that I know of.
Anyone seen this before ?
== EDIT TO ORIGINAL ==============================
Below is the Generated Change Script
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.Build_Group ADD CONSTRAINT
PK_Build_Group PRIMARY KEY CLUSTERED
(
build_group_pk
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
The syntax error is occurring on the WITH line. If I rem out the two ALLOW options, it will run.
here is my suggestion:
1) reboot your PC
2) enter SSMS
3) right click the table and select "refresh"
4) open the table, right click and select "Design", and make a change
5) click on the "generate change script" toolbar icon (or from the menu - "Table Designer" then "generate change script")
6) store a copy of this change script
7) attempt to save the table
8) if you still get an error, edit your question to include the change script
I have the same problem using SSMS v10 (SQL 2008) against an SQL Server 2000 server/database. If I create a table with a few columns in the designer and also set a primary key using the designer, then save and try Script table as > Create to > New query window it generates SQL with incorrect syntax.
Msg 170, Level 15, State 1, Line 58
Line 58: Incorrect syntax near '('.
Deleting the two ALLOW options didn't work for me, but removing the entire WITH clause does fix the issue. Regardless of whether this is the right thing to do, why does SMSS generate bad scripts?