Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
 Уникальный индекс с пустым значением  [new]
vassil
Member

Откуда: Хабаровск
Сообщений: 112
Есть уникальный индекс из нескольких свойств IndexAka.

Index IndexAka On (tradingNetwork, goodsGroup, aka) [ Data = aka, Unique ];

Property aka As %String(MAXLEN = 300,TRUNCATE=1) ;

Index goodsGroupIndex On goodsGroup;

Relationship bonusOperationGoods As doc.BonusOperationGoods(JSONIGNORE = 1) [ Cardinality = many, Inverse = goodsName ];

Property tradingNetwork As ent.TradingNetwork;

Relationship goodsGroup As ent.GoodsGroup [ Cardinality = one, Inverse = goodsName ];

Property goodsGroupList As list Of %String(MAXLEN = 300);

/// Артикул товара
Property marking as %String;


Если например, группа не указана (goodsGroup), то выражение

set groupId = ""
&sql(INSERT OR UPDATE into ent.GoodsName (tradingNetwork,aka,goodsGroup,goodsGroupList,marking) 
 		values (:accountId,:goodsName,:groupId,:groupList,:marking))

не обновляет уже существующую запись, а создает еще одну такую же с пустой группой. Как сделать, чтобы пустое значение тоже участвовало в уникальности?
10 мар 19, 15:09    [21828706]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
logist
Member

Откуда: InterSystems
Сообщений: 275
vassil,

Я не совсем понял - ты хочешь чтобы aka было уникальным или триплет (tradingNetwork, goodsGroup, aka)?

Как у тебя объявлено - это должно быть одно из 3 уникальное (т.е. триплет уникальный)

Кстати Data=aka не имеет смысла если aka в самом индексе
11 мар 19, 05:52    [21828851]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
vassil
Member

Откуда: Хабаровск
Сообщений: 112
logist,
триплет (tradingNetwork, goodsGroup, aka) чтобы был уникальным.
11 мар 19, 15:42    [21829319]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
Блок А.Н.
Member

Откуда: Новосибирск
Сообщений: 3811
vassil,

мне кажется, плохая практика использовать insert or update без явного указания полей естественного ключа.
А ваша ситуация, кажется, из-за этого: INSERT OR UPDATE determines of a record exists by matching UNIQUE KEY field values to the existing data values. If a UNIQUE KEY violation occurs, INSERT OR UPDATE performs an update operation. Note that a UNIQUE KEY field value may not be a value explicitly specified in INSERT OR UPDATE; it may be the result of a column default value or a computed value.
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_insert

Т.е. она сначала делает insert, а потом, если он не удался, update. Я, честно говоря, думал, что null участвует в уникальности.
11 мар 19, 18:26    [21829616]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
logist
Member

Откуда: InterSystems
Сообщений: 275
vassil,

действительно посмотрел сейчас - пустые поля не участвуют в проверке на уникальность:

zIndexAkaCheckUnique(id="",pValue...) [ SQLCODE,id,pValue ] public { New %ROWCOUNT,%ROWID,%msg,SQLCODE 
	if ($Get(pValue(1))'="")&&($Get(pValue(2))'="")&&($Get(pValue(3))'="") {
		 ;---&sql(SELECT 1 as _PassFail FROM zTRAK_SSH.UniqueTest WHERE tradingNetwork = :pValue(1) AND goodsGroup = :pValue(2) AND aka = :pValue(3) AND %ID <> :id)
 		 ;--- ** SQL PUBLIC Variables: %ROWCOUNT, %ROWID, %msg, SQLCODE, id, pValue
		do %0Ro
		Quit SQLCODE=100
	} else { quit 1 } }
 q


https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_createtable#RSQL_createtable_fconstraints

The UNIQUE data constraint specifies that this field accepts only unique values. Thus, no two records can contain the same value for this field. The SQL empty string ('') is considered to be a data value, so with the UNIQUE data constraint applied, no two records can contain an empty string value for this field. A NULL is not considered to be a data value, so the UNIQUE data constraint does not apply to multiple NULLs. To restrict use of NULL for a field, use the NOT NULL keyword constraint.

Я думаю что простейший способ обойти это ограничение - сделать вычисляемое поле, которое будет принимать не-пустое значение для пустого goodsGroup

Класс:

Class zTRAK.SSH.UniqueTest Extends %Persistent
{

Index IndexAka On (tradingNetwork, goodsGroupIndexed, aka) [ Data = aka, Unique ];

Property aka As %String(MAXLEN = 300, TRUNCATE = 1);

Index goodsGroupIndex On goodsGroup;

Property tradingNetwork As %Numeric;

Property goodsGroup As %Numeric;

Property goodsGroupIndexed As %Numeric [ SqlComputeCode = {set {*}=+{goodsGroup}}, SqlComputed ];

Property goodsGroupList As list Of %String(MAXLEN = 300);

ClassMethod Run()
{
	do ..%KillExtent()
	set accountId=1,goodsName="g1",groupId="",groupList=""
	&SQL(INSERT OR UPDATE INTO zTRAK_SSH.UniqueTest (tradingNetwork,aka,goodsGroup,goodsGroupList)
		VALUES (:accountId,:goodsName,:groupId,:groupList))
	write "run 1: ",SQLCODE,!
	set accountId=1,goodsName="g1",groupId="",groupList=""
	&SQL(INSERT OR UPDATE INTO zTRAK_SSH.UniqueTest (tradingNetwork,aka,goodsGroup,goodsGroupList)
		VALUES (:accountId,:goodsName,:groupId,:groupList))
	write "run 2: ",SQLCODE,!
	quit $$$OK
}


}



Пример:

DEV>w ##class(zTRAK.SSH.UniqueTest).Run()                         
run 1: 0
run 2: 0
1
DEV>zw ^zTRAK.SSH.UniqueTestI                                     
^zTRAK.SSH.UniqueTestI("IndexAka",1,0," G1",1)=$lb("","g1")
^zTRAK.SSH.UniqueTestI("goodsGroupIndex",-100000000000000,1)=""

DEV>zw ^zTRAK.SSH.UniqueTestD
^zTRAK.SSH.UniqueTestD=1
^zTRAK.SSH.UniqueTestD(1)=$lb("","g1",1,"","",,0)
12 мар 19, 04:20    [21829895]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
vassil
Member

Откуда: Хабаровск
Сообщений: 112
Хорошо, спасибо за информацию.
12 мар 19, 05:14    [21829899]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
ser_shu
Member

Откуда: Хабаровск
Сообщений: 243
vassil, пустые значения не контролируются на уникальность на уровне %Save().
можно поставить Type=key, но там свои заморочки, пустое превращается в -1000000000(0), строки пишутся "как есть".
обычно пустые значения не допускаются там, где требуется уникальность, так что никто и не влетает.
12 мар 19, 11:19    [21830025]     Ответить | Цитировать Сообщить модератору
 Re: Уникальный индекс с пустым значением  [new]
ser_shu
Member

Откуда: Хабаровск
Сообщений: 243
logist
vassil,
...
Кстати Data=aka не имеет смысла если aka в самом индексе

смысл небольшой есть, так как в индексе значение aka преобразованное (тип string).
13 мар 19, 02:49    [21830890]     Ответить | Цитировать Сообщить модератору
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить