SQL Server seems to go out of its way to remove a COLLATE
restriction on a nvarchar
column if the collation is the DB default. My DB default is SQL_Latin1_General_CP1_CI_AS
. If I create a table thus:
CREATE TABLE [dbo].[UserActive](
[Id] [uniqueidentifier] NOT NULL,
[DateCreated] [datetimeoffset](7) NOT NULL,
[Username] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Password] [nvarchar](max) NULL,
[Email] [nvarchar](254) NOT NULL,
CONSTRAINT [PK_UserActive] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
... then ask SQL Server Management Studio to script the table as a CREATE
statement, I get the following:
CREATE TABLE [dbo].[UserActive](
[Id] [uniqueidentifier] NOT NULL,
[DateCreated] [datetimeoffset](7) NOT NULL,
[Username] [nvarchar](50) NOT NULL,
[Password] [nvarchar](max) NULL,
[Email] [nvarchar](254) NOT NULL,
CONSTRAINT [PK_UserActive] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Is there any way I can retain the explicit COLLATE
even if it's the DB default? I want to be explicit about the fact that any unique index I add on the Username
column will have that case-insensitive collation, even if the DB default is changed for some reason. It's nice and self-documenting, which is lost without the explicit collation as part of the table definition.
varbinary
column. I also can't imagine why it would be null.nvarchar(max)
field. Surely you wouldn't store a binary hash in a Unicode text field? Also the name is a bit telltale, you would normally call itPasswordHash
or similar to make it more obvious.PasswordHasher
simply returns a string containing the salted hash.max
.