简体   繁体   中英

SQL Server stored procedure - inserting new rows

I want to insert records in Table2 from Table1 and that too insert with my new primary key specified.. I have written following stored procedure for that ::

DECLARE @Iterator INT, @tempCount INT, @Nbb_ID INT

SET @Iterator = 0
SET @tempCount = count('SELECT * FROM Table1')

WHILE (@Iterator < @tempCount)
BEGIN
    SET @Nbb_ID =   NEWID()

    INSERT INTO Table2 (Nbb_ID, Nbb_Name)
    VALUES (@Nbb_ID, (SELECT NAME1 FROM Table1 WHERE rownum = @Iterator + 1))

    SET @Iterator = @Iterator + 1
END

I don't understand where am I going wrong ?

The INSERT command comes in two flavors:

(1) either you have all your values available, as literals or SQL Server variables - in that case, you can use the INSERT .. VALUES() approach:

INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
VALUES(Value1, Value2, @Variable3, @Variable4, ...., ValueN)

Note: I would recommend to always explicitly specify the list of column to insert data into - that way, you won't have any nasty surprises if suddenly your table has an extra column, or if your tables has an IDENTITY or computed column. Yes - it's a tiny bit more work - once - but then you have your INSERT statement as solid as it can be and you won't have to constantly fiddle around with it if your table changes.

(2) if you don't have all your values as literals and/or variables, but instead you want to rely on another table, multiple tables, or views, to provide the values, then you can use the INSERT ... SELECT ... approach:

INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
   SELECT
       SourceColumn1, SourceColumn2, @Variable3, @Variable4, ...., SourceColumnN
   FROM
       dbo.YourProvidingTableOrView

Here, you must define exactly as many items in the SELECT as your INSERT expects - and those can be columns from the table(s) (or view(s)), or those can be literals or variables. Again: explicitly provide the list of columns to insert into - see above.

You can use one or the other - but you cannot mix the two - you cannot use VALUES(...) and then have a SELECT query in the middle of your list of values - pick one of the two - stick with it.

So in your case, you need to change your INSERT statement to:

INSERT INTO Table2 (Nbb_ID, Nbb_Name)
   SELECT 
      NEWID(), NAME1 
   FROM 
      Table1 

and that should do it - there's absolutely no need to create your own row-by-agonizing-row WHILE loop here.... just use a single, set-based statement and you're done!

I'm not entirely sure what you're trying to achieve, but if you're just wanting to copy the records from Table1 into Table2 but give a new ID to the Table2 record, then you can do this more efficiently by using

insert into Table2 
select NEWID(), NAME1 from Table1

This will evaluate NEWID() for each record that is being taken from Table1, thus giving the Table2 record a different UID.

The benefit over your method is that this is a set-based approach which is what DBs are best at. Your method is RBAR (row-by-agonizing-row) which is not the best use of SQL.

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