Question

I am exploring the use of table valued parameters in stored procedures to do multiple inserts in a single call to the database.

The table value parameter contains information that, more or less, reflects the definition of the table I want to insert into. It is only missing the ID column.

If I have the following table definition:

Create Table Product
(
     ProductID int,
     ProductName varchar(100),
     ProductDesc varchar(4000),
     ProductCost int
)

Type definition:

Create Type ProductTable as Table
(
    ProductName varchar(100),
    ProductDesc varchar(4000),
    ProductCost int
)

and stored procedure definition:

Create Procedure usp_Product_Insert
    @Products ProductTable READONLY
AS
    INSERT Product
    (
        ProductID,
        ProductName,
        ProductDesc,
        ProductCost
    )
    SELECT
        (Select ISNULL(Max(ProductID),0) + 1 From Product),
        P.ProductName,
        P.ProductDesc,
        P.ProductCost
    FROM
        @Products P

How do I alter what I have to insert unique id's if there is more than one set of data in my parameter?

Right now, if I run the following statement

Truncate Table Product
Declare @Products ProductTable
Insert @Products Values ('Playstation', 'Game Console', 300)
exec usp_Product_InsertUpdate_WithOutput @Products

through the stored procedure with no previous records in the table, I get

ProductID   ProductName ProductDesc ProductCost
1           Playstation     Game Console    300

But if I run more than one record through

Truncate Table Product
Declare @Products ProductTable
Insert @Products Values
('Playstation', 'Game Console', 300),
('Xbox', 'Game Console', 200),
('Wii', 'Game Console', 150)
exec usp_Product_InsertUpdate_WithOutput @Products

I get

ProductID   ProductDesc     ProductDesc ProductCost
1           Playstation     Game Console    300
1           Xbox            Game Console    200
1           Wii             Game Console    150

What I would like to see is

ProductID   ProductDesc     ProductDesc ProductCost
1           Playstation     Game Console    300
2           Xbox            Game Console    200
3           Wii             Game Console    150

How can I accomplish this efficiently without using identity?

Était-ce utile?

La solution

You can't. And should not even try.

Business define business keys.

Developers define surrogate keys.

What you want is a surrogate key, so use an IDENTITY column.

If your business defines surrogate keys, then your duty is to teach them they should not do so.

Autres conseils

After further searching, I found this approach provided by hims056:

The stored procedure would be rewritten as follows:

Create Procedure usp_Product_Insert
    @Products ProductTable READONLY
AS
    INSERT Product
    (
        ProductID,
        ProductName,
        ProductDesc,
        ProductCost
    )
    SELECT
        (ROW_NUMBER( ) OVER ( ORDER BY ProductID ASC )) + (Select ISNULL(Max(ProductID),0) From Product),
        P.ProductName,
        P.ProductDesc,
        P.ProductCost
    FROM
        @Products P
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top