SQL - 避免来自外部rest API的重复数据

时间:2017-10-03 07:41:14

标签: sql-server rest azure

我有一个外部休息API(https://api.bitfinex.com/v1/lendbook/usd),我想将数据从那里插入到我的azure表中,但避免重复数据。我知道数据本身有时会有重复数据,有时却没有,但我也怀疑我的查询。因此,我正在寻找一种解决方案,以确保即使API数据经常更新,也不会将重复数据推送到我的表中。

下面是我使用node-mssql插入数据的代码,核心是查询:

insert(row: object): any {
    const sql = `
      IF NOT EXISTS (
        SELECT 1
        FROM dbo.lendbook d WITH (HOLDLOCK)
        WHERE d.rate = @rate
               AND d.amount  = @amount
               AND d.period = @period
               AND d.timestamp = @timestamp
               AND d.type = @type
               AND d.frr = @frr
      )
      BEGIN
        INSERT dbo.lendbook
          (rate, amount, period, timestamp, type, frr)
        VALUES
          (@rate, @amount, @period, @timestamp, @type, @frr)
      END
    `;
    const ps = new mssql.PreparedStatement(this.db);
    ps.input('rate', mssql.Float);
    ps.input('amount', mssql.Float);
    ps.input('period', mssql.Int);
    ps.input('timestamp', mssql.DateTime);
    ps.input('type', mssql.NVarChar);
    ps.input('frr', mssql.NVarChar);

    ps.prepare(sql, (err: any) => {
      if (err) {
        LendbookService.LOGGER.error('MSSQL prepare error', err);
      }
      else {
        ps.execute(row, (err: any) => {
          if (err) {
            LendbookService.LOGGER.error('MSSQL execute error', err);
          }
          ps.unprepare((err: any) => {
            if (err) {
              LendbookService.LOGGER.error('MSSQL unprepare error', err);
            }
          });
        });
      }
    });
    return ps;
  }

这是我的表的定义:

enter image description here

1 个答案:

答案 0 :(得分:0)

经过数小时的研究和测试,我发现了它。下面的查询插入来自其余API的数据,然后在推入数据库中的表之前过滤绝对重复项(在每列中具有相同的值)。希望它可以帮助处于相同情况的人。

const sql = `
      INSERT dbo.lendbook
        (rate, amount, period, timestamp, type, frr)
      VALUES
        (@rate, @amount, @period, @timestamp, @type, @frr)

      ;WITH cte
        AS (SELECT ROW_NUMBER() OVER (PARTITION BY rate, amount, period, timestamp, type, frr
          ORDER BY ( SELECT 0)) RN
          FROM dbo.lendbook)
      DELETE FROM cte
      WHERE  RN > 1;
    `;