Wednesday, September 14, 2016

Take a backup of particular tables data in SQL

Some cases we need to delete the data from the table. We can delete the record from AX or directly from SQL database by using delete SQL. Before delete the record, we are checking more than 3 times. Because, it is all business data.

If we have deleted the wrong data, we can’t revert back if you weren’t take the backup before delete. So backup process is necessary before do the delete operation. Database backup and restore will take more time. Instead of taking a whole database backup we can take a particular table data backup before do the delete operation for a particular table.

We can take the table data backup through SQL Server Management Studio. SSMS having an option for table data backup.

Here, I will share the screenshots step by step.





Select the table(s) that you want to take a backup

Mention the backup SQL file path.

Select the data only option




To restore the data, you can open the output SQL file in SQL Server Management Studio and connect the server and execute the SQL file script.

Thank you.

Saturday, August 27, 2016

Cross-reference create is taking long time but not completed (Never ending)

I tried to update the cross-reference, but the cross-reference update progress is not completed. It is only showing that it is in progress.

To create/update the cross-reference, in the development workspace, open the Tools menu, and then click Cross-reference > Periodic > Update

I have referred into this link http://www.agermark.com/2014/05/cross-reference-update-never-finishing.html to solve this issue. But, I couldn’t complete a single step. Because, the cross-reference update is not completed.

After that, I have noticed that the cross-reference progress dialog box is not showing the proper status. When the cross-reference is updating, in the progress window, we could able to find that which object is in progress.

I have checked that the following cross-reference table’s rows count from SQL Server Management Studio. The table rows are inserted.
  1. XREFNAMES
  2. XREFDIALOGUPDATE
  3. XREFREFERENCES
  4. XREFPATHS
  5. XREFTABLERELATION

So, this is a problem.

The cross-reference update is running based on the batch job. When we call the cross-reference update, it will create a batch job and starting that batch job. If the batch is not updating or showing waiting status not showing the executing status then cross-reference progress box won’t show any updated message. Simply it will display the update animation never complete.

The problem is that incremental CIL have some issue. I cleared the XppIL folder files, full CIL and did the incremental CIL. Incremental CIL is running successful.

I again started the cross-reference update process. It worked fine.

If the batch job is working fine, then the cross-reference will work.


Note: The cross-reference may take long time based on the server performance at first time.

Cross-reference tool

Introduction to cross-reference tool:

Cross-reference tool is one of the Microsoft Dynamics AX IDE. It is used to find the relationships between the objects. If you want to know what are the objects are used in a particular class or what are the objects are using a particular class, you can use cross-reference tool.
For example:
I have one output menu item, but I don’t know where this menu item is used. I need to find the menus for the particular menu item. So, the solution is that I have to look all module menus manually. Instead of finding manually, we can use cross-reference tool.

To find the menus for the particular menu item:

Right click on the menu item > Add-Ins > Cross-reference - > used by
It will give you the list of objects that are using this menu item. In the result window, you can find the menus object also.

If you click using option, it will give you the list of objects used in the selected menu item. It may give you the form of the selected output menu item.


Cross-reference results are coming from the following tables.

  1. XREFNAMES
  2. XREFDIALOGUPDATE
  3. XREFREFERENCES
  4. XREFPATHS
  5. XREFTABLERELATION

To create/update the cross-reference

By default, cross-reference don’t have data. To create the cross-references you need to configure manually by navigating to, in the development workspace, open the Tools menu, and then click Cross-reference > Periodic > Update. The Update cross-reference window appears. Select update all and click OK button. It will create a batch job and start running the batch job.

After completed the cross-reference update, if you create a new object in AOT, that created object reference won’t be updated automatically in cross-reference. We need to do manually by right click on the object > Add-Ins > Cross-reference > Update. You need to do the same job again after you modified the object.

Automatic cross-reference update

Instead of doing this manually, we can set automatic process when the compiler compile the objects. To set this option, development workspace > Tools > Option > Development > click compiler button > check cross-reference checkbox and click OK button.

It will affect your performance, because it will run whenever compiler compiles the objects. If you don’t want immediate update, you can go for the scheduling process for every week or end of the day or etc. Refer into this link for cross-reference scheduling https://msdn.microsoft.com/en-us/library/cc566587.aspx.

For more information, please refer https://msdn.microsoft.com/EN-US/library/aa626961.aspx

Thursday, August 18, 2016

Cannot create a record in SysXppAssembly (SysXppAssembly). The record already exists.

I have done some changes in one class. That class is running on the server side. It is related to the service operations. The attribute SysEntryPointAttribute is used in that class method for decorate. This class is used for batch job process. The problem is that my changes are not reflecting.

The solution for this issue is that we need to do the incremental CIL. So, I tried the incremental CIL. But, I got one error message “Cannot create a record in SysXppAssembly (SysXppAssembly). The record already exists.”

I thought AOS restart will solve this issue, but not worked.

So, I did the following steps. It worked.

  1. Stop the AOS
  2. Navigate to the XppIL folder in your AOS server “C:\Program Files\Microsoft Dynamics AX\60\Server\YourAXInstanceName\bin\XppIL”
  3. Backup the files from the XppIL folder.
  4. Delete the files from the XppIL folder. Note: files only not sub folders.
  5. Restart the AOS
  6. The XppIL folder files will be created after the AOS restart


I tried the incremental CIL, Incremental CIL is completed successfully.

Whenever we created/modified the class that is used for batch job process, we need to do the incremental CIL.

Aug 19, 2018: I faced the same issue today. I tried to delete the XppIL folder files but no luck. My solution is not worked.

I found one post in the community, as per post I have done the following steps to resolve this issue.

  1. Stopped AOS service
  2. Deleted the XppIL folder files
  3. Truncated the model database SysXppAssembly table in the SQL management table (TRUNCATE TABLE SysXppAssembly).
  4. Started the AOS service


It created the files in the XppIL folder and also created the record in the SysXppAssembly table. Its worked.

Happy :)

Thursday, August 11, 2016

Recreate development environment from stage environment

When we install AX hotfix, first we need to install in development. Once it is installed and tested successfully then we can move to stage and everything is fine in stage then we can move to production by using model store deployment. This is the best practices suggested by Microsoft.
But, sometimes the hot fixes are installed directly on stage and production not in development then we will face objects version issue. If mismatch hotfix between stage and development is only one, we can install hotfix directly in development. But, if it is more than, we need to install one by one.

Instead of installing missing hotfixes one by one, we can recreate the development environment from stage environment by using two methods.
  1. Model store move
  2. Restoring the database and work on the settings section


For the first method,

  1. we need to do the model store move with id conflict overwrite option from stage to development
  2. Full CIL
  3. Incremental CIL
  4. You may face the id conflict issue when you do the database synchronization. Id conflict issue is AOT and SQL database table id/ field id is different. What we need to do is update/match the AOT id in SQL table manually. You could get more detail into the link https://blogs.msdn.microsoft.com/axsupport/2012/09/19/troubleshooting-aot-synchronization-errors/ To update through AX with multiple tables, you might refer into the link http://dev.goshoom.net/en/2011/11/id-change/
I got the below error message when I did the synchronization. The message saying that field id is already using by another field.
Illegal data conversion from original field PURCHPARAMETERS.TestField to PURCHPARAMETERS.ProductReceiptCharges: Unable to convert data types to anything but character field type (0 to 4).

This method is already explained in “Deploying customizations across Microsoft Dynamics AX 2012 environments” white paper in the topic “Recreate the staging environment from the production system”. You could download the whitepaper into this link https://www.microsoft.com/en-in/download/details.aspx?id=26571


For the second method, you can refer into this link

Wednesday, April 6, 2016

Handle table validations in X++

When we try to insert a record in a table by using X++, we use the insert method, but when we call the insert method, it won’t consider all mandatory fields are entered or not. It allows the empty values even the field is mandatory. This mandatory validation logic are developed on the validate write method. Think is that validate method is not called default when we call the insert or update method.

So, as per the Microsoft best practice document, we need to call the validate write method before we call the insert or update method.

Note: AX forms call the validatewrite method default when we insert or update the records through form.


For example:

static void Hari_TestInsertMethod(Args _args)
{
    Hari_ClassTest   classTest;
   
    classTest.Class = '2nd';
    classTest.Description = 'Description';

    if(classTest.validateWrite())
    {
        classTest.insert();
        info('Record inserted successfully');
    }
}


The second point is that we can build the validation for each field by using validatefield method. This method is called default when we enter the value in the form. But this validatefield method is not called default when we use the insert or update method even if we call the validatewrite method.


For validate field example, I have created one validation in the table validatefield method.

public boolean validateField(FieldId _fieldIdToCheck)
{
    boolean ret;

    ret = super(_fieldIdToCheck);
   
    if(ret)
    {
        switch (_fieldIdToCheck)
        {
            case fieldNum(Hari_ClassTest, Description):
                if(this.Description == 'Description')
                {
                    checkFailed("The value shouldn't be description");
                    ret = false;
                }
                break;
        }
    }

    return ret;
}


To call the validatefield and validatewrite method when we call the insert or update method, we can create a new validate method in a new class. Refer the below method named validateRecord. The functionality is that this method call all field’s validatefield method and validatewrite method manually.

public static boolean validateRecord(common _common)
{
    boolean     ret = true;
    DictTable   dictTable = new DictTable(_common.TableId);
    int         fields;
    int         i;

    fields = dictTable.fieldCnt();
    //iterate through each field and validate it
    for(i = 1; i<= fields; i++)
    {
        ret = ret && _common.validateField(dictTable.fieldCnt2Id(i));
    }

    //validate the record itself over here
    ret = ret && _common.validateWrite();

    return ret;
}


Insert the value by using validateRecord method:

static void Hari_TestInsertMethod(Args _args)
{
    Hari_ClassTest   classTest;
   
    classTest.Class = '2nd';
    classTest.Description = 'Description';
    if(Hari_TableValidations::validateRecord(classTest))
    {
        classTest.insert();
        info('Record inserted successfully');
    }
}