仅当同一行不超过x天数时才插入

时间:2016-12-28 03:26:41

标签: sql-server tsql

我有下表@HasVal:

+-------------------+--------------------------------------------+--------------+
| SourceId (INT)    | HashByte VARBINARY(32)                     | DateInserted |
+-------------------+--------------------------------------------+--------------+
| 345781            | 0xDC91932F2B1877D554F2F85ACB5709D33771D122 | 2016-12-17   |
| 345000            | 0x6368519CA666D6FF7E412835A25240A476E10CCD | 2016-12-16   |
+-------------------+--------------------------------------------+--------------+

第一次插入新项目。

当项目(SourceId和HasByte的组合)在同一天再次进入或少于3天时,我将允许其他项目将被完全忽略。

所以意味着如果一个具有SourceId 345781和0xDC91932F2B1877D554F2F85ACB5709D33771D122的项目在12月27日再次进入,我将忽略它。

现在我有类似下面的内容

DECLARE @currentDate DATE, @newSourceId INT

SET @currentDate = '2016-12-21'
SET @newSourceId = 223134

DECLARE @oldHash VARBINARY(32), @oldDate DATE

SELECT TOP 1 @oldHash = HashByte, @oldDate = DateInserted FROM @HasVal
  WHERE SourceId = @newSourceId AND 
  HashByte = HASHBYTES('SHA1', CONVERT(nvarchar(500),'some values to hash'))

IF @oldHash IS NULL
BEGIN
    -- insert new item
    INSERT INTO @HasVal VALUES 
        (@newSourceId, 
         HASHBYTES('SHA1', CONVERT(nvarchar(500),'some values to hash')), GETDATE())
END
ELSE
BEGIN
    IF @oldDate >= DATEADD(day, -3, @currentDate)
    BEGIN
        -- allow the item for further processing
        SELECT 'Allowed'
    END
    -- ignore the item
    ELSE SELECT 'NOT Allowed'
END

我想知道的是,是否有更短的方式或更有效的方法来做同样的事情?

我觉得此时我只能在一个SELECTINSERT语句中编写更短的代码IF @oldDate >= DATEADD(day, -3, @currentDate)

1 个答案:

答案 0 :(得分:1)

看起来这将满足您的需求:

-- Sample data.
declare @HasVal as Table ( SourceId Int, HashByte VarBinary(32), DateInserted Date );
insert into @HasVal ( SourceId, HashByte, DateInserted ) values
  ( 345781, 0xDC91932F2B1877D554F2F85ACB5709D33771D122, '20161217' ), -- Using ISO date format.
  ( 345000, 0x6368519CA666D6FF7E412835A25240A476E10CCD, '20161216' ),
  ( 223134, 0xC17FC3F4AF82FF0E32A0A7A62BEF699B5F53D237, '20161229' ); -- Hash of 'some values to hash'.
select * from @HasVal;

-- Inputs.
declare @NewSourceId as Int = 223134;
declare @HashSource as VarChar(100) = 'some values to hash';

-- Process the data.
declare @Today as Date = GetDate();
-- Since cryptographic hashes are computationally expensive by design, hash once and use twice.
declare @NewHash as VarBinary(32) = HashBytes( 'SHA1', Cast( @HashSource as NVarChar(500) ) );
select @Today as Today, @NewHash as NewHash; -- Debugging display.

-- Insert the row if there is no existing row that matches on   SourceId   and   HashByte   and
--   was inserted within the last three days.
insert into @HasVal ( SourceId, HashByte, DateInserted )
  select @NewSourceId, @NewHash, @Today
    where not exists (
      select 42 from @HasVal
        where SourceId = @NewSourceId and HashByte = @NewHash and DateInserted >= DateAdd( day, -3, @Today ) );
if @@RowCount > 0 -- If there is additional code to execute based on whether a row was inserted.
  select 'Row inserted.' as JustSayin

select * from @HasVal; -- Display the result.