2016-08-22 1 views
0

У меня есть хранимая процедура, которую я использую для импорта заказов в базу данных опроса. В настоящее время он импортирует все заказы с предыдущего дня, но последние изменения в бизнес-плане требуют, чтобы эти опросы отправлялись ежечасно. Импорт происходит из представления в другой базе данных. атрибут 1 - номер заказа, который будет уникальным для каждого опроса, поэтому мы можем использовать его для ограничения импорта.Изменить, где инструкция для исключения дубликатов

Как изменить это, чтобы не вытаскивать дубликаты?

BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

Insert INTO SurveyTable 
(SurveyTable.firstname, 
SurveyTable.token, 
SurveyTable.email, 
SurveyTable.emailstatus, 
SurveyTable.language, 
SurveyTable.remindersent, 
SurveyTable.attribute_1, 
SurveyTable.attribute_2) 


select 
    location, 
    cast('' as xml).value('xs:base64Binary(sql:column("token"))', 'nvarchar(MAX)'), 
    email, 
    emailstatus, 
    [language], 
    remindersent, 
    attribute_1, 
    attribute_2 
from 
    (
     select 
      RTRIM([Closed_Orders_For_Survey].[Location]) location, 
      crypt_gen_random(12) as token, 
      [Closed_Orders_For_Survey].[Email] email, 
      'OK' emailstatus, 
      'en' [language], 
      'N' remindersent, 
      [Closed_Orders_For_Survey].[Order Number] attribute_1, 
      CONVERT(VARCHAR(10), [Closed_Orders_For_Survey].[Invoice Date],110) attribute_2 
     from 
      [Closed_Orders_For_Survey] 
     where 
      [Closed_Orders_For_Survey].[Order Date] >= dateadd(DAY, -1, Convert(date, GETDATE())) 
    ) as x 
END 

P.S. токен - это сгенерированная уникальная строка, используемая при создании URL опроса. Мы решили не использовать номер заказа в качестве токена, потому что это было бы слишком предсказуемым и позволяло бы людям изменять свой URL-адрес, чтобы заполнить опросы других пользователей.

ответ

1

Это не идеально подходит для очень больших наборов данных (вы должны убедиться, что у вас хорошие индексы для атрибута_1), но вы можете сделать предложение «где не существует», чтобы отфильтровать любые заказы из внутреннего запроса которые уже были вставлены:

select 
    location, 
    cast('' as xml).value('xs:base64Binary(sql:column("token"))', 'nvarchar(MAX)'), 
    email, 
    emailstatus, 
    [language], 
    remindersent, 
    attribute_1, 
    attribute_2 
from 
    (
     select 
      RTRIM([Closed_Orders_For_Survey].[Location]) location, 
      crypt_gen_random(12) as token, 
      [Closed_Orders_For_Survey].[Email] email, 
      'OK' emailstatus, 
      'en' [language], 
      'N' remindersent, 
      [Closed_Orders_For_Survey].[Order Number] attribute_1, 
      CONVERT(VARCHAR(10), [Closed_Orders_For_Survey].[Invoice Date],110) attribute_2 
     from 
      [Closed_Orders_For_Survey] 
     where 
      [Closed_Orders_For_Survey].[Order Date] >= dateadd(DAY, -1, Convert(date, GETDATE())) 
    ) as x 
where 
    not exists (
     select attribute_1 
      from SurveyTable 
      where 
       attribute_1 = x.attribute_1 
     ) 
+0

будет работать, даже если исходный вид содержит номер счета-фактуры в качестве символа и назначения как nvarchar? – d90

+1

Это должно, так как символы char прикладываются к nvarchar, когда они вставлены в любом случае, они должны использовать сравнение таким же образом. –

+0

По какой-либо причине он по-прежнему тянет большинство строк из представления (которые уже импортированы). В представлении есть 6k + строк, а 5140 - в этом запросе. – d90

0

Это может показаться глупым, но если токен является первичным ключом, попытка вставить дубликат токена будет неудачной. Ловушка, что конкретная ошибка в вашем приложении (и энергично игнорировать его), и вы золотой.

Если это должна быть вся одна транзакция, вы всегда можете добавить «и токен не в (выбрать токен из таблицы)», подзапрос (потенциально неэффективный, но должен работать).