While Loop

Hello everyone,

I need to do a expression rule which will return a unique code.

So my expression will need to generate a code (done already), verify if exists already in the database, if yes, the expression will need to generate another code, until it does not exists in the database.

I checked loop functions in Appian and does not find the While loop function, but rather functions with known iteration like "forEach", "apply".

Thank you in advance.

Nanbei

  Discussion posts and replies are publicly visible

  • Hello Nanbei,

    First and foremost, it is not recommended to run the query entity(or any kind of DB calls) inside a loop. You can create a stored procedure and move the same logic to the database side. So that the performance will not be affected and you can use the while loop in the Stored Procedure.

    Or if the code is just a unique number, then you can just make of use of the auto-generated primary key column.

  • 1) Try this if your list will be small

    foreach(

    local!List,

    load(

    local!id: queryEntity.data.id {query on individual field},

    if(isnull(local!id),

    ##generatecode##,

    local!id

    )

    )

    ),

    2) If list is big, 

    load(

    local!queryList:##Query all the ids##

    foreach(

    local!list,

    load(

    local!code:displayvalue(fv!item.id,local!queryList.id,local!queryList.code,"")

    if(isnull(local!code),##generateCode##,local!code)

    )

    )


    3) Performance wise best way to do this using Cursor inside the stored procedure. 

  • 0
    Certified Lead Developer

    I only recommend this basic approach if your domain (the number of codes possible) is much, much larger than the number of codes generated.

    I assume that your "codes" are pseudo-random generated values.  If you're going to try to create 100,000 codes for 50,000 people, you DO NOT WANT to generate codes randomly and see if they're already in the database.  Half your codes are used at the end, then it becomes how many times do you flip a coin before it finally comes up tails?  Twice?  Fifteen times?  Though unlikely, you could theoretically need to retry several thousand times. 

    If you're trying to generate 50,000 codes for 50,000 people, the last code would only have 1 in 50,000 odds of success of working the first time, and only 1 in 50,000 odds of working the second time, or the third, or any time after that.  You still have less than 20 percent chance of having found it after 10,000 attempts.

    If you're going to go the route of generating codes at random, then trying again if you have a match, you need to make the chances of a match astronomically slim, something like 10,000 times as many possible values as there are values that are actually being used.  You'll still have to be capable of withstanding a performance hit of several retries in a row.  No matter how unlikely it becomes to retry 50 times before you find an unused code, it always remains possible.

    Exact expectations placed on random numbers and performance just in general don't go together.  The most inefficient sorting algorithm ever invented, which can theoretically take an infinite amount of time to process, is the most inefficient ever because it uses randomization.  See Bogosort.

  • This seems almost wastefully expensive.

    By that I mean this is excess, inefficient process.  Don't guess and check new codes.

    I expect there are at least 2 alternatives, (but probably more)

    1st - https://community.appian.com/w/the-appian-playbook/846/generating-guids - you can make a guild with expressions.

    2nd - both Oracle and SQL server will manage unique sequences for you, you should be able to pull them.

    3rd - if you don't have the luxury of Oracle or SQL Server, you can  make a "codes" table in mySQL where the PK is your new code.  just make new rows in that table and use the id value as your code.  It doesn't have to start at 1.

  • 0
    Certified Lead Developer

    At least 3 other possibilities.

    One might be to find one of the codes already used in the database at random, find the next code after that in sequence, and create a random code between them.  That way you ensure that you always generate a random unused code each time.  If you had adjacent values that a code wouldn't fit between, you'd keep moving up until the next used code was more than one space away.

    Another method would be to randomly assign a first digit from list of unused first digits and randomize the rest of the string.  Then after all first digits are used, randomly assign a used first digit and randomly assign a second digit from unused second digits, until all those are used, then unused third digits and so on.  For a numeric code, you'd be traversing a tree structure with each node having 10 branches.  For alphabet codes, each node would have 26 branches.  Again, unique codes would be guaranteed but it would still be pseudorandom.

    If you have a very small list of possible codes, like 100,000, you could make a set of all permutations and store it in a database table before the app goes live.  When a code is needed, select a row from that database table at random, return it, and then delete the row.  All will eventually be used, but in random order.  Or you could create the list, randomize it before it goes live, and return the first row and delete it every time.

  • thank you for your reply, and sorry to reply you this late.

    I solved the issue by generating a new type of code.

    I asked the previous question because the application which I am developping need to import data from other data bases and to avoid any conflicts I finally generate a new type of code from Appian.

    Thank you :)