存储过程使用表值参数将值插入表中

时间:2013-06-20 19:58:03

标签: sql-server sql-server-2008

鉴于以下简单结构:

TABLE: Product (ProductId, ProductName)

TABLE: Category (CategoryId, CategoryName)

LINK TABLE: ProductId,CategoryId

我有一个表类型,我希望将其传递给存储过程,以便在不存在的情况下将值插入到另一个表中。

CREATE TYPE StringList_TBLType AS TABLE (s NVARCHAR(255) NOT NULL PRIMARY KEY)

我想在传入ProductName的存储过程和类别名称的StringList_TBLType中执行以下操作

  1. 从我的StringList_TBLType
  2. 中选择所有字符串
  3. 如果字符串不存在,则将其插入类别表
  4. 获取已插入或已存在的类别的ID
  5. 将ProductId和CategoryId插入LINK TABLE。
  6. 我可能会努力工作并获得一些工作,但我对MS SQL和存储过程一般都没什么经验,我很害怕我最终会写一个效率很低的方法。

2 个答案:

答案 0 :(得分:2)

您可以使用MERGE语句捕获类别ID。

DECLARE @changes TABLE  (ChangeID VARCHAR(10), Id INTEGER);
DECLARE @JustSomeRandomVariable INT;

MERGE Category AS TARGET
USING @data AS SOURCE
    ON TARGET.Category = SOURCE.s
WHEN NOT MATCHED THEN
    INSERT ([Category])
    VALUES (SOURCE.s)
WHEN MATCHED THEN 
    UPDATE SET @JustSomeRandomVariable = 1
OUTPUT $action, inserted.Id INTO @changes;

merge语句中的随机变量确保更新记录到@changes表变量中。

现在您可以使用@changes更新链接表。

INSERT INTO Link SELECT ProductID, ChangeID FROM @changes

只需使用简单的选择查询检索所需的ProductID。

修改

这可能会导致Link表中出现双重记录。您可能需要稍微调整一下,也许使用MERGE语句插入到Link表中。

@data是您程序的StringList_TBLType参数。

答案 1 :(得分:0)

这是我建议的(未经测试)

CREATE PROCEDURE AddProductToCategories 
@productname nvarchar(255),
@categories StringList_TBLType READONLY
AS
BEGIN

DECLARE @productId bigint --change to datatype of Product.ProductId
SET @productId = (SELECT TOP 1 ProductId FROM Product WHERE ProductName = @productname) --What to do if your product names are not unique?

IF @productId is not NULL
BEGIN

DECLARE cur CURSOR FOR (
    SELECT cat.CategoryName, cat.CategoryId, c.s
    FROM @categories c
        RIGHT OUTER JOIN Category cat on c.s = cat.CategoryName
)

DECLARE @id as bigint --change to datatype of Category.CategoryId
DECLARE @name as nvarchar(255) --change to datatype of Category.CategoryName
DECLARE @categoryNameToAdd as nvarchar(255)

OPEN cur
FETCH NEXT FROM cur INTO @name, @id, @categoryNameToAdd

WHILE @@FETCH_STATUS = 0
BEGIN
    IF @id is NULL
    BEGIN
        --category does not exist yet in table Category
        INSERT INTO Category (CategoryName) VALUES (@categoryNameToAdd)
        SET @id = SCOPE_IDENTITY()
    END

    INSERT INTO ProductsCategories --your link table
    (ProductId, CategoryId)
    VALUES
    (@productId, @id) 


    FETCH NEXT FROM cur INTO @name, @id, @categoryNameToAdd
END --cursor


CLOSE cur
DEALLOCATE cur
END --IF @productId
END --sproc