选择n行并运行存储过程

时间:2014-10-22 19:50:36

标签: sql sql-server

我有表1 - 比方说 - 10K记录。

我使用的是

ROW_NUMBER() OVER(BATCH_ID) as ROWLIST  

获取行号

我需要的是:对于第一个1K行运行,让我们说(我将运行存储过程,由于CPU / RAM要求和限制,我需要一次运行x行数)< / p>

INSERT INTO dbo.[tbl_sub] 
SELECT CIN
FROM  tbl_Main

并且对于下一个1K行运行相同的事情。直到记录集(或rowcount)结束。

所以基本上将一个包含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)

3 个答案:

答案 0 :(得分:0)

有多种方法可以做到这一点,这里有一个解决方案 - 并不是说​​效率最高:

假设您希望将所有行从tbl_Main移动到tbl_sub WHILE EXISTS语句,请继续我们的LOOP,前提是我们仍然在tbl_Main中显示尚不存在的值(NOT EXISTS )在tbl_sub。

每次迭代将按BATCH_ID的顺序插入1000行,直到完成。在上面的示例中,不清楚为什么使用ROW_NUMBER()窗口函数,因为您尚未指定该列是PARTITION BY还是ORDER BY而您可能不需要它。

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

答案 1 :(得分:0)

一种方法是创建一个临时表,其中包含具有标识号(从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

我不确定你的情况是否有用

答案 2 :(得分:0)

我会创建一个运行此

的存储过程
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