1

尝试根据传递的参数插入多行。

试过这个,它只重复了一次:

ALTER PROCEDURE [dbo].[ActivateCertificates]

    @Count              int,
    @CertificateNumber  int,
    @Buyer              VarChar(50)


AS
Declare @x int
Declare @InitialCharacter   Char(1)
SET @InitialCharacter='C'
Declare @Last3      Char(3)
SET @Last3='867'

    while @x <= @Count 
begin
    /* CREATE THE CERTIFICATE NUMBER */
    set @CertificateNumber = @CertificateNumber +1
    /* insert into certificates  cert number and who sold to. */
    INSERT into Certificates (CertificateNumber,Buyer) 
    VALUES (@InitialCharacter + ltrim(rtrim(cast(@CertificateNumber as char))) + @Last3, @Buyer) 
end 
set @x =@x + 1


GO
4

2 回答 2

1

您的变量在BEGIN/END块外递增。另外,我建议您最初将变量设置为 0,以避免在该内存位置存储任何潜在的垃圾数据。

于 2013-06-14T22:26:54.297 回答
0

为了使用基于集合的查询而不是循环来实现您的目标(顺便说一句,StackOverflow 上有很多这样的示例),您必须有一个计数(数字)表或使用子查询或递归 CTE 即时创建它.

CREATE TABLE tally (id INT NOT NULL PRIMARY KEY);

将其填充到 100000(Celko 风格

INSERT INTO tally (id) 
SELECT a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + 1 as N
  FROM (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) a
      , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) b
      , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) c
      , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) d
      , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) e
ORDER BY N;

现在您的存储过程归结为一条语句

CREATE PROCEDURE ActivateCertificates
  @Count              INT,
  @CertificateNumber  INT,
  @Buyer              VARCHAR(50)
AS
INSERT INTO Certificates (CertificateNumber, Buyer) 
SELECT 'C' + CAST(q.number + t.id AS VARCHAR(12)) + '867', q.buyer 
  FROM
( 
  SELECT @CertificateNumber number, @Buyer buyer
) q, tally t
WHERE t.id <= @Count;

这是SQLFiddle演示

现在,如果您生成的证书数量相对较少(< 32768),那么您可以使用递归 CTE 来构建数字序列(并且不需要持久的计数表)

CREATE PROCEDURE ActivateCertificates
  @Count              INT,
  @CertificateNumber  INT,
  @Buyer              VARCHAR(50)
AS
WITH tally AS (
  SELECT 1 id
  UNION ALL
  SELECT id + 1 FROM tally WHERE id < @Count
)
INSERT INTO Certificates (CertificateNumber, Buyer) 
SELECT 'C' + CAST(q.number + t.id AS VARCHAR(12)) + '867', q.buyer 
  FROM
( 
  SELECT @CertificateNumber number, @Buyer buyer
) q, tally t OPTION (MAXRECURSION 32767);

这是该案例的SQLFiddle演示

于 2013-06-16T04:28:43.930 回答