首页 > 解决方案 > 如果找到行,则触发代码,如果没有返回,则不执行任何操作

问题描述

我有过去已经测试和使用过的代码。我现在想用 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

标签: sqlsql-serverif-statement

解决方案


通过一些细微的修改,您可以处理您的请求,消除对 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;

推荐阅读