使用while循环增加自定义ID字段

时间:2018-12-02 06:55:44

标签: sql sql-server loops tsql id

我正在尝试生成一个ID,其格式为000H-Y,其中数字从000到019。我的代码仅生成从010H-Y到019H-Y。我的while循环是否存在格式问题或错误?

if exists(select * from sysobjects where name = 'Bikes')
    drop table Bikes
go

create table Bikes
(
    BikeID nchar(6) not null,
        constraint pk_Bikes_BikeID primary key(BikeID),
        constraint chk_Bikes_BikeID check(BikeID like ('0[0-19][HYS]-[AP]')),
    StableDate date not null
        default getdate()
)
go

if exists(select * from sysobjects where name = 'PopulateBikes')
    drop procedure PopulateBikes
go

create procedure PopulateBikes
@outcome as nvarchar(12) output
as
declare @min as int = 0, 
@max as int = 19
    if @@ERROR <> 0
        return -1
    while(@min < @max)
    begin
        set @min+=1
        insert into Bikes(BikeID)
        values ('0'+ cast(@min as nvarchar(2))+ 'H-A')

    end
go

declare @retVal as int = 0
exec @retVal = PopulateBikes 'SPName:OK'
if @retVal = -1
    print 'Error encountered!'
go

select * from Bikes go

2 个答案:

答案 0 :(得分:1)

您可以使用递归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约束是wron,应该像

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;

Demo


更新

从您提供的用于创建表的代码中,我假设您错了,因为我认为这些字符是可能的值,因此您可以将表创建为

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不允许

答案 1 :(得分:0)

解决方案:

考虑如何为API Version: certmanager.k8s.io/v1alpha1 Kind: Certificate Metadata: ... Spec: Acme: Config: Dns 01: Provider: dns Domains: test.<myhost>.com Common Name: test.<myhost>.com Dns Names: test.<myhost>.com Issuer Ref: Kind: ClusterIssuer Name: letsencrypt-prod-dns Secret Name: letsencrypt-tls Events: <none> 生成值。

此行:

Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.0", GitCommit:"0ed33881dc4355495f623c6f22e7dd0b7632b7c0", GitTreeState:"archive", BuildDate:"2018-10-12T16:56:06Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.6", GitCommit:"a21fdbd78dde8f5447f5f6c331f7eb6f80bd684e", GitTreeState:"clean", BuildDate:"2018-07-26T10:04:08Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}

您将生成从BikeIDselect ('0'+ cast(@min as nvarchar(2))+ 'H-Y') 的值。

尝试一下:

01H-Y

还需要将检查约束更改为:

019H-Y