简体   繁体   中英

Insert n rows stored procedure

Trying to insert multiple rows based on a passed parameter.

Tried this and it only repeated once:

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

Your variable is incremented outside the BEGIN/END block. Also I would recommend you initially set your variable to 0 to avoid any potential garbage data stored in that memory location.

To achieve your goal using a set-based query instead of a loop ( BTW there are lots of such examples here on StackOverflow ) you'll have to have a tally (numbers) table or create it on a fly with a subquery or recursive CTE.

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

To populate it up to 100000 ( Celko-style )

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;

Now your stored procedure boils down to one statement

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;

Here is SQLFiddle demo

Now if you generate relatively small amounts of certificates (< 32768) then you can use recursive CTE to build a sequence of numbers (and don't need a persisted tally table)

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);

Here is SQLFiddle demo for that case

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM