Sql 选择n行数并运行存储过程
我有表1,它有——比方说——10K记录 我用的是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个
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上运行,在生产时间内记录数以百万计我添加了代码您可以修改您的查询吗?我添加了代码您可以修改您的查询吗?