Sql 选择n行数并运行存储过程

Sql 选择n行数并运行存储过程,sql,sql-server,Sql,Sql Server,我有表1,它有——比方说——10K记录 我用的是 ROW_NUMBER() OVER(BATCH_ID) as ROWLIST 获取行号 我需要的是:对于运行的前1K行,假设我将有一个运行的存储过程,由于特定的原因,由于CPU/RAM的要求和限制,我需要它一次运行x行 INSERT INTO dbo.[tbl_sub] SELECT CIN FROM tbl_Main 对于接下来的1K行,运行相同的东西。直到记录集或行计数结束 因此,基本上是将一个包含X个记录的表划分为行,然后每X个

我有表1,它有——比方说——10K记录

我用的是

ROW_NUMBER() OVER(BATCH_ID) as ROWLIST  
获取行号

我需要的是:对于运行的前1K行,假设我将有一个运行的存储过程,由于特定的原因,由于CPU/RAM的要求和限制,我需要它一次运行x行

INSERT INTO dbo.[tbl_sub] 
SELECT CIN
FROM  tbl_Main
对于接下来的1K行,运行相同的东西。直到记录集或行计数结束

因此,基本上是将一个包含X个记录的表划分为行,然后每X个行运行一个特定的代码

以下是一些很棒的解决方案的代码!我很难在以下代码中实现它:

CREATE TABLE [LTAC_TEST_1](
[CLAIM_ID] [nvarchar](15) NULL,
[CIN] [nvarchar](10) NULL,
[SVC_DATE] [datetime] NULL,
[SVC_DATE_TO] [datetime] NULL,
[TOTAL_DAYS] [int] NULL,
[CHAIN_COUNT] [int] NULL
) ON [PRIMARY]

;WITH chain_builder AS
(
SELECT ROW_NUMBER() OVER(ORDER BY s.CIN, s.CLAIM_ID) as chain_ID,
  s.CIN,
  s.SVC_DATE, s.SVC_DATE_TO, s.CLAIM_ID, 1 as chain_count
FROM [LTAC_FINBASE_BASE2] s
WHERE s.SVC_DATE <> ALL 
  (
  SELECT DATEADD(d, 1, s2.SVC_DATE_TO)
  FROM [LTAC_FINBASE_BASE2] s2
  WHERE s.CIN = s2.CIN
  )
UNION ALL
SELECT chain_ID, s.CIN, s.SVC_DATE, s.SVC_DATE_TO,
  s.CLAIM_ID, chain_count + 1
  FROM [LTAC_FINBASE_BASE2] s
JOIN chain_builder as c
  ON s.CIN = c.CIN AND
  s.SVC_DATE = DATEADD(d, 1, c.SVC_DATE_TO)
),
chains AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
  CLAIM_ID, chain_count, ROW_NUMBER() OVER(PARTITION BY chain_ID, chain_count ORDER BY SVC_DATE_TO DESC) as link_row
FROM chain_builder
),
link_picker AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
  CLAIM_ID, chain_count
FROM chains
WHERE link_row = 1
),
diff AS
(
SELECT c.chain_ID, c.CIN, c.SVC_DATE, c.SVC_DATE_TO,
  c.CLAIM_ID, c.chain_count,
  datediff(day,c.SVC_DATE,c.SVC_DATE_TO)+1 daysdiff
FROM link_picker c
),
diff_sum AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
  CLAIM_ID, chain_count,
  SUM(daysdiff) OVER (PARTITION BY chain_ID) as total_diff
FROM diff
),
diff_comp AS
(
SELECT chain_ID, CIN,
  MAX(total_diff) OVER (PARTITION BY CIN) as total_diff
FROM diff_sum
)
INSERT INTO [LTAC_TEST_1]
SELECT DISTINCT ds.CLAIM_ID, ds.CIN, ds.SVC_DATE,
  ds.SVC_DATE_TO, ds.total_diff as TOTAL_DAYS, ds.chain_count as CHAIN_COUNT
FROM diff_sum ds
JOIN diff_comp dc
ON ds.chain_ID = dc.chain_ID AND ds.CIN = dc.CIN
  AND ds.total_diff = dc.total_diff
OPTION (maxrecursion 0)

有多种方法可以做到这一点,这里有一种解决方案——并不是说它是最有效的:

如果您想将所有行从tbl_Main移动到tbl_sub,则WHILE EXISTS语句表示继续我们的循环,前提是tbl_Main中仍然存在tbl_sub中不存在的值

在每次迭代中,将按批次ID的顺序插入1000行,直到完成。在上面的示例中,不清楚为什么要使用ROW_NUMBER窗口函数,因为您没有指定该列是分区依据还是排序依据,并且可能不需要它

WHILE EXISTS
    (
        SELECT
            *

        FROM
            tbl_Main

        WHERE
            NOT EXISTS
            (
                SELECT  *
                FROM    dbo.tbl_sub
                WHERE   CIN = tbl_Main.CIN
            )
    )

BEGIN
    INSERT INTO dbo.tbl_sub
    (
        CIN
    )

    SELECT TOP 1000
        CIN

    FROM
        tbl_Main

    WHERE
        NOT EXISTS
        (
            SELECT  *
            FROM    dbo.tbl_sub
            WHERE   CIN = tbl_Main.CIN
        )

    ORDER BY
        BATCH_ID
END

一种方法是创建一个临时表,其中包含标识号从0开始的所有键值和两个计算列,这两个计算列将标识号转换为BatchID和介于0和999之间的批次号

CREATE TABLE #t
(
id int identity (0,1),
BatchID as ([id]/10),
BatchNumber as ([id]%10),
KeyColumn varchar(50)
)

INSERT INTO #t(KeyColumn) 
SELECT KeyColumn  FROM [DataTable_t]
然后,您可以循环使用BatchID的所有值,并对这组1000条记录执行任何需要的操作

--Subquery to return a batch of 1000 records
(SELECT d.* 
FROM #t t 
JOIN DataTable_t] d 
ON d.KeyColumn = t.KeyColumn
WHERE t.BatchID = @BatchID ) AS Batch

我不确定这在您的情况下是否有任何用处

我将创建一个运行此功能的存储过程

DECLARE @RowsAffected INT =1

While(@RowsAffected<>0)
BEGIN
INSERT INTO dbo.[tbl_sub] 
   SELECT TOP 1000
      tbl_Main.CIN
   FROM  tbl_Main
   left join dbo.[tbl_sub] t2 on t2.CIN=tbl_Main.CIN
   WHERE t2.CIN IS NULL

   SET @RowsAffected=@@Rowcount
END

在CPU/RAM要求不成问题的情况下,您能否在正常工作时间之外安排此操作?不,它在生产srv上运行,在生产时间内记录数以百万计我添加了代码您可以修改您的查询吗?我添加了代码您可以修改您的查询吗?