Вопрос

Добрый день, при попытке слияния двух контаков, если у проигравшего есть заказ, то процесс дедупликации падает с ошибкой: 

System.Data.SqlClient.SqlException (0x80131904): Конфликт инструкции DELETE с ограничением REFERENCE "FKZt10BIrUNMXjPYmQeSNwKs8aI". 
Конфликт произошел в базе данных "ClarinsInstall", таблица "dbo.Order", column 'ContactId'.

При отладке не увидела ContactId, среди ключей таблицы Order, по которым идет перепривязка данных (есть только CreatedById и OwnerId),
подскажите, с чем это может быть вызвано?

У меня такой же вопрос

3 комментария
Лучший ответ

Зверев Александр пишет:
Проверьте Order в дизайнере объектов, там должно быть такое справочное поле. А если нет, то было и его удалили в объекте, но по какой-то причине осталось в базе (возможно, объект не скомпилировали).

Если проблема, действительно, в этом, то нужно не выполнять обновление конкретной записи в Order, а определиться с необходимостью наличия поля Contact в Order и в зависимости от принятого решения либо добавить в entity schema Order данное поле и скомпилировать схему, если его нет, либо удалить из таблицы в базе данных, если оно не нужно.

Иначе проблема может воспроизвестись при следующем слиянии дублей.

Это как раз и значит наличие записи в Order, ссылающееся полем ContactId на сливаемый контакт. Проверьте Order в дизайнере объектов, там должно быть такое справочное поле. А если нет, то было и его удалили в объекте, но по какой-то причине осталось в базе (возможно, объект не скомпилировали). В таком случае, если есть возможность, подключитесь к БД, найдите эту запись и замените значение ContactId на null.

Зверев Александр пишет:
Проверьте Order в дизайнере объектов, там должно быть такое справочное поле. А если нет, то было и его удалили в объекте, но по какой-то причине осталось в базе (возможно, объект не скомпилировали).

Если проблема, действительно, в этом, то нужно не выполнять обновление конкретной записи в Order, а определиться с необходимостью наличия поля Contact в Order и в зависимости от принятого решения либо добавить в entity schema Order данное поле и скомпилировать схему, если его нет, либо удалить из таблицы в базе данных, если оно не нужно.

Иначе проблема может воспроизвестись при следующем слиянии дублей.

Кстати, не уверен, что повторное добавление поля в объект пройдёт успешно без последствий. У колонки в базе прописывается GUID в Extended Properties, он будет уже другим.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Подскажите, пожалуйста, как можно настроить собственное правило поиска дубликатов среди контрагентов.

BPM Online 7.12

СУБД Oracle 11g

Проблема в том, что большинство инструкций относятся к MS SQL. В Oracle просто не вижу большинство указанных хранимых процедур. Плюс просто не вижу раздела "Правила поиска дубликатов" в Дизайнере системы. Не вижу в БД процедур типа "tsp_FindAccountDuplicateByName", процедура tsp_FindAccountSimilarRecords есть, но там пустышка.

Если я правильно понял, то глобальный поиск дубликатов пока недоступен для Oracle. Нужно хотя бы настроить локальный поиск дубликатов. 

Изменение пакета tspkg_DuplicatesSearch (функции fn_GetAccountDuplicates и процедуры tsp_SearchForAccountDuplicates) результата не дало. 

Вторая проблема: в стандарте вижу, что дубликат проверяется по Name(по крайней мере одно из правил) при изменении карточка контрагента. При создании нового контрагента эта же логика почему-то не работает и можно легко создать дубликаты.

У меня такой же вопрос

6 комментариев

Проверка на дубли при сохранении через миникарточку появилась в 7.12.3. В версии 7.12.3 появился поиск дублей на основании правил для Oracle. В будущих релизах планируется массовая дедупликация для данной СУБД + пользовательская настройка правил + уже можно технически с версии 7.12.3 для новой дедупликации добавить новое правило. Инструкция тут.

Зверев Александр,

Здравствуйте, Александр. 

Спасибо за информацию. Один уточняющий вопрос. У нас на DEV не настроен GlobalSearch (BPM развернут on-site). Однако дедубликация по name срабатывает. Как это может быть?

Видимо, это предыдущая версия, без глобального поиска. Новый то добавили только в 7.12.3:

Для БД Oracle, появилась возможность поиска дублей лидов, а также локального поиска дублей контактов и контрагентов при сохранении. Базовый набор правил поиска можно включать по ссылке “Правила поиска дублей” в дизайнере системы. Для работы поиска дублей на Oracle необходимо настроить глобальный поиск и включить функциональность “ESDeduplication”.

Добрый день. Апдейт на 7.12.3 провели. Global Serach и ESDeduplication включили, правило новое настроили. Видим, что оно работает корректно в миникарточке.

НО при сохранении/изменении в обычной карточке поиск дублей не происходит. Этот функционал для Oracle еще не реализован?

P.S. Стандартные правила также не работают при сохранении/изменении через основную карточку.

Вторая ссылка из моего верхнего комментария уже недоступна, хотя раньше точно была. Видимо, что-то в поддержке работы с Oracle ещё меняют, лучше ещё подождать.

Понятно. Спасибо

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Коллеги, выручайте. У меня были записи в разделе, которые создали разные контакты, но данные контакты по факту являются дубликатами.
Сделал поиск дубликатов для контактов, объединил найденные дубликаты. 

И получилось так, что у части записей затерлось поле "Создал", select возвращает данное поле со старым id создавшего, которого по факту уже нет так-как он объединился.

Как вернуть все обратно? Если возможность посмотреть логи дубликатов?

Я ожидал, что после объединения дубликатов, система сама перезапишет во всех записях поле создал на новый id.

У меня такой же вопрос

1 комментарий

Добрый день!
 

Дедупликация записи - это не создание новой.
Фактически, Вы удаляете одну из записей, и обновляете значения оставшейся.

Вернуть результат дедупликации пользовательскими средствами нельзя.
Вы можете поднять бэкап БД до обновления и перенести значения CreatedBy при помощи запроса в БД.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

В продолжение данного топика 

Правило дедубликации только по телефону не работает. Более того, методом научного тыка было обнаружено следующее:

1) Мы создали правило поиска по телефону и ещё одному полю UsrDedub (по аналогии правило поиска по названию и телефону).

2) Сделали значение UsrDedub = 1 в нескольких контрагентах (около 20). В лиде UsrDedub также = 1. Правило отработало корректно.

3) Сделали значение UsrDedub = 1 для всех контрагентов (около 7 500). Правило работать перестало.

4) Изменили параметр @offsetLimit в SQL запросе tsp_FindAccountSimilarRecords с 200 на 7500. Правило вновь стало работать.

Отсюда мы сделали вывод - правило поиска по телефону отрабатывает только по коллекции контрагентов, которые уже отобраны каким либо правилом поиска дублей.

Копаем дальше, но может кто-то может подсказать:

1) Насколько изменение @offsetLimit может быть критичным для быстродействия системы. Изменение до 10 000 визуально никаки систему не загрузили.

2) Как заставить правило поиска похожих контрагентов по телефону из лида работать самостоятельно, без дополнительных правил поиска.

3) Либо если он работает в паре с другим правилом - в первую очередь проводить поиск именно по телефону?

У меня такой же вопрос

2 комментария

Оказалось, что именно низкий @offsetLimit не позволяет правилу поиска похожих контрагентов по телефону отрабатывать корректно индивидуально. Чем чревато увеличение этого значения - пока не знаю.

Здравствуйте!

1. Если будет слишком большое количество записей, то вполне возможен отвал запроса по timeout.

2, 3.  Для того, чтобы правило поиска похожих контрагентов в лидах работало отдельно, необходимо в хранимой процедуре tsp_FindAccountSimilarRecords изменить блок "IF @execStmt IS NOT NULL..."  на:

               SET @detailsSelectQuery = N'SELECT TOP '+ CAST(@offsetLimit as NVARCHAR) +
                ' ' + @queryColumnName + CHAR(10) + 
                'FROM ' + CHAR(10) + @schemaName + CHAR(10) +
                'WITH (NOLOCK) ' + CHAR(10) +
                'WHERE 1=1 ';

                IF @execStmt IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = 
                    @detailsSelectQuery + CHAR(10) + 'AND' + CHAR(10) + @queryColumnName + CHAR(10) + ' IN ('    + @execStmt + ')';
                END

                IF @equalQueryConditions IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + 
                    @equalQueryConditions;
                END

                IF @inQueryConditions IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + @inQueryConditions;
                END

                IF @detailsSelectQuery IS NOT NULL
                BEGIN
                    INSERT INTO @resultIdsTable
                    EXEC sp_executesql @detailsSelectQuery;
                END

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Кейс следующий: сделать правило дедубликации в разделе лиды по похожим контрагентам с проверкой ТОЛЬКО по телефону. Базовое правило не подходит, поскольку проверяет по названию И телефону.

Добавил правило в DuplicatesRule, добавил процедуру поиска с помощью SQL запроса (см. AccountPhoneRuleUsr). Ничего не выходит. Что интересно, если убрать из базового правила (phoneAndAccountNameRule) упоминание поиска по названию, то он тоже перестаёт отрабатывать в принципе. Такое ощущение, что где-то прописано, что поиск по телефону работает только в паре с каким-то совпадением.

Кто-нибудь сталкивался с данной задачкой?

IF(OBJECT_ID('dbo.tsp_FindAccountSimilarRecords','P')) IS NOT NULL
	DROP PROCEDURE dbo.tsp_FindAccountSimilarRecords
GO
 
CREATE PROCEDURE tsp_FindAccountSimilarRecords (@primaryColumnValue uniqueidentifier, @rawXMLConfig nvarchar(MAX), @offsetLimit int = 200)
AS 
 
 
DECLARE @parsedConfig TABLE (
	SchemaName nvarchar(128),
	ParentShemaName nvarchar(128) NULL,
	ColumnName nvarchar(128),
	ColumnValue nvarchar(4000),
	ColumnValueTypeId nvarchar(128)
 );
 
DECLARE @accountRulesConfig TABLE (
	RuleId uniqueidentifier, 
	SchemaName sysname,
	ParentSchemaName sysname NULL,
	ColumnName sysname, 
	NormalizeFnPattern nvarchar(4000),
	CleanDataSchemaName sysname NULL);
 
DECLARE @xmlBody xml;
 
DECLARE @webAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000013'	,
		@phoneAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000014'	,
		@cityAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000015'	,
		@countryAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000016'	,
		@AccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000017'	,
		@AccountPhoneRuleUsr uniqueidentifier = '778e768d-3941-4461-8954-59702c1f1fab'	,
		@AccountInnRule uniqueidentifier = '1470da34-31ae-4da5-b6c8-9410751133a4'	;
 
DECLARE @leadSchemaUId uniqueidentifier = '41AF89E9-750B-4EBB-8CAC-FF39B64841EC' ;
 
DECLARE @accountSchemaName sysname = 'Account',
		@accountCleanDataSchemaName sysname = 'VwAccountCleanDataValues',
		@accountCommunicationSchemaName sysname = 'AccountCommunication',
		@accountCommunicationCleanDataSchemaName sysname = 'VwAccountCommunicationCleanDataValues',
		@accountAddressSchemaName sysname = 'AccountAddress';
 
DECLARE @accountNameColumn sysname = 'Name',
		@accountInnColumn sysname = 'UsrINN',
		@accountCommunicationColumn sysname = 'Number',
		@accountCommunicationPhoneColumn sysname = 'SearchNumber',
		@accountCountryColumn sysname = 'CountryId',
		@accountCityColumn sysname = 'CityId',
		@communicationTypeIdColumn sysname = 'CommunicationTypeId';
 
DECLARE @resultIdsTable TABLE (Id uniqueidentifier);
 
DECLARE @phoneCommunicationTypeTable TABLE (Id uniqueidentifier);
 
DECLARE @preStmtValues TABLE (
	ColumnName sysname NOT NULL,
	ColumnValue nvarchar (4000) NULL,
	SchemaName sysname NOT NULL,
	ColumnValueTypeId NVARCHAR(128)
);
 
 
DECLARE @emailNormalizePattern nvarchar(50) = N'0-9a-zа-я@_.',
		@nameNormalizePattern nvarchar(50) = N'0-9a-zа-я',
		@normalizedFnSelectStmt nvarchar(250),
		@innNormalizePattern nvarchar(12) = N'0-9',
		@normalizedFnValueStmt nvarchar(250);
 
DECLARE @execStmt nvarchar(MAX),
		@baseNormalizeFn sysname = 'dbo.fn_NormalizeString',
		@phoneNormalizeFn sysname = 'dbo.fn_ExtractDigitLimitFromNumber',
		@webNormalizeFn sysname = 'dbo.fn_ExtractDomainFromUrl';
 
DECLARE @ruleId uniqueidentifier,
		@countDetailValues int = 0;
 
DECLARE @inQueryConditions nvarchar(MAX),
		@equalQueryConditions nvarchar(MAX),
		@schemaName sysname,
		@queryColumnName nvarchar(128);
 
BEGIN
 
 
	SET @xmlBody  = CAST(@rawXMLConfig AS XML);
 
	INSERT INTO @phoneCommunicationTypeTable
	VALUES('0DA6A26B-D7BC-DF11-B00F-001D60E938C6') ,
		('3DDDB3CC-53EE-49C4-A71F-E9E257F59E49') ,
		('D4A2DC80-30CA-DF11-9B2A-001D60E938C6') ,
		('2B387201-67CC-DF11-9B2A-001D60E938C6') ,
		('6A3FB10C-67CC-DF11-9B2A-001D60E938C6') ,
		('E9D91E45-8D92-4E38-95A0-EF8AA28C9E7A') 
 
 
	INSERT INTO @accountRulesConfig (RuleId, SchemaName, ParentSchemaName, ColumnName, NormalizeFnPattern, CleanDataSchemaName)
	VALUES 	(@webAndAccountNameRule, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationColumn,  @webNormalizeFn + '(N##VALUE##)', @accountCommunicationCleanDataSchemaName),
			(@webAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn,  @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')',  @accountCleanDataSchemaName),
			(@phoneAndAccountNameRule, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationPhoneColumn,  @phoneNormalizeFn + '(##VALUE##)', @accountCommunicationCleanDataSchemaName),
			(@phoneAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn,  @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@cityAndAccountNameRule, @accountAddressSchemaName, @accountSchemaName, @accountCityColumn, NULL, NULL),
			(@cityAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@countryAndAccountNameRule, @accountAddressSchemaName, @accountSchemaName, @accountCountryColumn, NULL,NULL),
			(@countryAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@AccountInnRule, @accountSchemaName, NULL, @accountInnColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @innNormalizePattern + ''')', NULL),
			(@AccountPhoneRuleUsr, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationPhoneColumn,  @phoneNormalizeFn + '(##VALUE##)', NULL),
			(@AccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName);
 
	INSERT INTO @parsedConfig
	SELECT NULLIF(p.value('(./schemaName)[1]', 'VARCHAR(128)'),'') AS SchemaName,
		NULLIF(p.value('(./parentSchemaName)[1]', 'VARCHAR(128)'),'') AS ParentSchemaName,
		NULLIF(p.value('(./columnName)[1]', 'NVARCHAR(128)'),'') AS ColumnName,
		NULLIF(p.value('(./columnValue)[1]', 'NVARCHAR(4000)'),'') AS ColumnValue,
		NULLIF(p.value('(./typeId)[1]', 'NVARCHAR(128)'),'') AS ColumnValueTypeId
		FROM @xmlBody.nodes('/columns/item') t(p)
 
	UPDATE	@parsedConfig 
	SET ColumnValue = dbo.fn_GetPhoneNumberSearchForm(ColumnValue)
	WHERE ColumnName = @accountCommunicationPhoneColumn
 
	DECLARE activeRuleList CURSOR
	FOR SELECT Id from DuplicatesRule
		WHERE ObjectId = @leadSchemaUId
		AND Id IN (SELECT RuleId FROM @accountRulesConfig)
		AND isActive = 1;
 
	OPEN activeRuleList
	FETCH NEXT
		FROM activeRuleList INTO @ruleId 
 
	WHILE @@FETCH_STATUS = 0
	BEGIN
 
		SET @execStmt = NULL;
		SET @countDetailValues = 0;
		SET @equalQueryConditions = NULL;
		SET @inQueryConditions = NULL;
 
 
		IF EXISTS (SELECT NULL
			FROM @accountRulesConfig config
			LEFT JOIN @parsedConfig parsed
			ON config.ColumnName = parsed.ColumnName
			AND config.SchemaName = parsed.SchemaName
			WHERE parsed.ColumnName IS NULL 
			AND config.RuleId = @ruleId)
		BEGIN 
			FETCH NEXT
			FROM activeRuleList INTO @ruleId
			CONTINUE
		END
		ELSE
		BEGIN	
			IF EXISTS (
				SELECT NULL
					FROM @parsedConfig parsed, @accountRulesConfig config
					WHERE parsed.ColumnName =config.ColumnName
					AND parsed.SchemaName = config.SchemaName
					AND config.ParentSchemaName IS NULL
					AND parsed.ColumnValue IS NULL
					AND config.RuleId = @ruleId)
			BEGIN
				FETCH NEXT
					FROM activeRuleList INTO @ruleId
				CONTINUE
			END
			ELSE
			BEGIN
				DELETE FROM @preStmtValues
				INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
				SELECT ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)+'.'+rulesCfg.ColumnName,
						CASE WHEN NormalizeFnPattern IS NOT NULL THEN 
							REPLACE(NormalizeFnPattern, '##VALUE##', QUOTENAME(parsedCfg.ColumnValue, ''''))
						ELSE QUOTENAME(parsedCfg.ColumnValue, '''') END ColumnValue, 
						ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)
					FROM @accountRulesConfig rulesCfg, 
						 @parsedConfig parsedCfg
					WHERE rulesCfg.ColumnName = parsedCfg.ColumnName
					AND rulesCfg.SchemaName = parsedCfg.SchemaName
					AND rulesCfg.ParentSchemaName IS NULL
					AND RuleId = @ruleId
 
				SET @queryColumnName = 'Id';
 
				SELECT TOP 1 @schemaName = SchemaName FROM @preStmtValues 
 
				SELECT DISTINCT @inQueryConditions = 
					' AND ' + ColumnName + ' IN (' + STUFF((SELECT ',' + ColumnValue FROM @preStmtValues f 
					WHERE f.ColumnName = t.ColumnName AND f.ColumnName IN (
						SELECT t.ColumnName 
							FROM @preStmtValues t 
						GROUP BY ColumnName HAVING COUNT(*) > 1)
					FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '') +')' FROM @preStmtValues t
 
				SELECT DISTINCT @equalQueryConditions = 
					STUFF((SELECT ' AND ' 
							+ ColumnName + ' LIKE ' 
							+ ColumnValue FROM @preStmtValues f
					WHERE f.ColumnName IN (
						SELECT t.ColumnName 
							FROM @preStmtValues t 
						GROUP BY ColumnName HAVING COUNT(*) = 1) 
					FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '')
 
				SET @execStmt = 
					N'SELECT TOP '+CAST(@offsetLimit as NVARCHAR)+' '+@queryColumnName + CHAR(10) + 
					'FROM '+ CHAR(10) +
					@schemaName + CHAR(10) +
					'WITH (NOLOCK) ' + CHAR(10) +
					'WHERE 1=1'+ CHAR(10);
 
				IF @equalQueryConditions IS NOT NULL
				BEGIN
					SET @execStmt = @execStmt + CHAR(10) + 
					@equalQueryConditions
				END
 
				IF @inQueryConditions IS NOT NULL
				BEGIN
					SET @execStmt = @execStmt + CHAR(10) + 
					@inQueryConditions
				END
 
 
				IF EXISTS (SELECT NULL FROM @accountRulesConfig 
								WHERE RuleId = @ruleId
								AND ParentSchemaName IS NOT NULL)
				BEGIN
					IF EXISTS (
						SELECT NULL
						 FROM @parsedConfig parsed, @accountRulesConfig config
							WHERE parsed.ColumnName =config.ColumnName
								AND parsed.SchemaName = config.SchemaName
								AND parsed.ParentShemaName = config.ParentSchemaName
								AND parsed.ColumnValue IS NOT NULL
								AND config.RuleId = @ruleId)
					BEGIN
 
						DELETE FROM @preStmtValues
						INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName, ColumnValueTypeId)
						SELECT ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)+'.'+rulesCfg.ColumnName, 
							CASE WHEN NormalizeFnPattern IS NOT NULL THEN 
							REPLACE(NormalizeFnPattern, '##VALUE##', QUOTENAME(parsedCfg.ColumnValue, ''''))
							ELSE QUOTENAME(parsedCfg.ColumnValue, '''') END ColumnValue, 
							ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName),
							ColumnValueTypeId
							FROM @accountRulesConfig rulesCfg, 
								 @parsedConfig parsedCfg
							WHERE rulesCfg.ColumnName = parsedCfg.ColumnName
							AND rulesCfg.ParentSchemaName = parsedCfg.ParentShemaName
							AND rulesCfg.SchemaName = parsedCfg.SchemaName
							AND RuleId = @ruleId
 
 
						SET @queryColumnName = 'AccountId';
 
						IF EXISTS (
							SELECT NULL 
								FROM @phoneCommunicationTypeTable 
								WHERE Id in (SELECT ColumnValueTypeId FROM @preStmtValues f))
						BEGIN 
							INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
							SELECT @communicationTypeIdColumn, 
							'''' + CAST(Id AS NVARCHAR(50)) + '''', 
							(SELECT TOP 1 SchemaName FROM @preStmtValues)
							FROM @phoneCommunicationTypeTable
						END
						ELSE 
						BEGIN
							INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
							SELECT @communicationTypeIdColumn, 
							'''' + ColumnValueTypeId + '''',
							SchemaName FROM @preStmtValues
							WHERE ColumnValueTypeId IS NOT NULL
						END	
 
						SELECT TOP 1 @schemaName = SchemaName FROM @preStmtValues 
 
						SELECT DISTINCT @inQueryConditions = 
							' AND ' + ColumnName + ' IN (' + STUFF((SELECT ',' + ColumnValue FROM @preStmtValues f 
							WHERE f.ColumnName = t.ColumnName AND f.ColumnName IN (
								SELECT t.ColumnName 
									FROM @preStmtValues t 
								GROUP BY ColumnName HAVING COUNT(*) > 1)
							FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '') +')' FROM @preStmtValues t
 
						SELECT DISTINCT @equalQueryConditions = 
							STUFF((SELECT ' AND ' 
									+ ColumnName + ' LIKE ' 
									+ ColumnValue FROM @preStmtValues f
							WHERE f.ColumnName IN (
								SELECT t.ColumnName 
									FROM @preStmtValues t 
								GROUP BY ColumnName HAVING COUNT(*) = 1) 
							FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '')
 
						IF @execStmt IS NOT NULL
						BEGIN
							SET @execStmt = 
							N'SELECT TOP '+CAST(@offsetLimit as NVARCHAR)+' '+@queryColumnName + CHAR(10) + 
							'FROM ' + CHAR(10) + 
							@schemaName + CHAR(10) +
							'WITH (NOLOCK) ' + CHAR(10) +
							'WHERE '+ @queryColumnName + CHAR(10) + 
							' IN ('	+ @execStmt + ')';
 
							IF @equalQueryConditions IS NOT NULL
							BEGIN
								SET @execStmt = @execStmt + CHAR(10) + 
								@equalQueryConditions;
							END	
 
							IF @inQueryConditions IS NOT NULL
							BEGIN
								SET @execStmt = @execStmt + CHAR(10) + 
								@inQueryConditions;
							END	
 
							INSERT INTO @resultIdsTable
							EXEC sp_executesql @execStmt;
						END
					END
				END
				ELSE
				BEGIN
					INSERT INTO @resultIdsTable
					EXEC sp_executesql @execStmt;
				END
			END
		END
 
	FETCH NEXT
		FROM activeRuleList INTO @ruleId
	END
	CLOSE activeRuleList
	DEALLOCATE activeRuleList
 
	DELETE
		FROM @resultIdsTable
		WHERE Id = @primaryColumnValue
 
	SELECT DISTINCT TOP (@offsetLimit) Id 
		FROM @resultIdsTable
 
END

 

У меня такой же вопрос

3 комментария

Здравствуйте, Данил!

Кастомизация правил поиска похожих лидов осуществляется по инструкции ниже.

1. Необходимо добавить скриптом новое правило в таблицу DuplicatesRule.

Пример скрипта:

insert into DuplicatesRule

(Name, IsActive, ObjectId)

values

('Имя правила', 1, '41AF89E9-750B-4EBB-8CAC-FF39B64841EC')

 

2. Заместить хранимую процедуру tsp_FindAccountSimilarRecordsMSSQL (для примера поиска по контрагентам, по контактам соответственно tsp_FindContactSimilarRecordsMSSQL). Для этого необходимо скопировать весь код из tsp_FindAccountSimilarRecordsMSSQL и дублировать его в новый SQL Script.

3. Объявить своё правилj в блоке с остальными правилами, где указать id добавленного правила с пункта 1 (из таблицы DuplicatesRule) http://prntscr.com/e2m5wz

4. Аналогично существующим правилам, добавить и своё в @accountRulesConfig http://prntscr.com/e2m72y

Например, если правило только для Телефона, копируем выделенную строчку на скриншоте и заменяем название правила на кастомное: http://prntscr.com/i5yogj 

5. Сохранить хранимую процедуру и выполнить установку в БД.

Если привязаться к Вашему коду, то ошибка вероятнее всего в п. 4. , т.к. правило определено неправильно: http://prntscr.com/i5yppg

 

Приятной работы

 

Пробовал и полностью скопировав это правило (если вы про отсутствие @accountCleanDataSchemaName в конце) - не работает.

Что интересно, если я прописываю правило с поиском по ИНН+Телефон, то поиск отрабатывает корректно - проверяет совпадение в обоих полях. Но как только пробую оставить ТОЛЬКО по телефону, то такая дедубликация не работает.

Здравствуйте!
Правила поиска дублей для похожих контрагентов/контактов в лиде сделаны таким образом, что нет возможности обращаться отдельно к таблице средств связи, по которой и происходит поиск только по телефону. Логика хранимых процедур была написана с учётом базовых правил, которые предполагают поиск похожих контактов/контрагентов только по правилам, которые включают поиск в таблице Account/Contact плюс таблица средств связи. А обращение только к таблице средств связи в текущей реализации хранимой процедуры не предусмотрено.

Для работы своего правила только по телефону или любого другого средства связи, необходимо внести изменения в хранимую процедуру tsp_FindAccountSimilarRecords, а именно вместо блока "IF @execStmt IS NOT NULL..."  (http://prntscr.com/ibe672) добавить код ниже:

               SET @detailsSelectQuery = N'SELECT TOP '+ CAST(@offsetLimit as NVARCHAR) +
                ' ' + @queryColumnName + CHAR(10) + 
                'FROM ' + CHAR(10) + @schemaName + CHAR(10) +
                'WITH (NOLOCK) ' + CHAR(10) +
                'WHERE 1=1 ';

                IF @execStmt IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = 
                    @detailsSelectQuery + CHAR(10) + 'AND' + CHAR(10) + @queryColumnName + CHAR(10) + ' IN ('    + @execStmt + ')';
                END

                IF @equalQueryConditions IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + 
                    @equalQueryConditions;
                END

                IF @inQueryConditions IS NOT NULL
                BEGIN
                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + @inQueryConditions;
                END

                IF @detailsSelectQuery IS NOT NULL
                BEGIN
                    INSERT INTO @resultIdsTable
                    EXEC sp_executesql @detailsSelectQuery;
                END

Войдите или зарегистрируйтесь, чтобы комментировать