Sql server 如何插入动态行数

Sql server 如何插入动态行数,sql-server,tsql,cursor,temp-tables,Sql Server,Tsql,Cursor,Temp Tables,我有一个材料表作为源表,如下所示: CREATE TABLE dbo.MATERIAL ( ID int IDENTITY(1,1) NOT NULL, CATEGORY_ID int NOT NULL, SECTION_ID int NOT NULL, STATUS_ID int NOT NULL ) CREATE TABLE dbo.ORDER ( ID int IDENTITY(1,1) NOT NULL, MATERIAL_ID int

我有一个材料表作为源表,如下所示:

CREATE TABLE dbo.MATERIAL (
    ID int IDENTITY(1,1) NOT NULL,
    CATEGORY_ID int NOT NULL,
    SECTION_ID int NOT NULL,
    STATUS_ID int NOT NULL
)
CREATE TABLE dbo.ORDER (
    ID int IDENTITY(1,1) NOT NULL,
    MATERIAL_ID int NOT NULL
)
CATEGORY_ID    SECTION_ID    STATUS_ID    COUNT
-----------    ----------    ---------    -----
     3             8             1          10
     8             2             2          11 
     4             6             1           8
我还有一个订单表作为目标表,如下所示:

CREATE TABLE dbo.MATERIAL (
    ID int IDENTITY(1,1) NOT NULL,
    CATEGORY_ID int NOT NULL,
    SECTION_ID int NOT NULL,
    STATUS_ID int NOT NULL
)
CREATE TABLE dbo.ORDER (
    ID int IDENTITY(1,1) NOT NULL,
    MATERIAL_ID int NOT NULL
)
CATEGORY_ID    SECTION_ID    STATUS_ID    COUNT
-----------    ----------    ---------    -----
     3             8             1          10
     8             2             2          11 
     4             6             1           8
我将ome数据发送到SQL server存储过程,并创建以下临时表

DECLARE @temptable TABLE (
    CATEGORY_ID int NOT NULL,
    SECTION_ID int NOT NULL,
    STATUS_ID int NOT NULL,
    COUNT int NOT NULL
)
并填写了如下数据:

CREATE TABLE dbo.MATERIAL (
    ID int IDENTITY(1,1) NOT NULL,
    CATEGORY_ID int NOT NULL,
    SECTION_ID int NOT NULL,
    STATUS_ID int NOT NULL
)
CREATE TABLE dbo.ORDER (
    ID int IDENTITY(1,1) NOT NULL,
    MATERIAL_ID int NOT NULL
)
CATEGORY_ID    SECTION_ID    STATUS_ID    COUNT
-----------    ----------    ---------    -----
     3             8             1          10
     8             2             2          11 
     4             6             1           8
我想要的是匹配物料表中的物料计数,该物料表与同一行中给定的类别ID、区段ID和状态ID三元组匹配;然后将这些记录的ID插入目标表ORDER

我怎样才能完成这项任务


问候。

现在我想我理解了需求,所以扔掉了一堆以前的工作

这里有一个工作:

这将生成一个名为GENROWS的数据集,其中包含的行数等于表中的max count。它是通过使用递归公共表表达式CTE来实现这一点的,以便在TESTERABLE中为max count的每个计数生成1行。 然后,它使用此数据集连接到诱惑和材质,以生成按顺序插入材质的时间

我不太喜欢使用保留字,所以我将order调整为morder,并且我建议调整列计数,否则您将不时被困在[]中包装字

注意:这假设物料表中不会有具有相同类别ID、区段ID和状态ID的重复记录。如果有,;那么这可能会也可能不会像预期的那样

最后一点,现在我已经更好地了解了您所追求的目标,我不确定您会看到与使用游标相比,性能有很大的提高。因为行必须以某种方式生成。这可能会更快一些,因为我们一次生成集合并插入,而不是单独生成。但是,生成、存储和检索生成的数据集会带来开销,这可能会抵消这一收益。只有测试才能说明问题

WITH 
GenRows (RowNumber, Val) AS (
   -- Anchor member definition
   SELECT 1 AS RowNumber, (Select max(count) val from temptable) val
   UNION ALL
   -- Recursive member definition
   SELECT a.RowNumber + 1  AS RowNumber, a.val
   FROM   GenRows a
   WHERE  a.RowNumber < a.val
)
Insert into morder (Material_ID)  
SELECT A.ID
FROM material A
INNER JOIN temptable B
   on A.Category_ID = B.Category_ID
  and A.Section_Id = B.Section_Id
  and A.Status_Id = B.Status_ID
INNER JOIN GenRows
  on GenRows.RowNumber <= b.[count]

我想我已经找到了解决办法。我应该用游标。下面的代码实现了这一点:

DECLARE @MATERIAL_ID int
DECLARE @CATEGORY_ID int
DECLARE @SECTION_ID int
DECLARE @STATUS_ID int
DECLARE @COUNT int

DECLARE cur CURSOR LOCAL FOR
SELECT
    CATEGORY_ID,
    SECTION_ID,
    STATUS_ID,
    COUNT
FROM
    @temptable 

OPEN cur
FETCH NEXT FROM cur INTO @CATEGORY_ID, @SECTION_ID, @STATUS_ID, @COUNT
WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO
            dbo.ORDER
            (MATERIAL_ID)
        SELECT
            TOP (@COUNT) ID
        FROM
            dbo.MATERIAL AS m
        WHERE
            m.CATEGORY_ID = @CATEGORY_ID
            AND m.SECTION_ID = @SECTION_ID
            AND m.STATUS_ID = @STATUS_ID

        FETCH NEXT FROM cur INTO @CATEGORY_ID, @SECTION_ID, @STATUS_ID, @COUNT
    END
CLOSE cur
DEALLOCATE cur

这听起来像是一个解释不当的消耗库存问题。物料是一张库存表。然后,在@tentable中组装一个BoM表,描述完成订单所需的项目和数量。问题是如何使用BoM从物料中提取库存的一些奇怪的变化,尽管没有跟踪任何以前消耗的库存,并将结果插入到订单中。由于项目数量大,减少往返次数和性能对项目至关重要。为了防止多次访问数据库,我们将带有子对象的对象序列化为XML,然后在数据库服务器上处理所有数据。使用此技术,我们可以一次插入数千种材料,并观察与多个项目类似的性能。@user3021830更新了答案,为您提供了一种不使用光标的方法,我相信光标会影响性能。最后一个响应对于您来说可能是最干净的。您正在失去使用游标所获得的一些性能。在RDBMS中,当您可以使用集合逻辑进行处理时,您将获得更好的性能。非常感谢您的更新。但它似乎仍然没有达到我的要求。我刚刚对查询做了一些微小的更改,并在@tentable中更新了所需数量的材料,不幸的是,ode现在没有运行正确的结果。请看我没有理解这个要求。我的印象是,您只想将记录插入到与材料中数据记录的数量精确匹配的顺序中,因此在fiddle示例中。。。诱惑有3,8,1,3。其中3是最后一个3是计数。如果查看物料表,有3,8,1的记录,但这些记录的计数大于3,因此没有匹配的数据。在Tentiable中的所有其他记录也是如此。现在,如果你在插入任何随机的一组记录后,从TESTERABLE中选择与3,8,1匹配的10个记录中的任意3个,我很抱歉没有提供正确的详细信息。让我们用集合论来举例说明这个项目。材料表是通用设置。所有项目都驻留在该表中,不属于该表的任何项目都不能添加到订单表中。用户发送dta,我将其填入@tentable,该dta描述了要拾取的材料的规格,以及计数为要拾取的材料数量。我需要的是找到与spesc匹配的材料,选择它们的计数编号,然后将这些材料的ID保存到订单表中。@user3021830现在我想我明白了你的想法,我想生成测试数据,当这看起来更像实际操作数据时,我已经更新了小提琴和结果;并清理了早些时候的垃圾。