1

给定以下简单的结构:

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 和 Category Names 的 StringList_TBLType

  1. 从我的 StringList_TBLType 中选择所有字符串
  2. 如果字符串不存在,则将其插入到 Category TABLE 中
  3. 获取已插入或已存在 Category 的 ID
  4. 将 ProductId 和 CategoryId 插入到 LINK TABLE 中。

我可能会努力工作并获得一些工作,但我对 MS SQL 和一般的存储过程几乎没有经验,并且害怕我最终会编写一种非常低效的方法来做到这一点。

4

2 回答 2

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;

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

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

INSERT INTO Link SELECT ProductID, ChangeID FROM @changes

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

编辑:

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

@data 是您的过程的 StringList_TBLType 参数。

于 2013-06-20T20:20:44.583 回答
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
于 2013-06-20T20:25:51.890 回答