Create an auto incrementing alpha numeric primary key in SQL Server Management Studio - sql

I have a Student table in SQL Server database which is as follows:
CREATE TABLE [dbo].[Student] (
[Id] INT NOT NULL IDENTITY,
[Name] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
I want the Id property to be alpha-numeric and auto-increment itself for a new entry. I want Id to be S<number> and then S<number+1> and so on.
I tried to solve this problem as a two-step process:
(i) I first tried to make the Id an auto-incrementing property by doing this:
Then I pressed "Update":
And then I updated again and it led me to this table:
CREATE TABLE [dbo].[Student] (
[Id] INT NOT NULL IDENTITY,
[Name] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
I do not think Id is an auto-incrementing value yet. How can I make it both auto-incrementing and alpha-numeric from the following interface:

It seems that you don't really want a fully auto-incrementing alphanumeric column A001,A002...B001, you just want a regular integer column with a prefix of S. For this you can use a simple computed column
ALTER TABLE Student
ADD MyId AS CONCAT('S', Id);

Related

Postgres Alter ID Start With?

I have an PostgreSQL SQL for creating table. Sometimes i need to TRUNCATE this table. but after this ID primary key, don't start with initial or desired starting value. my question is that how can i restart primary key (id) to desired starting value.
CREATE TABLE IF NOT EXISTS "binance_rules" (
"id" int8 GENERATED ALWAYS AS IDENTITY (START WITH 100100100000),
"THPARS_DATI" timestamp DEFAULT NULL,
"THPARS_LIST" varchar(10) check ("THPARS_LIST" in ('yes','no')) DEFAULT NULL,
"THPARS_PRIO" INT DEFAULT NULL,
PRIMARY KEY ("id")
);
any sql example will be appreciated.
You can alter the table column to restart the counting:
alter table binance_rules alter column id restart;
Here is a db<>fiddle.

How can I add a column and populate it with a number after sorting a table?

I have this table:
CREATE TABLE [dbo].[Phrase]
(
[PhraseId] [uniqueidentifier] NOT NULL,
[PhraseNum] [int] NULL
[English] [nvarchar](250) NOT NULL,
PRIMARY KEY CLUSTERED ([PhraseId] ASC)
) ON [PRIMARY]
GO
What I would like to do is to sort the table and populate the column PhraseNum with a number where the first row of the sorted table is 1 and each row after that has a value one larger than the one before.
Alan, if data in PhraseNum is not important (as I could see in your post), you can drop that column and add as an identity column
ALTER TABLE Phrase drop column PhraseNum ;
ALTER TABLE Phrase Add PhraseNum int identity(1,1) not null;
The numbering of PhraseNum will be done by the cluster index sorting criteria, so by PhraseId
But it is safe to test on a test database first
In SQL Server, you would do this with an identity column:
CREATE TABLE [dbo].[Phrase](
[PhraseId] [uniqueidentifier] NOT NULL PRIMARY KEY,
[PhraseNum] int identity(1, 1) NOT NULL
[English] [nvarchar](250) NOT NULL
);
Having a unique identify as a (clustered) primary key is a really, really bad idea. Why? New values are not ordered. That means that the data has to be re-ordered for each insert -- causing fragmentation.
You should use the PhraseNum column as the primary key.

Lookup tables localization

On an project where I use localization I have the following tables:
create table dbo.Posts
(
Id int identity not null primary key clustered (Id),
Created datetime not null,
);
create table dbo.PostsLocalized
(
Id int identity not null primary key clustered (Id),
PostId int not null,
LanguageId int not null,
PostTypeId int not null,
[Text] nvarchar (max) not null,
Title nvarchar (120) not null,
constraint UQ_PostsLocalized_PostId_LanguageId unique (PostId, LanguageId)
);
create table dbo.PostTypes
(
Id int identity not null primary key clustered (Id),
Name nvarchar (max) not null
);
So I am localizing the Posts with a PostsLocalized table but not the PostTypes table.
The PostTypes table is basically a lookup table as others I have in my database.
Do you think I should localize the lookup tables, for example, PostTypes?
I would add a new table named PostTypesLocalized with the localized names.
The same for other lookup tables like Genders, Countries, ...
Or should I localize the lookup tables only in the application?
UPDATE
To clarify:
All localized versions of one post has the same PostType.
I need to display the PostTypes in the UI that is why I need to translate them.
So I tried a new approach following the answer of #dasblinkenlight:
create table dbo.Posts
(
Id int identity not null primary key clustered (Id), -- The id of the localized post
Created datetime not null,
PostId int not null, -- The id of the post
PostTypeId int not null
LanguageId int not null,
[Text] nvarchar (max) not null,
Title nvarchar (120) not null,
constraint UQ_PostsLocalized_PostId_LanguageId unique (PostId, LanguageId)
);
create table dbo.PostTypes
(
Id int identity not null primary key clustered (Id), -- PostType localized id
PostTypeId int not null, -- The id of the post type
Name nvarchar (max) not null
);
Considering (1) then Posts > PostTypeId should be related to PostTypes > PostTypeId.
But how can I do this?
The answer depends on the usage of the Name field of the PostTypes table:
If all uses of that field come from code and/or non-localizable scripts that you may have, localization is not necessary
If the Name makes it to the end-user's view, you should localize the table.
If you need to localize PostTypes, a separate PostTypesLocalized table, in addition to the PostTypes table with locale-independent name, sounds like an appropriate solution.
You should consider the placement of the PostTypeId field, too. Would all localizations with the same PostId refer to the same PostTypeId, or would some of them be different? In case that all localizations of the same Post refer to the same PostType, the field should belong to the Posts table, instead of PostLocalized.
should I localize the lookup tables only in the application?
Adding localization to your database counts as localization of your application. It is a good solution when you contemplate multiple applications using the same database structure.

SQL Server - Create an identifying relationship

I'm currently designing a database to be implemented in SQL Server. I created the following tables without problem:
CREATE TABLE [Client] (
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
[IsEnabled] BIT NOT NULL DEFAULT 1,
CONSTRAINT PK_TCASystem PRIMARY KEY CLUSTERED (
ClientId
)
);
CREATE TABLE [Configuration] (
[ConfigId] INT NOT NULL,
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
CONSTRAINT PK_Configuration PRIMARY KEY CLUSTERED (
ConfigId, ClientId
),
CONSTRAINT "FK_SystemConfiguration" FOREIGN KEY
(
ClientId
) REFERENCES [Client] (
ClientId
)
);
However, when I tried to add this one:
CREATE TABLE [Mail] (
[MailId] INT NOT NULL,
[ConfigId] INT NOT NULL,
[Recipient] VARCHAR(500) NOT NULL,
[Sender] VARCHAR(50) NOT NULL,
[Subject] VARCHAR(250) NOT NULL,
[Message] TEXT NULL,
CONSTRAINT PK_Mail PRIMARY KEY CLUSTERED (
MailId, ConfigId
),
CONSTRAINT "FK_ConfigurationMail" FOREIGN KEY
(
ConfigId
) REFERENCES [Configuration] (
ConfigId
)
);
I got an error saying that There are no primary or candidate keys in the referenced table 'Configuration' that match the referencing column list in the foreign key 'FK_ConfigurationMail'. I believe this is because the constraint is trying to reference ConfigId, only one half of the composite key, and for this to work I'd need to reference the ClientId too, is that correct?
But my problem is that I first did the design for this database in MYSQL Workbench, and there I indicated that Configuration and Mail, as well as Client and Configuration, have a 1:n identifying relationship (because a Mail instance cannot be created if there isn't a Configuration instance first, and at the same time a Configuration instance cannot exist without having being assigned to a Client first), and as such it created the composite keys for Configuration and Mail. You can see a picture of that here.
So my question is, how can I translate this identifying relationship to SQL Server? Or is that not possible?
EDIT: As suggested I will remove the composite keys from the Configuration table, albeit my question still stands: If I have a 1:n identifying relationship where one of the tables involved uses composite keys, how can I display this on SQL Server? Or is such a case never supposed to happen?
2ND EDIT: To anyone who might come across this question, this post is well worth a read. Cleared up all my confusion in the matter.
Foreign key must reference PK (the entire PK, not portion of PK) or unique index. So add this between create table [Configuration] and [Mail].
CREATE UNIQUE NONCLUSTERED INDEX [UX_Configuration] ON [Configuration]
(
[ConfigId] ASC
)
Check out at sql fiddle for the whole working script:
http://www.sqlfiddle.com/#!3/8877f

Multilingual database design

I'm trying to design a database schema for a multilingual application. I have so far found a sample from this address. http://fczaja.blogspot.com/2010/08/multilanguage-database-design.html
But I haven't understood this sample. Should I insert Id value on app_product first? How can I know that these values are true for ProductId on app_product_translation?
CREATE TABLE ref_language (
Code Char(2)NOT NULL,
Name Varchar(20) NOT NULL,
PRIMARY KEY (Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_product_translation (
ProductId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Description Text NOT NULL,
FOREIGN KEY (ProductId) REFERENCES app_product(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);
It looks like SQLServer code, proceeding on that assumption.
Yes you must insert the app_product first. But you cannot insert the id column's value. It is assigned automatically, because it is an identity column.
Two things you can check out...to find the identity column's value after inserting.
The OUTPUT clause of the INSERT statement. It can return any values that are inserted, not just the identity column.
The ##Identity variable. (by far more traditional and popular)
declare #lastid int
insert into x values (1,2,3)
set #lastid = ##identity
insert into y values (#lastid, a, b, c)