Вы можете использовать рекурсивный CTE
WITH CTE AS
(
SELECT 1 N
UNION ALL
SELECT N + 1
FROM CTE
WHERE N <= 18
)
SELECT CAST(N AS VARCHAR(10)) + 'H-Y'
-- or SELECT '0' + CAST(N AS VARCHAR(10)) + 'H-Y'
FROM CTE;
Нет необходимости использовать WHILE
цикл, и это убивает производительность.
Также ваше ограничение CHECK
нарушено, онодолжно быть похоже на
CONSTRAINT CH_Bikes_BikeID CHECK(BikeID LIKE '0[0-9]H-Y' OR BikeID LIKE '0[0-9][0-9]H-Y')
Итак, вот ваша таблица и запрос на ее заполнение
CREATE TABLE Bikes
(
BikeID VARCHAR(10) NOT NULL,
StableDate DATE NOT NULL DEFAULT GetDate(),
CONSTRAINT CH_Bikes_BikeID CHECK(BikeID LIKE '0[0-9]H-Y' OR BikeID LIKE '0[0-9][0-9]H-Y'),
CONSTRAINT PK_Bikes_BikeID PRIMARY KEY (BikeID)
);
WITH CTE AS
(
SELECT 1 N
UNION ALL
SELECT N + 1
FROM CTE
WHERE N <= 18
)
INSERT INTO Bikes (BikeID)
SELECT '0' + CAST(N AS VARCHAR(10)) + 'H-Y'
FROM CTE;
SELECT *
FROM Bikes
ORDER BY CASE WHEN LEN(BikeID) = 5
THEN 0
ELSE 1
END;
Демо
ОБНОВЛЕНИЕ
Исходя из кода, который вы предоставляете для создания таблицы, я предполагаю, что вы ошибаетесь, потому что я думаю, что эти символы являются возможными значениями, поэтому вы можете создать свою таблицу как
CREATE TABLE Bikes
(
BikeID VARCHAR(10) NOT NULL,
StableDate DATE NOT NULL CONSTRAINT DF_Bikes_StableDate DEFAULT GetDate(),
CONSTRAINT PK_Bikes_BikeID PRIMARY KEY (BikeID),
CONSTRAINT CH_Bikes_BikeID
CHECK(BikeID LIKE '0[0-9][H,Y,S]-[A,P]' OR BikeID LIKE '0[0-9][0-9][H,Y,S]-[A,P]')
);
А вот пример вставки данных в него
WITH CTE AS
(
SELECT 1 N
UNION ALL
SELECT N + 1
FROM CTE
WHERE N <= 18
)
INSERT INTO Bikes (BikeID)
SELECT '0' + CAST(N AS VARCHAR(10)) +
CASE WHEN N % 3 = 1
THEN 'H-A'
ELSE 'Y-P'
END
FROM CTE
ORDER BY N;
SELECT *
FROM Bikes
ORDER BY CASE WHEN LEN(BikeID) = 5
THEN 0
ELSE 1
END;
В строке CHECK(BikeID LIKE '0[0-9][H,Y,S]-[A,P]' OR BikeID LIKE '0[0-9][0-9][H,Y,S]-[A,P]')
проверьте возможные значения, например:
H-A
разрешено Y-P
разрешено S-P
разрешено K-A
запрещено AB-AP
запрещено