I have a table created like this originally:
CREATE TABLE dbo.XX (
YY int DEFAULT(NULL)
)
If you do this, and then script the table later on, you will get the following code, plus a randomly named default constraint:
CREATE TABLE [dbo].XX([YY] [int] NULL)
GO
ALTER TABLE [dbo].XX ADD DEFAULT (NULL) FOR [YY]
GO
Now is there any real point in specifying DEFAULT (NULL) on a column instead of just leaving it as [YY] [int] NULL in the first place?
There is no need to add a DEFAULT(NULL) to nullable columns.
If data is not supplied to such columns, they will have a NULL.
The only benefit I see is the one Larry Lustig has posted in his comment to the question - it documents the fact that you have not forgotten to add a default to the nullable column.
None that I can think of.
From a programming point of view NULL is the implicit default anyway without needing to (implicitly) create an actual default constraint in sys.objects.
Both of the following will end up inserting NULL without the default constraint.
INSERT INTO [dbo].XX([YY]) VALUES (DEFAULT)
INSERT INTO [dbo].XX([YY]) DEFAULT VALUES
I don't subscribe to the view in the comments that it documents you didn't "forget" to add a default constraint. Nullable columns rarely have default constraints in my experience so this would just add a load of unneeded clutter.
The more important thing to include is the column nullability - as below - so it is clear to future readers that the column is nullable and so it doesn't depend on ANSI_NULL_DFLT session options what you actually end up with.
CREATE TABLE dbo.XX (
YY int NULL
)
Related
Is NULL or NOT NULL necessary for Adding a column in SQL Server? (If you are going to run UPDATE statement after)
I tested without it locally, and it seems to work fine both in SQL and on the website; but I wanted to make sure before running release/production.
I looked up some other articles, including microsoft website. Some show it with, some without. SO articles say some benefits of NULL, like if you have information that may be added later. But assuming I am going to run UPDATE to add values after, will it matter?
I am guessing it does not matter from what I've tested and read.
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
UPDATE [dbo].[MyTable] SET NewColumn ='Math' WHERE ID = 1
UPDATE [dbo].[MyTable] SET NewColumn ='Science' WHERE ID = 2
You can skip it, and by default the column will be created as NULL. However it is more legible if you indicate it explicitly.
Keep in mind that if your table already has data, you CANNOT add the column as NOT NULL. For this, you should firstly add the column as NULL, then UPDATE the values with non-null valid data and then alter column to NOT NULL.
Edit: Assuming the default behavior of the sql server when adding columns.
You don't have to write it, when you skip it column will be created as 'NULL'.
Following statements are equal:
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150) NULL;
If you want to add a column and DB engine should guarantee you that this new column will be always populated you can add a NOT NULL column with a default value.
Other option will be to change the column to NOT NULL after the update.
I'd make sure you have something declarative. And if you are setting as "not null," be sure you have a default value or use can suffer LOTS of data loss if data previously exists. It makes me nervous because this an ALTER vs a CREATE.
I have a table with the following columns:
ID Name
1 test1
2 test2
Now I added new column IsConfirmed. And this column contain null in all rows.
ID Name IsConfirmed
1 test1 null
2 test2 null
How can I set false to IsConfirmed column to all rows in the table using T-SQL?
Thanks
UPDATE YourTableName
SET IsConfirmed=0
WHERE isConfirmed is Null
#JohnFx's suggestion is a perfect solution to the problem in hand. However, you might want to be interested to know how to prevent this kind of situation from appearing and, at the same time, possibly to solve other potential issues.
In particular, the fact that you wanted to replace the NULLs with 0s immediately might indicate that you never wanted the column to hold NULLs in the first place. If that is actually the case, you should have added the column with the NOT NULL specifier:
ALTER TABLE tablename
ADD IsConfirmed bit NOT NULL
Of course, if you try to add a NOT NULL column to a non-empty table, you'll get an error if you do not also provide a default value for the column, because SQL Server would attempt to add the column with NULLs, which, according to the definition, are not allowed. So, add NOT NULL columns like this instead:
ALTER TABLE tablename
ADD IsConfirmed bit NOT NULL
CONSTRAINT DF_tablename_IsConfirmed DEFAULT (0)
The CONSTRAINT DF_tablename_IsConfirmed part is optional, you can leave just DEAFULT (0), but I would still recommend you to give explicit names to all your constraints, including the defaults, because that way it would be easier for you to drop/recreate them. And for the same reason (to make your managing the constraints easier), it would be better for you to use fixed patterns in naming the constraints. The pattern in the above statement (DF for DEFAULT, followed by the table name, followed by the column name) is just an example, you could very well come up a different one. But once you have, just be consistent.
I want to store a single row in a configuration table for my application. I would like to enforce that this table can contain only one row.
What is the simplest way to enforce the single row constraint ?
You make sure one of the columns can only contain one value, and then make that the primary key (or apply a uniqueness constraint).
CREATE TABLE T1(
Lock char(1) not null,
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)
I have a number of these tables in various databases, mostly for storing config. It's a lot nicer knowing that, if the config item should be an int, you'll only ever read an int from the DB.
I usually use Damien's approach, which has always worked great for me, but I also add one thing:
CREATE TABLE T1(
Lock char(1) not null DEFAULT 'X',
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)
Adding the "DEFAULT 'X'", you will never have to deal with the Lock column, and won't have to remember which was the lock value when loading the table for the first time.
You may want to rethink this strategy. In similar situations, I've often found it invaluable to leave the old configuration rows lying around for historical information.
To do that, you actually have an extra column creation_date_time (date/time of insertion or update) and an insert or insert/update trigger which will populate it correctly with the current date/time.
Then, in order to get your current configuration, you use something like:
select * from config_table order by creation_date_time desc fetch first row only
(depending on your DBMS flavour).
That way, you still get to maintain the history for recovery purposes (you can institute cleanup procedures if the table gets too big but this is unlikely) and you still get to work with the latest configuration.
You can implement an INSTEAD OF Trigger to enforce this type of business logic within the database.
The trigger can contain logic to check if a record already exists in the table and if so, ROLLBACK the Insert.
Now, taking a step back to look at the bigger picture, I wonder if perhaps there is an alternative and more suitable way for you to store this information, perhaps in a configuration file or environment variable for example?
I know this is very old but instead of thinking BIG sometimes better think small use an identity integer like this:
Create Table TableWhatever
(
keycol int primary key not null identity(1,1)
check(keycol =1),
Col2 varchar(7)
)
This way each time you try to insert another row the check constraint will raise preventing you from inserting any row since the identity p key won't accept any value but 1
Here's a solution I came up with for a lock-type table which can contain only one row, holding a Y or N (an application lock state, for example).
Create the table with one column. I put a check constraint on the one column so that only a Y or N can be put in it. (Or 1 or 0, or whatever)
Insert one row in the table, with the "normal" state (e.g. N means not locked)
Then create an INSERT trigger on the table that only has a SIGNAL (DB2) or RAISERROR (SQL Server) or RAISE_APPLICATION_ERROR (Oracle). This makes it so application code can update the table, but any INSERT fails.
DB2 example:
create table PRICE_LIST_LOCK
(
LOCKED_YN char(1) not null
constraint PRICE_LIST_LOCK_YN_CK check (LOCKED_YN in ('Y', 'N') )
);
--- do this insert when creating the table
insert into PRICE_LIST_LOCK
values ('N');
--- once there is one row in the table, create this trigger
CREATE TRIGGER ONLY_ONE_ROW_IN_PRICE_LIST_LOCK
NO CASCADE
BEFORE INSERT ON PRICE_LIST_LOCK
FOR EACH ROW
SIGNAL SQLSTATE '81000' -- arbitrary user-defined value
SET MESSAGE_TEXT='Only one row is allowed in this table';
Works for me.
I use a bit field for primary key with name IsActive.
So there can be 2 rows at most and and the sql to get the valid row is:
select * from Settings where IsActive = 1
if the table is named Settings.
The easiest way is to define the ID field as a computed column by value 1 (or any number ,....), then consider a unique index for the ID.
CREATE TABLE [dbo].[SingleRowTable](
[ID] AS ((1)),
[Title] [varchar](50) NOT NULL,
CONSTRAINT [IX_SingleRowTable] UNIQUE NONCLUSTERED
(
[ID] ASC
)
) ON [PRIMARY]
You can write a trigger on the insert action on the table. Whenever someone tries to insert a new row in the table, fire away the logic of removing the latest row in the insert trigger code.
Old question but how about using IDENTITY(MAX,1) of a small column type?
CREATE TABLE [dbo].[Config](
[ID] [tinyint] IDENTITY(255,1) NOT NULL,
[Config1] [nvarchar](max) NOT NULL,
[Config2] [nvarchar](max) NOT NULL
IF NOT EXISTS ( select * from table )
BEGIN
///Your insert statement
END
Here we can also make an invisible value which will be the same after first entry in the database.Example:
Student Table:
Id:int
firstname:char
Here in the entry box,we have to specify the same value for id column which will restrict as after first entry other than writing lock bla bla due to primary key constraint thus having only one row forever.
Hope this helps!
Often we need to add a non-nullable column to a table, and it is quite a mission. Using a default constraint as is doesn’t work, so we have to create nullable columns, update them to default values, then make them non-nullable. Is there not an easier way to do this?
Yes, the WITH VALUES modifier to a DEFAULT constraint applies the default value to existing rows, eliminating all the 'hard' work described in the question.
IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id=OBJECT_ID('[caConfig]') AND [Name]='ExportWizardVersion')
ALTER TABLE [caConfig]
ADD
[ExportWizardVersion] varchar(5) not null CONSTRAINT DF_caConfig_ExportWizardVersion DEFAULT '5.8' WITH VALUES,
[ExportPeriodEnd] varchar(10) not null CONSTRAINT DF_caConfig_ExportPeriodEnd DEFAULT 'MonthEnd' WITH VALUES
In SQL Server 2000/2005,
Is it possible to force the default value to be written to already existing rows when adding a new column to a table without using NOT NULL on the new column?
You need two statements. First create the column with not null. Then change the not null constraint to nullable
alter table mytable add mycolumn varchar(10) not null default ('a value')
alter table mytable alter column mycolumn varchar(10) null
I understand your question, but you are saying that for future records, NULL (unknown, indeterminate or whatever your semantics are) is acceptable (but if it is left off in an insert, there will be a default), but that for all the existing data, you are going to go ahead and assign it the default.
I would have to look hard at this situation and ask why you are even going to allow NULLs in future records at all - given none of the historical records will have it, and there is a default in place for future records.
I doubt it.
http://msdn.microsoft.com/en-us/library/ms190273(SQL.90).aspx
The approach recommended by Microsoft is as follows (taken from the url above)
UPDATE MyTable SET NullCol = N'some_value' WHERE NullCol IS NULL
ALTER TABLE MyTable ALTER COLUMN NullCOl NVARCHAR(20) NOT NULL
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
[**WITH VALUES]**
WITH VALUES can be used to store the default value in the new column for each existing row in the table.
more detail on MSDN link .
https://msdn.microsoft.com/en-in/library/ms190273.aspx