I've already set default value for some of my columns.
CREATE TABLE [dbo].[TEST]
(
[id] [INT] NULL,
[fname] [VARCHAR](50) NULL,
[lname] [VARCHAR](50) NULL,
[default1] [VARCHAR](50) NULL,
[default2] [VARCHAR](50) NULL,
[default3] [VARCHAR](50) NULL
) ON [PRIMARY]
ALTER TABLE [dbo].[TEST]
ADD CONSTRAINT [DF_TEST_job] DEFAULT ('test1') FOR [default1]
ALTER TABLE [dbo].[TEST]
ADD CONSTRAINT [DF_TEST_default2] DEFAULT ('test2') FOR [default2]
ALTER TABLE [dbo].[TEST]
ADD CONSTRAINT [DF_TEST_default3] DEFAULT ('test3') FOR [default3]
Now I'm going to set all columns with default values to null in my INSERT statement sometimes.
I know that if I provide values for the columns in the INSERT, their defaults will be ignored. But I'm looking for a way to set default values off on some inserts.
I know that it might be impossible, but I want to learn it's way (if there is.
I don't fully understand what you're trying to ask here....
If you provide a value for a column - even if it's NULL, in your INSERT statement, then SQL Server will use that provided value and skip any default value defined on the column.
So by just providing NULL, you're basically doing what your title asks: ignore the default value of the column.... the default value of a column is only used if you omit that column entirely from your INSERT statement....
Related
Consider the following table. I use a trigger to add to the table. In the column of converting the number to the string, it fails.
CREATE TABLE [dbo].[tblAIAgent]
(
[AgentCode] [NVARCHAR](10) NOT NULL,
[NationalCode] [BIGINT] NOT NULL
CONSTRAINT [DF_tblAIAgent_NationalCode] DEFAULT ((0)),
[FirstName] [NVARCHAR](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Name] DEFAULT (''),
[LastName] [NVARCHAR](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Family] DEFAULT (''),
[IsActive] [BIT] NOT NULL
CONSTRAINT [DF_tblAIAgent_Active] DEFAULT ((1)),
[Counter] [INT] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblAIAgent]
PRIMARY KEY CLUSTERED
)
ALTER TRIGGER [dbo].[AgentInsert]
ON [dbo].[tblAIAgent]
INSTEAD OF INSERT
AS
BEGIN
DECLARE #AgentCode NVARCHAR(10)
DECLARE #NationalCode BIGINT
DECLARE #FirstName NVARCHAR(50)
DECLARE #LastName NVARCHAR(50)
DECLARE #IsActive BIT
DECLARE #CounterIs INT
SET #CounterIs = ##IDENTITY
SELECT
#AgentCode = AgentCode,
#NationalCode = NationalCode,
#FirstName = FirstName,
#LastName = LastName,
#IsActive = IsActive
FROM inserted
INSERT INTO tblAIAgent (NationalCode, FirstName, LastName, IsActive, AgentCode)
VALUES (#NationalCode, #FirstName, #LastName, #IsActive, 'Agent_' + CAST(#CounterIs AS NVARCHAR(4)))
END
You have a few problems here:
The ##IDENTITY is a system function contains the last identity value that is generated when an INSERT, SELECT INTO, or BULK COPY statement is completed. If the statement did not affect any tables with identity columns, ##IDENTITY returns NULL. If multiple rows are inserted, generating multiple identity values, ##IDENTITY returns the last identity value generated.
In your case, you have an INSTEAD OF INSERT trigger, so there is no INSERT.
This below query is completely wrong and will gives wrong results, it works as expected only if one row inserted, if there is more than 1 row, then those variables will hold just the values of one row, and you will lose the other values of the other rows, cause the pseudo INSERTED may contains 1 or more rows
select #AgentCode=AgentCode,
#NationalCode=NationalCode,
#FirstName=FirstName,
#LastName=LastName,
#IsActive=IsActive
from inserted
Now, looking to your table, you already have an IDENTITY column, so you don't need to a TRIGGER at all, you can just make a computed column as
CREATE TABLE [dbo].[tblAIAgent](
[AgentCode] AS 'Agent_' + CAST([Counter] AS VARCHAR(10)),
[NationalCode] [bigint] NOT NULL
CONSTRAINT [DF_tblAIAgent_NationalCode] DEFAULT ((0)),
[FirstName] [nvarchar](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Name] DEFAULT (''),
[LastName] [nvarchar](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Family] DEFAULT (''),
[IsActive] [bit] NOT NULL
CONSTRAINT [DF_tblAIAgent_Active] DEFAULT ((1)),
[Counter] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblAIAgent] PRIMARY KEY ([Counter])
);
UPDATE:
According to your comment "a computed column can no longer be selected as the PK. I want this column to be placed in other relevant tables as a FK.I wrote the trigger to get the column value instead of the computed column so that I can select the column as the primary key". You are trying to make it a PRIMARY KEY so you can do as
CREATE TABLE T(
Counter INT IDENTITY(1,1) NOT NULL,
OtherCol INT,
Computed AS CONCAT('Agent_', CAST(Counter AS VARCHAR(10))) PERSISTED,
CONSTRAINT PKT PRIMARY KEY(Computed)
);
CREATE TABLE TT(
ReferenceComputedColumn VARCHAR(16) NOT NULL,
OtherColumn INT,
CONSTRAINT FK_ReferencedComputedColumn
FOREIGN KEY(ReferenceComputedColumn)
REFERENCES T(Computed)
)
INSERT INTO T(OtherCol) VALUES
(1), (2), (3);
INSERT INTO TT(ReferenceComputedColumn, OtherColumn) VALUES
('Agent_1', 10),
('Agent_3', 20);
SELECT *
FROM T LEFT JOIN TT
ON T.Computed = TT.ReferenceComputedColumn;
See how it's working.
See also this article Properly Persisted Computed Columns by Paul White.
Try this
SELECT CONVERT(NVARCHAR(255), #AgentCode)
SELECT CAST([PictureId] AS NVARCHAR(4)) From Category
I'd like to modify a table that already has data in the database to have a column reflect default data when it is populated.
Specifically, I'd like to take two columns:
[Created] [datetime] NULL ,
[CreatedBy] [varchar](50) NULL ,
And change them to have defaults like the following:
[Created] [datetime] NULL DEFAULT GETDATE(),
[CreatedBy] [varchar](50) NULL DEFAULT USER_ID(),
Can something like this be accomplished with an alter table statement? I'm using Azure so I can't edit the tables in the GUI.
ALTER TABLE dbo.TableName
ADD CONSTRAINT df_Created DEFAULT (GETDATE()) FOR Created;
ALTER TABLE dbo.TableName
ADD CONSTRAINT df_CreatedBy DEFAULT (USER_ID()) FOR CreatedBy;
Check the documentation for ALTER TABLE...
I have a table with following columns:
[ClauseID] [int] NOT NULL,
[PolicyCategoryID] [int] NOT NULL,
[ExpiryDate] [smalldatetime] NULL,
By now ClauseID and PolicyCategoryID together creates the primary key. But I want ExpiryDate also be a part of primary key. To make the column not null I tried the following but it gives an error:
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL DEFAULT '2079-06-06'
Incorrect syntax near the keyword 'DEFAULT'.
Any idea why? Is it not possible to set a default date like this?
EDIT: By bad! Default key was already set. That must be the reason it gave an error.
try this:
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL
ALTER TABLE tblClauses_PolicyCategory ADD CONSTRAINT
cons_expiryDate DEFAULT '2079-06-06' FOR ExpiryDate
Before execute these lines, please check if exists some rows with ExpiryDate null, if yes, please, update all nullable rows to default value
I think this will help you:
CREATE TABLE tblClauses_PolicyCategory(
[ClauseID] [int] NOT NULL,
[PolicyCategoryID] [int] NOT NULL,
[ExpiryDate] [smalldatetime] NULL)
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL
ALTER TABLE tblClauses_PolicyCategory
ADD CONSTRAINT cons_default DEFAULT '2079-06-06' FOR ExpiryDate
But, before changing ExpireDate to NOT NULL, you must populate values for existing rows in this column, and then change column to NOT NULL.
I want to add 2 new columns to existing table.
One of them should be NOT NULL with default value 0
(filled in the existing rows as well).
I have tried the following syntax:
Alter TABLE dbo.MamConfiguration
add [IsLimitedByNumOfUsers] [bit] NOT NULL,
CONSTRAINT IsLimitedByNumOfUsers_Defualt [IsLimitedByNumOfUsers] DEFAULT 0
[NumOfUsersLimit] [int] NULL
go
But it throws exception. How should I write it?
You can use this:
ALTER TABLE dbo.MamConfiguration
ADD [IsLimitedByNumOfUsers] [BIT] NOT NULL DEFAULT 0,
[NumOfUsersLimit] [INT] NULL
GO
or this:
ALTER TABLE dbo.MamConfiguration
ADD [IsLimitedByNumOfUsers] [BIT] NOT NULL
CONSTRAINT IsLimitedByNumOfUsers_Default DEFAULT 0,
[NumOfUsersLimit] [INT] NULL
go
More: ALTER TABLE
Try this.
ALTER TABLE dbo.MamConfiguration
ADD [IsLimitedByNumOfUsers] [bit] NOT NULL DEFAULT 0,
[NumOfUsersLimit] [int] NULL
To add multiple columns to a table and add default constraint on one of them-
ALTER TABLE dbo.MamConfiguration
ADD [IsLimitedByNumOfUsers] [BIT] CONSTRAINT Def_IsLimitedByNumOfUsers DEFAULT(0) NOT NULL,
[NumOfUsersLimit] [INT] NULL;
GO
Each column is different;
ALTER TABLE
MamConfiguration
ADD
Configuration1 BIT NULL, --this column is nullable
Configuration2 BIT NOT NULL, --this column is not nullable
Configuration3 BIT NOT NULL DEFAULT(0), --this column is not nullable and set default value is 0(zero)
Configuration4 BIT NOT NULL CONSTRAINT DF_Configuration4 DEFAULT(0) --this column is not nullable and set default value is 0(zero) with spesific constraint name
GO
How can I modify this command in order to have an identity column which has five digits integer like 00000 and start from 00001 ?
CREATE TABLE [dbo].[Company]
(
[CompanyId] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](200) NOT NULL
)
An integer does not have any leading 0 by itself. It is a formatting issue to deal with when converting the integer to a string for displaying.
If you really, really need to be able to present such a string right out of SQL, you can do it with a computed column:
CREATE TABLE [dbo].[Company](
[CompanyId] [bigint] IDENTITY(1,1) NOT NULL,
[FormattedCompanyId] AS RIGHT('0000'+ CONVERT(VARCHAR,Num),5),
[Name] nvarchar NOT NULL,
I would never use that solution myself though, formatting doesn't belong in the data store.
You need to add the leading zeros yourself. As a solution you can add an other colomn named say "formatedID" and update it with an "after insert trigger" with the value from the identity column and formatted with the leading zeros you want to.
Example :
CREATE TABLE [dbo].[Company]
(
[CompanyId] [bigint] IDENTITY(1,1) NOT NULL,
[FormattedID] [VARCHAR(20)],
[Name] [nvarchar](200) NOT NULL
)
CREATE TRIGGER ON [dbo].[Company]
FOR INSERT
AS
BEGIN
UPDATE [dbo].[Company]
FROM inserted
SET FormattedID = RIGHT('0000'+ CONVERT(VARCHAR, [dbo].[Company].CompanyId),5)
WHERE dbo.Company.CompanyId = inserted.CompanyId
END