Wed, Jun
4 New Articles

Anatomy of Net.Data Language

  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Sometimes you just need to get it done quickly, whatever it might be. This certainly applies to the demands of IT development, whether it’s a new development, an enhancement, or an ever-dreaded maintenance task. For many of your applications, you’ve developed libraries of well-tested routines and code snippets that make the job easier and faster. These libraries are what economists identify as an increase in worker productivity.

But what about Web application development? It takes years of development and development experience to build these libraries, and Web development is new to many of us. One alternative is to use a tool that supports rapid development yet minimizes the compromises such tools often bring along with them. One such tool is Net.Data.

Net.Data started life in IBM’s DB2 UDB labs as an offering known as DB2WWW. In the early days of the Web and HTML, it was a response to the need to dynamically publish data residing in a production database to a Web page quickly and easily. A macro or a script (choose your desired word) could be developed in a text editor and saved to a directory, and the DB2WWW interpreter would execute the saved instructions interactively from within the Web server. Finally, instant gratification for the developer. At the time, the primary alternative was to write a custom Common Gateway Interface (CGI) program for each data retrieval task.

Over time, new function was added to DB2WWW, and—as with all good things IBM—it was renamed Net.Data. It is now a strategic part of all the DB2 UDB implementations, including the AS/400, and is provided with the database at no additional charge. Getting Net.Data to operate generally requires no more than a few entries in an HTTP server configuration.

Net.Data provides essentially all of the capability found in any other programming language or environment. To accomplish this, Net.Data developed its own language and structure. The purpose of this article is to introduce you to that structure, and see how complex implementations can be developed from a few relatively simple components. Over time I’ve found development easier in a new language or environment if I can first understand the basic parts of the language and how these parts fit together.


For the purposes of this article I will refer to a file containing Net.Data code as a macro. Calling the code a script or a program is just as valid—though IBM’s documentation uses the word macro—so I will use it for consistency.

Begin with a Block

The primary language construct in Net.Data is known as the block. Blocks group common pieces of function together and allow the developer control over what occurs and when it occurs inside the macro. Blocks are very familiar to experienced programmers. For example, a block in CL is defined by the Do/End keyword combination and is defined by the open brace ({) and the close brace (}) characters in C or C++. Net.Data blocks begin with the percent (%) character, followed by an identification of what type of block that it is, and finally the { character. All Net.Data blocks end with the %} character combination.

The simplest possible Net.Data macro must contain at least one block, and that block must be an HTML block. The following line of code, for instance, is an example of the famous Hello World example in Net.Data:


Hello World


As I noted, the block begins with the % character. Next, the type of block is identified (in this case HTML), the block is given a name inside the parentheses, and the beginning is finished up with the { character. The simple HTML producing Hello World should be easy to recognize.

The purpose of an HTML block is to output something to the requesting browser, typically HTML or text. The output approach Net.Data takes is to send anything it does not recognize as a part of the language to the browser. If the unrecognized content happens to be valid HTML, the browser should behave as expected.

Multiple HTML sections are allowed within a single macro file. One distinct advantage to this feature is an ability to produce and maintain an entire Web site, or a significant portion of it, from within a single source file. Another advantage is the ability to share other code in the macro file between different Web pages on a site. The result will be a more-consistent-looking, easier-to-maintain site.

Net.Data parses macros from the beginning to the end without regard for line breaks. A block can be nested within another block all on the same line in the source file, if desired; however, line breaks do add to the readability of any piece of code and can be added anywhere within the block with just a few exceptions inside the beginning and ending character combinations.

All good developers provide lots of good comments in their code, right? Net.Data provides for comments again by using the block construct. Any block that begins simply with the %{ character combination is treated as a comment. As with all blocks, the comment ends with the %} combination.

Data Is Always Changing

A programming environment wouldn’t be much good without the ability to support variable data, and Net.Data is no exception. Its support for variables is similar to the support in many other macro facilities and interpretive languages in that all variable data is stored internally as a character string and is converted to numeric or other formats if a particular operation demands it.

Variable names must begin with a letter or the underscore (_) character and can contain any character after the first. Variable names can be very long, with the actual limit depending on the operating system on which Net.Data is running. Variable names in Net.Data are case sensitive. Be sure to check the source code carefully for case or spelling differences if a reference to a variable does not behave as expected.

Variables either are created explicitly by using a %DEFINE block or can be defined implicitly by assigning a value to a variable name inside the DTW_ASSIGN built-in function. Implicit creation is similar to creating a new variable right in the result field of an RPG C spec, whereas explicit creation is similar to defining the variable in the RPG IV D spec. The debate over implicit vs. explicit variable creation has gone on for a long time, but likely you will want to plan your project to include explicit creation.

One difficulty related to Net.Data’s variable creation behavior is that if you misspell or fail to match the case of an explicitly defined variable within a DTW_ASSIGN function, you will end up with a new variable that contains the desired value. The value of the variable you were trying to change will not have been altered, which just means you need to be careful.

HTML forms are a big part of any Web application. Fields, defined as part of a form within a Net.Data macro, automatically become variables and are available for use elsewhere in the macro.

Web server software platforms tend to use operating system environment variables extensively, making them very important in Web applications. For example, the user ID of the individual using the application may be available in an environment variable. Net.Data provides special, automatic support for querying and updating environment variables. If the macro variable is created in a %DEFINE block, with the same name as the environment variable and assigned the reserved value %ENVVAR, Net.Data will populate the variable with the value from the environment each time the variable is accessed. Net.Data will also update the value in the environment when it is changed from within the macro.

Another special type of variable exists within Net.Data, particularly to support its role in retrieving data from database tables—that being the %TABLE variable type. A Net.Data table is similar to an array but really is more easily compared to a database table, except that the Net.Data table is located in memory. %TABLE variables have a variable number of rows, each of which contains columns of data. A limited set of Net.Data functions will process %TABLE variables.

Variables within Net.Data have scope, much as they do in other language environments. If a variable is defined at the beginning of the macro, outside of any operational block, it will have global scope. That is, the variable and its value will be available anywhere within the macro. A variable defined inside a block, such as an HTML block, will only be available within that block and will not be visible to other parts of the macro. In all cases, the variable must be defined before it is first used because Net.Data is interpreted.

String handling in Web applications is important, and often the contents of a variable must be inserted simply as text. Other languages require the use of some sort of output function or printing of the value before it can be visible. Net.Data will output the contents of any variable, except %TABLE variables, simply by enclosing the variable in parentheses and prefacing it with the dollar ($) character. This sounds more complicated than it is.

Going with the Flow

Now that you know Net.Data has variables and has a distinct organization within the macro, you need to know how to control the flow of the program. The primary flow of control operations in any language really gets down to either executing logic based on the satisfaction of some condition or executing some logic for a controlled number of times (a loop).

Conditional expressions in Net.Data are constructed using %IF / %ELSE / %ENDIF statements. They break the rules of a block somewhat in that the { characters are not used. If the condition (in parentheses) following the %IF statement is true, the statements following the condition are executed. Otherwise the statements following the %ELSE reserved word are executed up to the %ENDIF statement.

The available conditional operators and the rules for the conditional test are similar to those in the C programming language. Two equal signs (==) are used for equivalency, and the exclamation point (!) represents not (i.e., != would be not equal).

%ELIF, a special version of %ELSE, is available that combines the capability of a %ELSE followed immediately by another %IF. %ELIF makes nested if logic much simpler to construct.

Loops in Net.Data are constructed with the %WHILE block. %WHILE contains a condition that is tested at the beginning of the loop, and all of the statements within the loop are executed if the condition is true. Execution passes to the statements following the end of %WHILE block if the condition is not true. Although some of the looping construct variants like FOR/NEXT and DO UNTIL that you often expect in a programming language don’t seem to be available, they all can be simulated with logic within a %WHILE block.

Functional Enhancement

The real work in most programming environments happens inside functions, and Net.Data is no different. Several types of functions are available, including user-defined functions, functions related to language environments, the mechanism Net.Data uses to connect to databases and other programming environments, and built-in functions.

User-defined functions give you a way to consolidate a set of statements that may be executed from more than one place within the macro. User-defined functions can accept a set of parameters and can contain any statements, blocks, or function calls necessary to get the job done. One interesting issue, though, is that, due to the fact that execution of Net.Data is interpreted, not compiled, a user-defined function must be defined in the source file before it is called.

Language environment functions are typically used to insert SQL statements. Each SQL statement needs a function defined before it can be executed and can either return query results as HTML directly in a Web page or in a %TABLE variable for processing elsewhere in the macro.

Both user-defined and language environment functions have a couple of special blocks within them. The first is a %MESSAGE block. This block allows the delivery of custom messages depending on particular return codes. In the case of SQL, the code is the SQLCODE associated with execution of the statement.

The other special block is %REPORT, and its subordinate block, %ROW. The statements inside %ROW execute once for each row returned from the execution of an SQL statement. Inside a user-defined function, the statements within the %ROW block execute once for each row in a %TABLE variable. Statements in the %REPORT block, outside of %ROW, execute once for each call of the function, either before or after the %ROW statements depending on their position relative to the %ROW block.

Built-in functions often make or break a development environment. Net.Data has a bunch of functions available, and they can take care of necessary programming needs like string handling, date, time, math, and interfaces to operating system programs.

Many of the built-in functions are supplied in two separate forms. The first form returns the result of the function as a parameter. The return value of the function will be the return code resulting from the execution.

The other built-in function form returns the result directly from the function and is identified with the characters DTW_r preceding the function name instead of DTW_. This form is useful when the results of a function are to be a parameter to another function. The first function can be specified within the call to the second, saving a couple of lines of code.

Functions are executed simply by prefacing the name of the function with the at (@) character.

All the Functionality in One Place

Figure 1 is reasonably self-explanatory and demonstrates a number of the features of the Net.Data language I’ve described. It can be executed on any AS/400 that has Net.Data configured. Configuring Net.Data is a relatively simple task, and IBM provides a good guide at www.as400.ibm.com/products/netdata/docs/tips.htm.

The file contains two HTML sections, either of which is executed by specifying the section name at the end of the macro URL. For example, on my AS/400 the Examples HTML section is executed by using the URL bin/db2www/pub/www/anatomy.txt/ examples. Figure 2 is the Web page the section produces.

In the end, is it better to develop a Web site with a Net.Data macro, or should you write programs? The answer is almost always the same: It depends. A Net.Data macro likely won’t be the highest performance solution, but it sure can be a quick way to get the job done. In my experience the ability to make small changes and immediately see the result is a tremendous benefit. Appropriate attention to database and SQL tuning, along with the appropriate use of certain Net.Data functions, can result in good performance, while getting the site up quickly. Ultimately a mix of macros and native programs is likely the best way to develop a site.

Give Net.Data a try. I firmly believe you will find it a very useful tool for taking your organization to the Web.


• AS/400 Net.Data home page: www.as400.ibm.com/netdata
• AS/400 Net.Data Tips and Techniques: www.as400.ibm.com/products/netdata/docs/tips.htm
• Net.Data documentation: www.as400.ibm.com/products/netdata/docs/doc.htm


A basic HTML block is named and is selected on the URL used to access the macro.

As with HTML, line breaks can be added for source readability but are ingnored
as the macro is processed.


%{Comments are enclosed in a block without any identifying type.%}

%{A variable defined outside of any other block will be global in scope.%}
%DEFINE{ A_Variable = “variable data” %}

%{Accessing environment variables is relatively easy.%}

%{Functions must be defined outside of an HTML block and must be defined in the source

file before they are used. See the Examples HTML section for how this is utilized%}

%FUNCTION(DTW_SQL) query_columns (IN TABLE_NAME) {


100 : “

No columns found for table $(Table_name)

” : exit

default : “

An SQL error occurred. Return code was $(RETURN_CODE)

” :



The following columns can be accessed within the $(Table_name) table:


Column $(V1) is of type $(V2) and has a length of $(V3)





An Anatomy of the Net.Data Language

%{Variables are case sensitive. The DTW_ASSIGN built-in function will create a new variable if it doesn’t
Since the variable is defined inside a block its scope will be limited to the block.%}

@DTW_ASSIGN(A_variable,”the other variable data”)

The contents of a variable can be accessed by enclosing the variable name in parentheses
and preceding it with the ‘$’ character. But be careful of the case sensitivity issue because the $(A_Variable) could be $(A_variable).

Accessing environment variables is relatively easy. For example, the remote

address accessing this page is $(REMOTE_ADDR).

@DTW_ASSIGN(The_question, “Yes”)

%IF(The_question == “Yes”)

Conditional expressions use an IF statement.


@DTW_ASSIGN(The_question, “No”)

%IF(The_question == “Yes”)

This text won’t display.

This text will display since the value of the variable changed.


%IF(The_question == “Yes”)

Nothing happens here.
%ELIF(The_question == “No”) The ELIF statement helps to streamline coding of nested IF conditions.


@DTW_ASSIGN(Loop_counter, “0”)

%WHILE(Loop_counter < “5”){

Loops are important in any programming language.

%{The program needs to take care of the loop condition itself

so a built-in math function is used to increment the counter.%}

@DTW_ADD(Loop_counter, “1”, Loop_counter)

A function is called simply by prefacing its name with the ‘@’ character.


There are only a few rules about how a Net.Data macro must be organized. Past coding examples
have implied that order may be more important than it is or that certain elements are
absolutely required. Very simple macros will operate properly and with the capabilities
of the Net.Data language extensive, dynamic Web sites can be developed quickly and easily.


Figure 1: It is relatively easy to demonstrate all of the essential elements of the Net.Data language.

Anatomy_of_Net._Data_Language07-00.png 400x422

Figure 2: A simple Web page is what the Examples HTML section of Listing 2 will produce.



Support MC Press Online

$0.00 Raised:

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: