IT tutorials
 
Applications Server
 

Microsoft Dynamic AX 2009 : Syntax (part 2) - Statements - Data-Aware Statements

10/1/2011 5:48:29 PM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

Statements

X++ statements specify object state and object behavior. Table 3 provides examples of X++ language statements that are commonly found in many programming languages.

Table 3. X++ Statement Examples
StatementExample
assignment statement
int i = 42;
;
i = 1;
i++;
++i;
i--;
--i;
i += 1;
i -= 1;

compound statement
int i;
{
i = 3;
i++;
}

print statement
int i = 42;
;
print i;
print "Hello World";
print 5.2;
pause;

if statement
boolean b = true;
int i = 42;
;
if ( b == true )
{
i++;
}
else
{
i--;
}

break statement
int i;
;
for ( i = 0; i < 100; i++ )
{
if ( i > 50 )
{
break;
}
}

continue statement
int i;
int j = 0;
;
for( i = 0; i < 100; i++ )
{
if ( i < 50 )
{
continue;
}
j++;
}

while statement
int i = 4;
;
while ( i <= 100 )
{
i++;
}

do while statement
int i = 4;
;
do
{
i++;
}
while ( i <= 100 );

for statement
int i;
;
for ( i = 0; i < 42; i++ )
{
print i;
pause;
}

switch statement
str s = "test";
;
switch ( s )
{
case "test" :
print s;
break;
default :
print "fail";
}
pause;

pause statement
print "Hello World";
pause;

window statement
window 100, 10 at 100,10;
print "Hello World";
pause;

breakpoint statement
breakpoint; //Causes the debugger to be invoked

return statement
int foo()
{
return 42;
}

throw statement
throw error("Error text");

try statement
try
{
throw error("Force exception");
}
catch( exception::Error )
{
print "Error";
pause;
}
catch
{
print "Another exception";
pause;
}

retry statement
try
{
throw error("Force exception");
}
catch( exception::Error )
{
retry;
}

.NET CLR interoperability statement
System.Text.StringBuilder sb;
sb = new System.Text.StringBuilder();
sb.Append("Hello World");
print sb.ToString();
pause;

local function
static void myJob(Args _args)
{
str myLocalFunction()
{
return "Hello World";
}
;
print myLocalFunction();
pause;
}

system function
guid g = newguid();
;
print abs(-1);

flush statement
MyTable myTable;
;
flush myTable;

changecompany statement
MyTable myTable;
;
while select myTable
{
print myTable.myField;
}
changecompany("ZZZ")
{
while select myTable
{
print myTable.myField;
}
}
pause;


Data-Aware Statements

The X++ language has built-in support for querying and manipulating database data. The syntax for database statements is similar to Structured Query Language (SQL), and this section assumes that you’re familiar with SQL. The following code shows how a select statement is used to return only the first selected record from the MyTable database table and how the data in the record’s myField field is printed.

static void myJob(Args _args)
{
MyTable myTable;
;
select firstOnly * from myTable where myTable.myField1=='value';
print myTable.myField2;
pause;
}


The “* from” part of the select statement in the example is optional. You can replace the asterisk (*) character with a comma-separated field list, such as myField2, myField3. You must define all fields, however, on the selection table model element, and only one selection table is allowed immediately after the from keyword. The where expression in the select statement can comprise any number of logical and relational operators. The firstOnly keyword is optional and can be replaced by one or more of the optional keywords. Table 4 describes all the possible keywords.

Table 4. Keyword Options for select Statements
KeywordDescription
FirstfastFetches the first selected record faster than the remaining selected records.
Firstonly Firstonly1Returns only the first selected record.
Firstonly10Returns only the first 10 selected records. Supported only on the Oracle database platform.
Firstonly100Returns only the first 100 selected records. Supported only on the Oracle database platform.
Firstonly1000Returns only the first 1000 selected records. Supported only on the Oracle database platform.
ForupdateSelects records for updating.
NofetchSpecifies that the Dynamics AX runtime should not execute the statement immediately because the records are required only by some other operation.
ForceplaceholdersForces the Dynamics AX runtime to generate a query with placeholder field constraints. For example, the query generated for the preceding code example looks like this: select * from myTable where myField1=?. Database query plans are reused when this option is specified. This is the default option for selectforceliterals keyword. statements that don’t join table records. This keyword can’t be used with the
ForceliteralsForces the Dynamics AX runtime to generate a query with the specified field constraints. For example, the query generated for the preceding code example looks like this: select * from myTable where myField1=’value’. Database query plans aren’t reused when this option is specified. This keyword can’t be used with the forceplaceholders keyword.
ForceselectorderForces the Microsoft SQL Server query processor to access tables in the order in which they are specified in the query. (The Oracle query processor ignores this keyword.)
ForcenestedloopForces the SQL Server query processor to use a nested-loop algorithm for table join operations. Other join algorithms, such as hash-join and merge-join, are therefore not considered by the query processor.
ReverseReturns records in reverse of the select order.
CrosscompanyForces the Dynamics AX runtime to generate a query without automatically adding the where clause in the dataAreaId field. This keyword can be used to select records from all or from a set of specified company accounts. For example, the query
while select crosscompany:companies myTable { }

selects all records in the myTable table from the company accounts specified in the companies container.
optimisticlockOverrides the table’s OccEnabled property and forces the optimistic locking scheme. This keyword can’t be used with the pessimisticlock and repeatableread keywords.
PessimisticlockOverrides the table’s OccEnabled property and forces the pessimistic locking scheme. This keyword can’t be used with the optimisticlock and repeatableread keywords.
RepeatablereadLocks all records read within a transaction. This keyword can be used to ensure consistent data is fetched by identical queries for the duration of the transaction, at the cost of blocking other updates of those records. Phantom reads can still occur if another process inserts records that match the range of the query. This keyword can’t be used with the optimisticlock and pessimisticlock keywords.

The following code example demonstrates how a table index clause is used to suggest the index that a database server should use when querying tables. The Dynamics AX runtime appends an order by clause and the index fields to the first select statement’s database query. Records are thus ordered by the index. The Dynamics AX runtime can insert a query hint into the second select statement’s database query, if the hint is reasonable to use.

static void myJob(Args _args)
{
MyTable1 myTable1;
MyTable2 myTable2;
;
while select myTable1
index myIndex1
{
print myTable1.myField2;
}

while select myTable2
index hint myIndex2
{
print myTable2.myField2;
}
pause;
}


The following code example demonstrates how the results from a select query can be ordered and grouped. The first select statement specifies that the resulting records must be sorted in ascending order based on myField1 values and then descending order based on myField2 values. The second select statement specifies that the resulting records must be grouped by myField1 values and sorted in descending order.

static void myJob(Args _args)
{
MyTable myTable;
;
while select myTable
order by Field1 asc, Field2 desc
{
print myTable.myField;
}
while select myTable
group by Field1 desc
{
print myTable.Field1;
}
pause;
}


The following code demonstrates use of the avg and count aggregate functions in select statements. The first select statement averages the values in the myFieldmyField field. The second select statement counts the number of records the selection returns and assigns the result to the myField column and assigns the result to the field.

static void myJob(Args _args)
{
MyTable myTable;
;
select avg(myField) from myTable;
print myTable.myField;

select count(myField) from myTable;
print myTable.myField;
pause;
}


Caution

The compiler doesn’t verify that aggregate function parameter types are numeric, so the result the function returns could be assigned to a field of type string. The compiler also performs rounding if, for example, the average function calculates a value of 1.5 and the type of myField is an integer.


Table 5 describes the aggregate functions supported in X++ select statements.

Table 5. Aggregate Functions in X++ select Statements
FunctionDescription
avgReturns the average of the non-null field values in the records the selection returns.
countReturns the number of non-null field values in the records the selection returns.
sumReturns the sum of the non-null field values in the records the selection returns.
minofReturns the minimum of the non-null field values in the records the selection returns.
maxofReturns the maximum of the non-null field values in the records the selection returns.

The following code example demonstrates how tables are joined with join conditions. The first select statement joins two tables by using an equality join condition between fields in the tables. The second select statement joins three tables to illustrate how you can nest join conditions and use an exists operator as an existence test with a join condition. The second select statement also demonstrates how you can use a group by sort in join conditions. In fact, the join condition can comprise multiple nested join conditions because the syntax of the join condition is the same as the body of a select statement.

static void myJob(Args _args)
{
MyTable1 myTable1;
MyTable2 myTable2;
MyTable3 myTable3;
;
select myField from myTable1
join myTable2
where myTable1.myField1=myTable2.myField1;
print myTable1.myField;

select myField from myTable1
join myTable2
group by myTable2.myField1
where myTable1.myField1=myTable2.myField1;
exists join myTable3
where myTable1.myField1=myTable3.mField2;
print myTable1.myField;
pause;
}


Table 6 describes the exists operator and the other join operators that can be used in place of the exists operator in the preceding example.

Table 6. Join Operators
OperatorDescription
existsReturns true if any records are in the result set after executing the join clause. Returns false otherwise.
notexistsReturns false if any records are in the result set after executing the join clause. Returns true otherwise.
outerReturns the left outer join of the first and second tables.

The following example demonstrates use of the while select statement that increments the myTable variable’s record cursor on each loop.

static void myJob(Args _args)
{
MyTable myTable;
;
while select myTable
{
Print myTable.myField;
}
}


You must use the ttsbegin, ttscommit, and ttsabort transaction statements to modify records in tables and to insert records into tables. The ttsbegin statement marks the beginning of a database transaction block; ttsbegin-ttscommit transaction blocks can be nested. The ttsbegin statements increment the transaction level; the ttscommit statements decrement the transaction level. The outermost block decrements the transaction level to zero and commits all database inserts and updates performed since the first ttsbegin statement to the database. The ttsabort statement rolls back all the database inserts, updates, and deletions performed since the ttsbegin statement. Table 7 provides examples of these transaction statements for single records and operations and for set-based (multiple-record) operations.

Table 7. Transaction Statement Examples
Statement TypeExample
ttsbegin

ttscommit

ttsabort
boolean b = true;
;
ttsbegin;
if ( b == true )
ttscommit;
else
ttsabort;

select forupdate
MyTable myTable;
;
ttsbegin;
select forupdate myTable;
myTable.myField = "new value";
myTable.update();
ttscommit;

insert method
MyTable myTable;
;
ttsbegin;
myTable.id = "new id";
myTable.myField = "new value";
myTable.insert();
ttscommit;

update_recordset
MyTable myTable;Int64 numberOfRecordsAffected;
; ttsbegin;

update_recordset myTable setting
myField1 = "value1",
myField2 = "value2"
where myTable.id == "001";
numberOfRecordsAffected = myTable.RowCount();
ttscommit;

insert_recordset
MyTable1 myTable1;
MyTable2 myTable2;
Int64 numberOfRecordsAffected;
;
ttsbegin;
insert_recordset myTable2 ( myField1, myField2 )
select myField1, myField2 from myTable1;
numberOfRecordsAffected = myTable.RowCount();
ttscommit;

delete_from
MyTable myTable;
Int64 numberOfRecordsAffected;
;
ttsbegin;
delete_from myTable
where myTable.id == "001";
numberOfRecordsAffected = myTable.RowCount();
ttscommit;


The last example in Table 7 demonstrates the method RowCount, which is new in Dynamics AX 2009. Its purpose is to get the count of records that are affected by set-based operations, namely, insert_recordset, update_recordset, and delete_from.

RowCount facilitates application scenarios that use set-based update operations. If no records are impacted by an update operation, the method application performs an insert or a set-based insert. In such a scenario, the application checks RowCount to see whether the update_ recordset statement impacted any rows. In the absence of RowCount, the application does another round-trip to the database to get the count of records impacted by the set-based update, an extra step that can degrade performance.
 
Others
 
- Microsoft Dynamic AX 2009 : Syntax (part 1) - Variable Declarations & Expressions
- Microsoft Dynamic AX 2009 : Jobs & The Type System
- Installing Active Directory Domain Services (part 3) - Creating a Domain Controller
- Installing Active Directory Domain Services (part 2) - Components of an Active Directory Infrastructure & Adding the AD DS Role Using the Windows Interface
- Installing Active Directory Domain Services (part 1) - Active Directory, Identity and Access
- Microsoft Dynamic GP 2010 : Speeding up access to information with SmartList Favorites
- Microsoft Dynamic GP 2010 : Sorting data to get the information you want
- Understanding the Basics of Collaboration in SharePoint 2010 (part 2) - Editing Features in SharePoint 2010
- Understanding the Basics of Collaboration in SharePoint 2010 (part 1) - Using SharePoint Sites and Templates
- BizTalk 2009 : Getting Started with Pipeline Development (part 3) - Configuring Recoverable Interchanges & Using the Default Pipelines
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us