sql - 如果找到行,则触发代码,如果没有返回,则不执行任何操作
问题描述
我有过去已经测试和使用过的代码。我现在想用 if 语句自动化这段代码。这意味着当返回行时,我想用游标执行该过程。如果没有找到记录或没有返回任何内容,我不会发生任何事情并停止。
附上,我的代码如何正确嵌入 if 语句?
declare @date smalldatetime
set @date = (select max(date) from inventory_table)
select symbol, id, count(distinct 2) cnt into #target
from inventory_table
where date between dateadd(day, -7, @date) and @date
group by symbol,id
having count(distinct 2) >= 4
-- Process with cursor starts here
DECLARE @MyList TABLE (iid int)
INSERT INTO @MyList
select distinct id from #target
DECLARE @iid int
DECLARE db_cursor CURSOR FOR
SELECT iid FROM @MyList
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @iid
WHILE @@FETCH_STATUS = 0
BEGIN
declare @mindate date,
@maxdate date
set @mindate = ( select min(date) from inventory_table where ID = @iid )
set @maxdate = ( select max(date) from inventory_table where ID = @iid )
exec spReissuingIDs @mindate , @maxdate, @iid
FETCH NEXT FROM db_cursor INTO @iid
END
CLOSE db_cursor
DEALLOCATE db_cursor
解决方案
通过一些细微的修改,您可以处理您的请求,消除对 CURSOR 的使用,并进行一些优化。
-- Define @MyList --
DECLARE @MyList TABLE (
ListId INT IDENTITY(1,1) PRIMARY KEY,
Iid INT,
MinDate DATETIME,
MaxDate DATETIME
);
-- Fetch Data --
INSERT INTO @MyList (
Iid, MinDate, MaxDate
)
SELECT DISTINCT
t.id, i.MinDate, i.MaxDate
FROM #target AS t
CROSS APPLY (
SELECT MIN( [date] ) AS MinDate, MAX( [date] ) AS MaxDate FROM inventory_table WHERE id = t.id
) AS i;
DECLARE @ListId INT, @iid INT, @min DATETIME, @max DATETIME;
-- Set @ListId to 1 for the first row.
SET @ListId = 1;
-- While @ListId <= to the number of rows in @MyList, run spReissuingIDs for each Iid --
-- Note: If no rows are present, spReissuingIDs will never be called --
WHILE ( @ListId <= ( SELECT MAX( ListId ) FROM @MyList ) )
BEGIN
-- Current Row --
SELECT
@iid = Iid, @min = MinDate, @max = MaxDate
FROM @MyList WHERE ListId = @ListId;
-- Process Row --
EXEC spReissuingIDs @min, @max, @iid
-- Next Row --
SET @ListId = ( @ListId + 1 );
END
几点注意事项:
- 使用 CURSOR 总是一个坏主意。
- 处理 RBAR(逐行处理)是一个代价高昂的想法,应尽可能避免。
对于此示例,将 @MyList.ListId 设置为 IDENTITY(1,1) 会为每一行分配一个唯一的、连续的 id,从而使您可以降低使用 CURSOR 的成本。当我没有其他选择将数据作为 SET 处理时,我经常使用它。
编辑:
另外,作为一个旁注,我不确定在哪里#target
创建,但是,如果 #target 有数据是代码是否应该继续的决定因素,您可以通过在最顶部添加以下内容来短路此代码电话:
IF NOT EXISTS( SELECT * FROM #target )
RETURN;
推荐阅读
- p-value - 使用混叠系数引导 p 值问题
- laravel - 在 Laravel 中获取 api 之前检查是否有互联网连接
- reactjs - React:创建一个搜索栏来过滤和映射学生
- python - Starting new Screen on the background on reboot
- azure - Docker 容器在本地运行良好。现在我需要在云端按计划进行
- flutter - Flutter - FutureBuilder 在热重载时触发两次
- angular - Angulars HostListener 干扰了聚焦的 HTML 对象
- security - @code 块中的代码是否已编译并通过浏览器调试可见?
- elrond - 失败:“setState”“newAddresses”字段中的地址应具有 SC 格式:地址:the_crowdfunding_contract
- javascript - 如何使用 Firebase 数据在一个 html 页面中显示多个表格?