Как сделать автоинкремент varchar - PullRequest
5 голосов
/ 15 января 2011

Могу ли я создать первичный ключ, например, "c0001, c0002" и для поставщика "s0001, s0002" в одной таблице?

Ответы [ 11 ]

19 голосов
/ 15 января 2011
  1. Идея дизайна базы данных состоит в том, чтобы хранить каждый элемент данных отдельно. И каждый элемент имеет свой тип данных, ограничения и правила. Это c0002 не одно поле, а два. То же самое с XXXnnn или чем-то еще. Это неверно, и это сильно ограничит вашу способность использовать данные, а также использовать функции и возможности базы данных.

    Разбейте его на два отдельных элемента данных:
    column_1 CHAR(1)<br> column_2 INTEGER

    Затем установите AUTOINCREMENT на column_2

    И да, ваш Первичный ключ может быть (column_1, column_2), поэтому вы не потеряли значение, которое c0002 имеет для вас.

  2. Никогда не размещайте поставщиков и клиентов (что бы ни означали "c" и "s") в одной таблице. Если вы сделаете это, у вас не будет таблицы базы данных, у вас будет плоский файл. И различные проблемы и ограничения, связанные с этим.

    Это значит, нормализовать данные. Вы получите:

    • одна таблица для Person или Organisation, содержащая общие данные (Name, Address ...)
    • одна таблица для Customer, содержащая специфичные для клиента данные (CreditLimit ...)
    • одна таблица для Supplier, содержащая данные, специфичные для поставщика (PaymentTerms ...)
    • нет двусмысленных или необязательных столбцов, поэтому нет значений Null
    • нет ограничений на использование или функции SQL
      ,

    А когда вам нужно добавить столбцы, вы делаете это только там, где это требуется, не затрагивая все другие иска плоского файла. Сфера действия ограничена областью изменения.

9 голосов
/ 15 января 2011

Мой подход будет:

  • создайте столбец ID INT IDENTITY и используйте его в качестве первичного ключа (он уникален, узок, статичен - идеален)

  • если вам действительно нужен идентификатор с буквой или чем-то, создайте вычисляемый столбец на основе этого ID INT IDENTITY

Попробуйте что-то вроде этого:

CREATE TABLE dbo.Demo(ID INT IDENTITY PRIMARY KEY,
                      IDwithChar AS 'C' + RIGHT('000000' + CAST(ID AS VARCHAR(10)), 6) PERSISTED
                     )

Эта таблица будет содержать ID значений из 1, 2, 3, 4........, а IDwithChar будет выглядеть как C000001, C000002, ....., C000042 и т. Д.

С этим вы получаете лучшее из обоих миров:

  • правильный, идеально подходящий первичный ключ (и ключ кластеризации) на вашей таблице, идеально подходящий для ссылок из других таблиц

  • ваш символьный идентификатор, правильно определенный, вычисленный, всегда актуальный .....

3 голосов
/ 31 января 2017

Да, на самом деле это два разных вопроса, 1. Можем ли мы использовать столбец varchar в качестве столбца с автоинкрементом с уникальными значениями, такими как числа бросков в классе

ANS: Да, вы можете сделать это правильно, используя приведенный ниже фрагмент кода без указания значения ID и P_ID,

CREATE TABLE dbo.TestDemo
  (ID INT IDENTITY(786,1) NOT NULL PRIMARY KEY CLUSTERED,
   P_ID AS 'LFQ' + RIGHT('00000' + CAST(ID AS VARCHAR(5)), 5) PERSISTED,
   Name varchar(50),
   PhoneNumber varchar(50)
  )
  1. Два разных приращения в одном и том же столбце,

ОТВЕТ: Нет, вы не можете использовать это в одной таблице.

2 голосов
/ 15 января 2011

Я предпочитаю искусственные первичные ключи.Ваши требования также могут быть реализованы как уникальный индекс для вычисляемого столбца:

CREATE TABLE [dbo].[AutoInc](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [Range] [varchar](50) NOT NULL,
  [Descriptor]  AS ([range]+CONVERT([varchar],[id],(0))) PERSISTED,
  CONSTRAINT [PK_AutoInc] PRIMARY KEY ([ID] ASC)
)

GO

CREATE UNIQUE INDEX [UK_AutoInc] ON [dbo].[AutoInc] 
(
    [Descriptor] ASC
)

GO
1 голос
/ 15 января 2011

Присвоение значения предметной области первичному ключу - это практика, которая идет далеко назад, во времена, когда программисты Cobol и динозавры шли вместе по земле. Практика сохраняется до наших дней чаще всего в устаревших системах инвентаризации. Это в основном способ удаления одного или нескольких столбцов данных и встраивания данных из исключенных столбцов в значение PK.

Если вы хотите сохранить клиента и поставщика в одной и той же таблице, просто сделайте это и используйте автоинкрементное целое число PK и добавьте столбец с именем ContactType или что-то подобное, которое может содержать значения «S» и «C» или что-либо , Вам не нужен составной первичный ключ.

Вы всегда можете объединить эти столбцы (PK и ContactType) в отчетах, например, C12345, S20000, (приведение целого числа к строке), если вы хотите исключить столбец для экономии места (т. Е. На распечатанной или отображаемой странице), и все в вашей организации понимают соглашение, согласно которому стоит первый символ идентификатора объекта для кода ContactType.

Этот подход будет использовать возможности автоинкрементации, встроенные в ядро ​​базы данных, упростить ваш PK и связанный с ним код на уровне данных и сделает вашу программу и базу данных более надежными.

0 голосов
/ 09 августа 2018

Вы можете попробовать ниже код:

SET @variable1 = SUBSTR((SELECT id FROM user WHERE id = (SELECT MAX(id) FROM user)), 5, 7)+1;
SET @variable2 = CONCAT("LHPL", @variable1);
INSERT INTO `user`(`id`, `name`) VALUES (@variable2,"Jeet");
  • 1-я строка, чтобы получить последний вставленный идентификатор, удалив четыре символа, затем увеличьте одно значение и установите значение переменной1
  • 2-я строка для создания полного идентификатора с четырехзначным префиксом и присвоения переменной2
  • вставить новое значение с сгенерированным новым первичным ключом = variable2
  • в этой таблице должно быть не менее одной информации для работы над SQL
0 голосов
/ 27 апреля 2018

Мы можем добавить Default Constraint Function с определением таблицы для достижения этого.

Первое создание таблицы -

create table temp_so (prikey varchar(100) primary key, name varchar(100))
go

Второй создать новый User Defined Function -

create function dbo.fn_AutoIncrementPriKey_so ()
returns varchar(100)
as
begin
    declare @prikey varchar(100)
    set @prikey = (select top (1) left(prikey,2) + cast(cast(stuff(prikey,1,2,'') as int)+1 as varchar(100)) from temp_so order by prikey desc)
    return isnull(@prikey, 'SB3000')
end
go

Третье определение таблицы для добавления default constraint -

alter table temp_so
add constraint df_temp_prikey
default dbo.[fn_AutoIncrementPriKey_so]() for prikey
go

Четвертая insert новая строка в таблице без указания значения для primary column -

insert into temp_so (name) values ('Rohit')
go 4

Проверьте данные в таблице сейчас -

select * from temp_so

ВЫХОД -

prikey  name
SB3000  Rohit
SB3001  Rohit
SB3002  Rohit
SB3003  Rohit
0 голосов
/ 27 мая 2017
INSERT INTO Yourtable (yourvarcharID) 
  values('yourvarcharPrefix'+(
      SELECT CAST((SELECT CAST((
      SELECT Substring((
      SELECT MAX(yourvarcharID) FROM [Yourtable ]),3,6)) AS int)+1) 
        AS VARCHAR(20))))

Здесь столбец varchar имеет префикс «RX», затем следует «1003 *», поэтому я выбрал substring после этого префикса и увеличил только это число.

0 голосов
/ 15 января 2011

Сначала позвольте нам заявить, что вы не можете сделать это напрямую.Если вы попробуете

create table dbo.t1 (
id varchar(10) identity,
);

, в сообщении об ошибке будет указано, какие типы данных поддерживаются напрямую.

Msg 2749, Уровень 16, Состояние 2, Строка 1 Die 'id'-Identitätsspalte muss vom Datentyp' int ',' bigint ',' smallint ',' tinyint 'oder' decimal 'bzw.'numeric' mit 0 Dezimalstellen sein und darf keine NULL-Werte zulassen.

Кстати: я пытался найти эту информацию в BOL или в MSDN и потерпел неудачу.

Теперь, зная, что вы не можете сделать это прямым способом, лучше следовать предложению @marc_s, используя вычисляемые столбцы.

0 голосов
/ 15 января 2011

Вместо того, чтобы делать 'c0001, c0002' для клиентов и 's0001, s0002' для поставщиков в одной таблице, действуйте следующим образом:

  • Создать одно поле с автоматическим приращением "id"Тип данных" int (10) unsigned ".
  • Создайте другое поле" type "типа данных" enum ('c', 's') "(где c = Клиент, s = Поставщик).

Как указывало "@PerformanceDBA", вы можете затем создать индекс первичного ключа для двух полей "id" & "type", чтобы ваше требование было выполнено с использованием правильной методологии.,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...