web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Any way around unique index 16 column max

(0) ShareShare
ReportReport
Posted on by 6,648

Hi All,

I added one filed in 'InventPosting' table and i want to add this field to 'ItemIdx' index.

when synchronize,i face with below error.

idx.png

You have solution for increase the maximum limit for index key column list??

Regards Hossein

*This post is locked for comments

I have the same question (0)
  • Verified answer
    Douglas Noel Profile Picture
    3,907 on at

    Hi,

    think this is more a specific sql question. Nevertheless, Ax isn't capable to generate such calculated indices, beside you create them by 'code' or manually.

    But, the normal (Ax standard way) solution to overcome this restriction and have a uniquess over more than the 16 fields which is handled by a unique index on sql side, is using some kind of hashfield (which is calculated from the index fields), filled by the insert update operations of ax table methods and put an ax unique index on that field.

    This is used in table inventdim, where you can have this situation if everything is 'enabled'.

    Here a hascode is calculated (!!! Configkey InventdimUniqueness has to be enabled) from the other fields.

    The combined index is restricted to the 16 fields (!! Dataareaid, partition) and is not unique, but the hashcode index.

    Maybe you have to add more non unique indices for optimize the execution on certain queries.

    Regards Douglas

  • Verified answer
    Hossein.K Profile Picture
    6,648 on at

    Hi Everybody,

    Add a persisted computed column that combines the 18 keys, then create an unique index on the computed column:

    alter table t add all_keys as c1+c2+c3+...+c18 persisted;
    create unique index i18 on t (all_keys);

    See Creating Indexes on Computed Columns.

    Another approach is to create an indexed view:

    create view v 
    with schemabinding
    as select c1+c2+c3+...+c18 as all_keys
    from dbo.t;
    
    create unique clustered index c18 on v(all_keys);

    See Creating Indexed Views.

    Both approaches allow for a partial key aggregate: aggregate c1+c2+c3 as k1, c4+c5+c6 as k2 etc. then index/create indexed view on (k1, k2, ...). Thia could be beneficial for range scans (index can be used for search on c1+c2+c3.

    Of course, all + operation in my example are string aggregation, the actual operator to use depends on the types of all those columns (ie. you may have to use explicit casts).

    PS. As unique constraints are enforced by an unique index, any restriction on unique indexes will apply to unique constraints as well:

    create table t (
        c1 char(3), c2 char(3), c3 char(3), c4 char(3),
        c5 char(3), c6 char(3), c7 char(3), c8 char(3),
        c9 char(3), c10 char(3), c11 char(3), c12 char(3),
        c13 char(3), c14 char(3), c15 char(3), c16 char(3),
        c17 char(3), c18 char(3), c19 char(3), c20 char(3),
        constraint unq unique
          (c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18));
    go  
    
    
    Msg 1904, Level 16, State 1, Line 3
    The index '' on table 't' has 18 column names in index key list. 
    The maximum limit for index or statistics key column list is 16.
    Msg 1750, Level 16, State 0, Line 3
    Could not create constraint. See previous errors.

    However, creating the constraint on a persisted computed column works:

    create table t (
        c1 char(3), c2 char(3), c3 char(3), c4 char(3),
        c5 char(3), c6 char(3), c7 char(3), c8 char(3),
        c9 char(3), c10 char(3), c11 char(3), c12 char(3),
        c13 char(3), c14 char(3), c15 char(3), c16 char(3),
        c17 char(3), c18 char(3), c19 char(3), c20 char(3),
        all_c as 
            c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11+
            c12+c13+c14+c15+c16+c17+c18 
            persisted
            constraint unq unique (all_c));
    go  



    Obviously, the persisted column consumes the space on disk so the approach may be bad for a very large table. The indexed view approach does not have this problem, it only consumes the space for the index, not the space for the computed column and index.

    Thanks
  • Verified answer
    Hossein.K Profile Picture
    6,648 on at

    Hi All,

    My problem has been resolved.you should use these function for increase index limit.i want to add one field('InventPostingProductType') to 'InventPosting' table.

    1- first,I add one field that is called 'SHA1Hash' field in my table

    2-I delete one of the index field that is called(CostRelation)

    3-I add 'SHA1Hash'  to my index

    4-With below functions,I produce SHA1Hash

    public str hashKey()
    {
    str hashKey = '';
    str hashKeyCaseInsensitive = '';#InventDimDevelop/*
    SQL Server has a limitation of 16 fields in one index. For InventDim this is a problem if extra dimensions are added in an installation.
    Instead we have added a new field which can store hashed values of the least used dimensions.
    The class InventDimUniquenessEnabling can be used to validate if the proper indexes are defined and this method includes the right fields.Create a string this is unique for every combination of the dimensions. This can for example be achieved by using the code pattern below for each field included in the hash.
    The field values must be trimmed for trailing spaces, as this method is invoked before insert() - where such trimming also occurs.if (this.<FieldName>)
    {
    hashKey += (hashKey ? '~' : '') + '<FieldName>:' + strRTrim(this.<FieldName>);
    }
    */// Due to index limitations, hash the values.
    if (this.InventPostingProductType)
    {
    hashKeyCaseInsensitive += (hashKey ? '~' : '') + 'InventPostingProductType:' + int642str(this.InventPostingProductType);
    }if (this.CostRelation)
    {
    hashKeyCaseInsensitive += (hashKeyCaseInsensitive ? '~' : '') + 'CostRelation:' + strRTrim(this.CostRelation);
    }return hashKey + strLwr(hashKeyCaseInsensitive);
    }

    public InventDimSHA1Hash hashValue()

    {

    str hashKey;

    InteropPermission permission;

    System.IO.MemoryStream hashStream;

    Binary hash;

    hashKey = this.hashKey();

    if (hashKey == '')

    {

    return conNull();

    }// Calculate the hash and convert it into a Binary

    permission = new InteropPermission(InteropKind::ClrInterop);

    permission.assert();hashStream = Microsoft.Dynamics.AX.Fim.Dimensions.Hash::ComputeSHA1Hash(hashKey);

    hash = Binary::constructFromMemoryStream(hashStream);

    hashStream.Close();

    CodeAccessPermission::revertAssert();return hash.getContainer();

    }

    5-finally, I add below code to 'insert' and 'update' methods of my table(InventPosting)

    this.sha1Hash = this.hashValue();

    super();

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the April Top 10 Community Leaders

These are the community rock stars!

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
CP04-islander Profile Picture

CP04-islander 39

#2
Michel ROY Profile Picture

Michel ROY 14

#3
imran ul haq Profile Picture

imran ul haq 8

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans