Ariba Spend Management Query API Guide 9r2
Ariba Spend Management Query API Guide 9r2
This documentation, as well as the Ariba software and/or services described in it, contain proprietary information. They are provided under a license or other
agreement containing restrictions on use and disclosure and are also protected by copyright, patent and/or other intellectual property laws. Except as permitted
by such agreement, no part of the document may be reproduced or transmitted in any form by any means, electronic, mechanical or otherwise, without the
prior written permission of Ariba, Inc.
Ariba, Inc. assumes no responsibility or liability for any errors or inaccuracies that may appear in the documentation. The information contained in the
documentation is subject to change without notice.
Ariba, the Ariba logo, AribaLIVE, SupplyWatch, Ariba.com, Ariba.com Network and Ariba Spend Management. Find it. Get it. Keep it. and PO-Flip are
registered trademarks of Ariba, Inc. Ariba Procure-to-Pay, Ariba Buyer, Ariba eForms, Ariba PunchOut, Ariba Services Procurement, Ariba Travel and
Expense, Ariba Procure-to-Order, Ariba Procurement Content, Ariba Sourcing, Ariba Savings and Pipeline Tracking, Ariba Category Management, Ariba
Category Playbooks, Ariba StartSourcing, Ariba Spend Visibility, Ariba Analysis, Ariba Data Enrichment, Ariba Contract Management, Ariba Contract
Compliance, Ariba Electronic Signatures, Ariba StartContracts, Ariba Invoice Management, Ariba Payment Management, Ariba Working Capital
Management, Ariba Settlement, Ariba Supplier Information and Performance Management, Ariba Supplier Information Management, Ariba Discovery, Ariba
Invoice Automation, Ariba PO Automation, Ariba Express Content, Ariba Ready, and Ariba LIVE are trademarks or service marks of Ariba, Inc. All other
brand or product names may be trademarks or registered trademarks of their respective companies or organizations in the United States and/or other countries.
Ariba Sourcing solutions (On Demand and software) are protected by one or more of the following patents, including without limitation: U.S. Patent Nos.
6,199,050; 6,216,114; 6,223,167; 6,230,146; 6,230,147; 6,285,989; 6,408,283; 6,499,018; 6,564,192; 6,871,191; 6,952,682; 7,010,511; 7,072,061; 7,130,815;
7,146,331; 7,152,043;7,225,152; 7,277,878; 7,249,085; 7,283,979; 7,283,980; 7,296,001; 7,346,574; 7,383,206; 7,395,238; 7,401,035; 7,407,035; 7,444,299;
7,483,852; 7,499,876; 7,536,362; 7,558,746; 7,558,752; 7,571,137; 7,599,878; 7,634,439; 7,657,461; and 7,693,747. Patents pending.
Other Ariba product solutions are protected by one or more of the following patents:
U.S. Patent Nos. 6,199,050, 6,216,114, 6,223,167, 6,230,146, 6,230,147, 6,285,989, 6,408,283, 6,499,018, 6,564,192, 6,584,451, 6,606,603, 6,714,939,
6,871,191, 6,952,682, 7,010,511, 7,047,318, 7,072,061, 7,084,998; 7,117,165; 7,225,145; 7,324,936; and 7,536,362. Patents pending.
Certain Ariba products may include third party software or other intellectual property licensed from a third party. For information regarding software or other
intellectual property licensed from a third party, go to http://www.ariba.com/copyrights.cfm.
Revision History
The following table provides a brief history of the updates to this guide. Ariba updates the technical
documentation for its On-Premise solutions if
• software changes delivered in service packs or hot fixes require a documentation update to correctly
reflect the new or changed functionality;
• the existing content is incorrect or user feedback indicated that important content is missing.
Ariba reserves the right to update its technical documentation without prior notification. Most
documentation updates will be made available in the same week as the software service packs are released,
but critical documentation updates may be released at any time.
Chapter 1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Advantages of the Ariba Query API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Query Defaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
SQL-Independence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Query API Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Testing and Debugging Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Using the Inspector to Run Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Using the Command Line Tool. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Setting Log Categories for the Ariba Query API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Using this Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Chapter 2
Ariba Query API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Ariba Query API Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Constructing a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Building a String Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Building a Query with Java Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Executing Query Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Specifying Query Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Validating a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Executing a Query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Executing an Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Processing Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Checking Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Accessing Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Accessing Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
AQLError Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Chapter 3
Writing Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Common Defaults for Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Filtering for Active Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Filtering by Partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Filtering for Locale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Accessing Data through Field Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Accessing Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Accessing Normalized Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Using Dot Notation in Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Metadata XML Settings Affecting Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Query Examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Auto-Join Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Vector Example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
The Query Result Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Using the Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Using the Cache with a Nametable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Configuration Settings for the Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Chapter 4
Query Language Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Syntax Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Terminal Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Other Punctuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Annotated Grammar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Select Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Class and Field References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Join Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Conditional Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Scalar Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Other Statement Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Built-in Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Known Limitations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Appendix A
Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Appendix B
Command Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
aribaquery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
You use the Ariba Query API to query your database from Java code. Ariba Query API provides
functionality much like that of SQL and the query language follows the basic SQL SELECT ... FROM ....
syntax.
The chief advantage of the Query API over raw SQL is that it is integrated with metadata XML and thus
allows you to express queries in terms of your object model’s classes and fields.
The Query API also provides defaults that make it easier to express common idioms, such as restricting a
query to the objects in a given partition, or defining a query so that it does not return objects marked as
inactive in the database.
This document describes how to create and execute queries using the Ariba Query API. It assumes that you
are familiar with using metadata XML files to define an object model, and that you have a basic knowledge
of SQL and database queries.
The basic query syntax is a SELECT ... FROM ... statement, with an optional WHERE clause, as in SQL. In
Ariba Query API queries, the terms in the SELECT statement are fields and classes from your object model,
rather than database tables and columns (as they would be in SQL). The following is a simple example:
The Ariba Query API reads the query statement, translates the Java field names into database tables, and
generates a SQL statement. For this example, the SQL statement might be as follows:
SELECT Use1.us_EmailAddress
FROM UserTab Use1
In this example, the terms in the SELECT statement refer to the Java class names (such as
ariba.user.core.User), and not database tables names (such as UserTab). The Query API is strongly typed,
and is able to validate class and field names based on the typing information in metadata XML files.
You can also use the Ariba Query API to execute raw SQL statements.
Query Defaults
The Query API provides default parameters and settings for common query options. These defaults mean
that you can omit many standard clauses from your queries, and have them defaulted by Ariba Query API.
For example, by default, the Query API adds an INCLUDE ACTIVE clause to all queries, to select items marked
as active in the database (and exclude those marked as inactive). When you construct a query, you do not
have to explicitly include a clause to omit inactive objects. For example, consider the query used in the
previous example:
When the Ariba Query API generates the SQL for this query, the default is to add a filter for active objects,
and also a filter that restricts the query by partition. The actual SQL generated for this query statement might
be as follows:
SELECT Use1.us_EmailAddress
FROM UserTab Use1
WHERE (Use1.us_Active = 1) AND
(Use1.us_PartitionNumber = 0 OR Use1.us_PartitionNumber = 2)
If the defaults are not appropriate, you can override them by supplying explicit query terms. The defaults
exist to provide convenient shortcuts for common idioms.
SQL-Independence
Another advantage of the Ariba Query API is that it insulates you from the details of the underlying SQL
implementation. SQL tends to vary in certain details between RDBMS vendors. The Ariba Query API is
RDBMS-independent, which means that you can write your queries without needing to know the details of
the underlying SQL implementation.
Internally, a query is a Java object, and you run that query by calling Java methods in the BaseService class.
You can construct the query either by using Java methods in the Query API or by writing the query as a
query string (using SQL-like syntax), and then parsing the string into an object. The query data is returned in
a Java object, an AQLResultCollection, which you can then process with methods in the Java API to extract
results.
Most Ariba Query API query statements are SELECT statements, but there is also limited support for UPDATE
statements and other SQL statement types.
For information on the Java API for running and parsing queries, see “Ariba Query API Overview” on
page 11.
aribaquery -username <xxx> -password <xxx> -host <hostname> -port <rpc port>
(If you are not using SSL, you must supply the -noSsl option as well.)
You can use aribaquery to submit arbitrary query strings. For example:
To indicate that you have entered a complete statement, you must either terminate the command with a
semicolon, or type go on a separate line after you submit the command. For example:
AQL> SELECT Country from ariba.basic.core.Country AS Country WHERE Name > 'Algeria' AND Name <
'Canada'
AQL> go
The keywords you use with aribaquery, such as go, quit, and exit, are
case-insensitive. The options, such as -username, are case-sensitive.
For a complete list of options available for aribaquery, see “aribaquery” on page 71.
The aql category includes both query and queryperf. If you turn on aql, the query and queryperf categories
are also enabled. If you use either queryperf or aql, you should set the log level to info.
A setting of queryperf/debug logs performance information for every query, which can generate a lot of
output in the query logs. A setting of queryperf/info uses parameters from config/Parameters.table to
determine a cutoff for which queries to include. The queryperf/info category traces the following types of
queries:
• Queries that take more than System.Debug.QueryExecutionThresholdMilliseconds to execute
• Queries that generate more than System.Debug.QueryGenerationThresholdSQLBytes of SQL
• Queries that use SELECT *
2 Determine a threshold in milliseconds that you feel would be acceptable to your end users, and set the
System.Debug.QueryExecutionThresholdMilliseconds parameter to this value. For example:
QueryExecutionThresholdMilliseconds=7000
All queries that exceed the specified threshold are logged to the log file. This will identify slow running
queries and provide insight into areas that need to be tuned.
Additionally, the appendixes provide reference information on the reserved words and command-line tools
in the Ariba Query API.
This chapter provides an overview of how to access the Query API from Java code. It includes the following
sections:
• “Ariba Query API Overview” on page 11
• “Constructing a Query” on page 12
• “Executing Query Statements” on page 14
• “Processing Results” on page 16
The example on the next page shows a simplified example of the API.
return addresses;
}
if (!StringUtil.nullOrEmptyOrBlankString(street)) {
conditions.add(
AQLCondition.buildEqual(
typeRef.buildField(Address.KeyLines), street));
}
if (!StringUtil.nullOrEmptyOrBlankString(city)) {
conditions.add(
AQLCondition.buildEqual(
typeRef.buildField(Address.KeyCity), city));
}
return AQLCondition.buildAnd(conditions);
}
The rest of this chapter describes each of these steps in more detail.
Constructing a Query
In the Ariba Query API, you can create a query either as a string query or a query object:
• A string query is a SQL-like string, such as SELECT Name FROM Requisition
• A query object is a Java object, constructed using methods in the interface AQLStatement. For example:
AQLQuery query = new AQLQuery("Requisition", ListUtil.list("Name"));
These two examples create the same query. In general, you use the Java form if you want to add to the query
from the logic of your Java code, and the string form if you are reading a query string from external files,
such as metadata XML files. You can also combine the two approaches; for example, you could parse a
query string to obtain an initial query, and then add to it programmatically.
The query string uses a SQL-like language, which is described in detail in “Query Language Details” on
page 27.
You can include values in the query string in any of the following ways:
• As literals:
"SELECT Name FROM Address WHERE Name = 'B%'"
When you include a named parameter in a query, you pass the value for that parameter in as an option to
the query. For example, in this case, you would pass a value for aName as a query parameter.
For information on specifying parameters to queries, see “Specifying Query Options” on page 14.
This approach is typically more appropriate in cases where the query is built up in pieces in different parts of
the code.
For examples of constructing queries using Java methods, see “Query Examples” on page 24. For a complete
list of the methods that are available for you to use in building queries, see the Javadoc.
String conditionText =
"(Description.CommonSupplier NOT IN " +
"(SELECT CostCenterToSupplier.Supplier.CommonSupplier"+
"FROM ariba.core.CostCenterToSupplier " +
"PARTITION %s SUBCLASS NONE " +
"WHERE CostCenterToSupplier.CostCenter = %s))";
partition.getName(),
AQLScalarExpression.buildLiteral(costCenter).toString());
return AQLCondition.parseCondition(conditionText);
From the Java API, you add conditions with methods in subclasses of AQLCondition. The AQLCondition class
itself is an abstract class, with subclasses such as AQLBetweenCondition and AQLOrCondition that implement
specific conditions.
For more information on the classes and methods in this example, see the Javadoc.
These methods take a query as argument, and operate on that query. With executeQuery or executeUpdate,
you can supply options, expressed as a parameter of type AQLOptions. When you call executeQuery or
executeUpdate, the Ariba Query API implicitly validates the incoming query. You can also explicitly validate
a query with a call to the validate method.
The rest of this section describes how to set up query options and how to run an execute or update statement.
Note: The BaseService API also includes other methods related to running queries; for a complete list of
available methods, see the Javadoc.
The AQLOptions class provides the following constructors for options objects:
• AQLOptions(Partition)
• AQLOptions(Partition[])
• AQLOptions()
The first form is the simplest form. You create an AQLOptions object, passing the partition to the constructor.
The rest of the information is retrieved from the user session.
The second form is similar, except that you pass an array of partitions, rather than just a single partition.
With the last form, you create an AQLOptions object, but don’t supply an explicit partition. With this form,
you have to either supply the partition later, or supply it on each individual call.
Once you have constructed an AQLOptions object, you can call methods in the AQLOptions class to set your
preferred options. For example, you can set a locale using the method setUserLocale. For a list of the
available methods that you can use to add options to your AQLOptions object, see the Javadoc.
You supply a value for this parameter and add it to your AQLOptions object as follows:
AQLOptions options;
Map paramMap = MapUtil.map();
paramMap.put("myParam", "R%");
options.setActualParameters(paramMap);
When the query is executed, the information is substituted from the map into the query. You can supply the
actual parameters either as a list or as a map — you use a list if your parameters are numbered, and a map
otherwise.
For a complete list of the available methods for setting values in AQLOptions objects, see the Javadoc.
Validating a Query
You call the validate method to check a query. The method signature is as follows:
This method performs semantic validation on the specifiedstatement. If an error is found, validate throws
an AQLValidateException describing the error.
The Ariba Query API also validates each query just before executing it.
Executing a Query
You use executeQuery to execute a query once you have constructed it. The BaseService API includes two
versions of this method: one that takes a query string as argument and one that takes a query object. The
method signatures are as follows:
AQLResultCollection executeQuery
(AQLStatement statement, AQLOptions options)
This method executes the specified statement, passing in any options defined in the options parameter.
AQLResultCollection executeQuery
(String statementText, AQLOptions options)
This method takes a query string as argument, parses and validates it, performs any substitutions,
generates an AQLStatement, and executes that query statement.
For example:
AQLQuery query =
AQLQuery.parseQuery("SELECT req, Preparer.Name " +
"FROM ariba.procure.core.Requisition req " +
"WHERE Preparer.Name = :1 " +
"ORDER BY Name");
AQLResultCollection resultCollection =
Base.getService().executeQuery (query, options);
Executing an Update
You execute an update statement by calling executeUpdate, passing either a string query or a statement
object. The resulting code calls a SQL update statement, which modifies a database table. You can update
either a class or a database table. The method signatures for update operations are as follows:
int executeUpdate
(String statementText, AQLOptions options) throws AQLException
int executeUpdate
(AQLStatement statement,
AQLOptions options)
throws AQLException
These methods execute a modification statement, and return the number of objects modified (possibly
zero).
To perform an update, you must explicitly set the options you pass to the executeUpdate method to have
write access, for example:
Update capability is restricted. The update statement must generate SQL that refers to only one table. (A
SQL update statement can only refer to one table in the FROM clause.) This restriction is enforced at query
validation time. Use extreme caution when using update statements.
Processing Results
A call to executeQuery returns an AQLResultCollection object. To process results you first check for errors,
and then access each of the results in the result object. You must check for errors before trying to process
results: if a result object contains errors and you make any call on it aside from checking for errors, the result
is a fatal error.
• AQLResultField
• AQLError
The AQLResultCollection class defines the result collection object, and most methods for accessing the
result collection. AQLResultField defines methods for accessing metadata about a result (such as its type),
and AQLError defines a method you can call to access the string representation of an error.
Checking Errors
To process results, you first check for errors. The AQLResultCollection class defines two methods for
checking errors:
List getErrors ()
AQLError getFirstError ()
Returns the first error in the list of AQLErrors, or null if there are no errors.
If there were errors, you access the error text with AQLError.toString. For example:
AQLResultCollection results;
if (results.getErrors() != null) {
System.out.println(results.getFirstError().toString());
}
Accessing Results
After checking for errors, you process the AQLResultCollection. The API uses a cursor-based model. You
move through the results with AQLResultCollection.next, which returns true if there is a next row and false
otherwise.
Once on a new row, you can access a specific column with methods in AQLResultsCollection. For example:
• To access fields, use getField
• To access cluster roots, use getBaseID and then dereference the ID
• To access other data (including embedded objects), use getObject
Each of these methods allow you to specify the value either by name or by position. For example, the
getField method has two forms, one that takes an integer and one that takes a string argument. The
following is a simple example:
This example accesses the object by position, using i as the index, and then converts the object to a string.
You can also access an object by column name. For example:
You can use getObject for any type. For example, you can use it to retrieve a BaseObject, such as Money. To
fetch cluster roots, use getBaseId and then call objectFromId on the baseID. For example:
ClusterRoot donor2 =
(ClusterRoot)Base.getSession().objectFromId(results.getBaseId(0));
....
For a complete list of the methods in AQLObjectCollection that you can use to fetch back data from your
results, see the Javadoc.
Accessing Metadata
To determine the data type of a result object, you can call AQLResultsCollection.getField to return an
AQLResultField object, through which you can access metadata about a column.
AQLResultField includes methods such as getType, getClassName, and getName. (For a complete list of the
available methods, see the Javadoc.) None of the methods take any arguments; they each simply return a
piece of metadata about the field. For example:
String getName ()
AQLError Class
The AQLError class provides information about errors that occur when a query fails. An AQLError object
contains information on one error. AQLError includes this method:
String toString ()
When you write a query statement using the Ariba Query API, you express that query in terms of the object
model. The Ariba Query API interprets your queries and generates SQL, adding appropriate defaults and
translating object model syntax. For example, if you write a query to return all requisitions from the
database, the Ariba Query API automatically filters that query to remove any requisitions that are inactive or
have been purged.
This chapter describes how to write queries with Ariba Query API. It includes the following sections:
• “Common Defaults for Queries” on page 19
• “Query Examples” on page 24
• “The Query Result Cache” on page 25
This query generates the following additional WHERE clauses to filter out inactive and purged objects:
SELECT Use1.us_EmailAddress
FROM UserTab Use1
WHERE (Use1.us_Active = 1) AND
(Use1.us_Purgedtate = 0 OR Use1.us_PurgeState IS NULL)
To include inactive objects in your query, you can add an explicit active/inactive clause, as described in
“Restricting by Inactive Objects” on page 40.
Filtering by Partition
A query can include one or more partitions, to retrieve only objects in that partition. In general, specifying a
partition yields the same data users see in that partition, in the user interface.
If you are querying on a partitioned class, the partition argument is required. You can specify it in your query
options object, or in the query itself. The Ariba Query API uses that partition information to add a partition
clause to the query. For example, consider the following query:
SELECT Use1.us_EmailAddress
FROM UserTab Use1
WHERE (Use1.us_Active = 1) AND (Use1.us_PurgeState = 1) AND (Use1.us_PartitionNumber = 0 OR
Use1.us_PartitionNumber = 2)
Partition 0 is unpartitioned data, and Partition 2 (in this example) is the partition you have specified in your
query options object. If you are querying on a partitioned class, the query filter always includes
unpartitioned data (Partition 0) as well.
For information on how to specify the partition directly in the query, or query across partitions, see
“Restricting by Partition” on page 40.
For example, if TestLanguage is a class with a field called TranslatedStrings which is a multilingual string,
the following query selects just one string translation:
When you write queries that access fields of type MultiLingualString, both locale and partition are required
in the AQLOptions. Ariba Query API returns the translation appropriate for the specified partition. If the
language of the partition cannot be determined (if the partition is Any, or there are several partitions with no
common language), Ariba Query API uses the user’s preferred language instead.
Because the Query API reads and parses the metadata, you can write queries that use field aliases. The
Query API is able to follow any such field aliases and reach the underlying field. You do not have to do
anything special in your query to indicate that you are using an alias.
Accessing Vectors
Ariba Spend Management applications store vectors in separate vector tables. The object model supports
both direct and indirect vectors. A vector of ‘direct’ uses a direct join between the ClusterRoot table and the
BaseObject table. A vector of ‘indirect’ joins through the BaseId table. You can use the same query to access
either a direct or indirect vector. The Ariba Query API determines the appropriate vector table for you and
queries that table.
When you write queries that access your database, you do not need to know the database layout, or which
classes have been normalized. The Ariba Query API checks the metadata XML to determine which classes
are normalized, and then constructs the query as appropriate.
For example, in Ariba Buyer, the Approvable hierarchy is normalized, which means that Ariba Buyer creates
a separate table for data that is shared by that class and its subclasses. This normalization makes it more
efficient to query on Approvable, which has a large number of subclasses. A query on Approvable need only
query that shared table, and does not need to join all the subclasses. Thus, this query:
However, the Address hierarchy is not normalized, so a similar query on that class translates to a query that
joins the individual tables by name. For example, consider this query:
SELECT v2_1.ad_Name
FROM v2_AddressTab v2_1
WHERE (v2_1.ad_Active = 1) AND
(v2_1.ad_PartitionNumber = 0 OR v2_1.ad_PartitionNumber = 2)
UNION ALL
SELECT v2_1.sl_Name
FROM v2_SupplierLocationTab v2_1
WHERE (v2_1.sl_Active = 1) AND
(v2_1.sl_PartitionNumber = 0 OR v2_1.sl_PartitionNumber = 2)
UNION ALL
SELECT v2_1.puoa_Name
FROM v2_PunchOutAddressTab v2_1
WHERE (v2_1.puoa_Active = 1) AND
(v2_1.puoa_PartitionNumber = 0 OR v2_1.puoa_PartitionNumber = 2)
When you write queries using the Ariba Query API, you write the simple query and let the Ariba Query API
determine which tables are involved and create any necessary join statements.
In the following example, TaxAmount is a field in Requisition that embeds a money object (a direct reference
to Money), and Preparer is a field in Requisition that refers to a User object (an indirect reference to User).
In this example, the amount field is referenced directly in the row of RequisitionTab, but the preparer name
requires a join to the User table. When you use the Query API, you do not need to know whether an object
embeds another (a direct reference) or refers to it (an indirect reference).
Note, however, that the implicit inner join means that you cannot use dot notation in OR queries. For example,
consider the following query:
In this query, the use of dot notation in User.Roles and User.Permissions means that Ariba Query API
always does an inner join, selecting only those users with both the specified role and the specified
permission. The OR query has no effect, since the inner join selects only rows that have both the specified
row and the specified permission. To write an OR query, you cannot use dot notation.
Note that User is in quotation marks because it is a reserved word. For a list of reserved words, see
“Reserved Words” on page 67.
Reqisition.Preparer = prep
Or, since Preparer is unique within the FROM list, it could be written as follows:
FROM A.f AS x
Is equivalent to:
The following metadata XML tags and attributes affect whether a given object or field is returned in a query:
• The noSchema attribute of a <class> declaration. If a class is declared with the attribute noSchema=true,
objects of that class are not stored in the database, and so cannot be returned in queries.
• The <derived> tag. If a field is declared as a <derived> element, the value of that field is computed
dynamically and not stored in the database. You cannot query for the value of derived fields.
• The noPersist attribute of a <field> declaration. If a class is declared with the attribute noPersist=true,
the data for that field is not stored in the database, and so cannot be returned in queries.
• The noQuery attribute of a <field> declaration. If a field is declared with the attribute noQuery=true, the
data for that field is stored in the database, but not returned in query results.
Query Examples
This section shows examples that illustrate how to construct query objects, using both AQLQuery methods and
query strings.
Auto-Join Example
The queries in this example look for requisitions where the Preparer.Name field matches a specified value,
and return the base IDs and names of those requisitions, ordered by Requisition name. This query illustrates
how the Ariba Query API implements the dotted path notation with an automatic implicit inner join.
This example includes the call to actually execute the query. This is omitted from the remaining examples.
AQLResultCollection resultCollection =
Base.getService().executeQuery (query, options);
Vector Example
This example illustrates queries that look for users with a specific role. It returns the base IDs of Users who
have the role given by the String object roleName.
When the result cache is enabled and a query is executed, the query result cache is checked to see if that
query has been executed before. If it has been, the previous results are returned.
The result cache is purged when it overflows, when an integration event runs, or when a multiserver node
rejoins the node group. When you write a query that uses the cache, it is your responsibility to ensure that it
is safe to use cached results.
To specify whether you want the results of a query to be cached, you set parameters in the AQLOptions object.
By default, the cache is disabled. To enable the cache, use the method AQLOptions.setUseCache.
This method constructs an AQLOptions object and returns that object, with appropriate options set. The
field and pattern parameters represent the information that the user has entered in the chooser. For
example, if a user searches for “Janic*,” the pattern field will be set to Janic*.
This method calls AQLNameTable.updateIgnoreCache, which disables the query cache whenever the user
has set up a custom query, or a query that includes user-created objects.
For situations where you want more control over the creation of the AQLOptions objects, you can also call
AQLNameTable.updateIgnoreCache directly.
Note that the AQLNameTable class does not cache queries if the includesUserObjects property is set to true. In
this case, it ignores any setting in your AQLOptions object.
This chapter provides a detailed description of the Ariba Query API query language. The query language is
a subset of a standard known as the Object Query Language, with a few Ariba-specific extensions, such as
syntax to specify Ariba partitions.
Syntax Conventions
This section describes the syntax conventions for the language grammar used in this chapter. In general,
punctuation symbols indicate syntax conventions; for example, * represents 0 or more occurrences of a
symbol. However, when a punctuation symbol appears in bold, you must type that symbol in your query
string. If you are not sure whether you should type a symbol, check the example for guidance.
Convention Description
nonterminal Non-terminal symbols are in lowercase.
::= This symbol introduces a production.
KEYWORD Terminal name symbols that are keywords (reserved) are in
all caps.
FunctionName Terminal name symbols that are not keywords (not
reserved) are in italics, mixed case.
<string_literal> A terminal symbol.
[ ] Surrounds optional elements.
Convention Description
* Indicates zero or more occurrences of the preceding
element.
Terminal Symbols
This section describes the terminal symbols used by Ariba Query API:
• Keywords
• Operators
• Punctuation
• Identifiers
• Literals
Keywords
Keywords are case-insensitive. The following names are reserved, and cannot be used as identifiers unless
they are quoted (delimited with double quotes) or follow a period (.) as in a field path, as described in
“Identifiers” on page 30.
Function names are not reserved words, except those that are already SQL92 reserved words. Ariba Query
API includes the following keywords:
In addition, Appendix A, “Reserved Words,” lists words that are not currently used but are reserved now as
keywords for possible future use.
Operators
Ariba Query API includes the following operators:
Operator Description
= == equality
< less than
<= less than or equal
> greater than
>= greater than or equal
<> != inequality
| bitwise or
& bitwise and
+ binary addition, unary positive
- binary subtraction, unary negative
|| concatenation
* multiplication
/ division
. field selection
() function call arguments/expression grouping
[] vector subscript
Other Punctuation
Ariba Query API includes the following additional punctuation:
, general separator
: parameter marker
Identifiers
The following are valid identifiers in Ariba Query API:
To use a keyword or reserved work as a identifier, surround it in double quotes. For example:
SELECT "User".Name
Also, for convenience, any identifier following a period is treated as if it were in quotes. A reserved
word/keyword cannot be used as an identifier unless it is quoted or it follows a period (.) in a field path.
Literals
This section describes the grammar for expressing literals in Ariba Query API.
Integer literals
An integer literal is defined as follows:
<integer_literal> ::=
0 | non_zero_digit digit*
non_zero_digit ::=
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
digit ::=
0 | non_zero_digit
<floating_point_literal> ::=
digit+ . digit* [ exponent ] |
. digit+ [ exponent ]
exponent ::=
( e | E ) [ + | - ] digit+
String literals
String literals are delimited by single quotes, and are case-sensitive. To include a single quote in a string
literal, double the quote. For example:
Date literals
In general, you use Date objects to express dates, although Ariba Query API also supports date literals.
Internally, dates are represented in GMT, and functions that return date values return those values in GMT.
To create a date from a literal, you can use Date or CalendarDate. Both can convert from literals to dates,
using the same format to describe the date. The only difference is that the Date function requires a timezone,
and the CalendarDate function does not.
The date format is based on the format used in SQL and IBM DB2. The format is as follows:
BaseID literals
In general, you use BaseID objects to express BaseIDs. However, you can also specify BaseID literals with
the BaseId built-in function, which parses a string representation of the BaseID. For example:
Data Types
Ariba Query API supports the data types used in metadata XML:
Type Description
Boolean java.lang.Boolean
Annotated Grammar
This section provides a complete description of the grammar used by Ariba Query API. It includes the
following sections:
• “Select Statements” on page 32
• “Class and Field References” on page 36
• “Join Clauses” on page 41
• “Conditional Expressions” on page 45
• “Scalar Expressions” on page 52
• “Other Statement Types” on page 58
Select Statements
The Ariba Query API supports the following SQL statement types:
• select
• update
• delete
• create
This section focuses on select statements. Most Ariba Query API statements are select statements. For
information on other statement types, see “Other Statement Types” on page 58.
Select Statements
A select statement describes data to be read from the database.
The select list describes the field or fields you are selecting. You can specify individual fields or use a
wildcard (*) to specify multiple fields. A select term can be any of the following:
• A simple type, such as string, integer, boolean, date, float, etc. The results list includes the appropriate
data type.
• A BaseObject (stored directly in the database table). The results list includes the BaseObject itself.
• A ClusterRoot (or other field declared explicitly as indirect). The result list includes the BaseID for that
BaseObject (not the object itself).
• A wildcard * character. A wildcard can appear after a class reference or on its own:
• If you use a wildcard after a class reference, the query returns all non-vector fields, including inherited
fields. The wildcard select is applied recursively for embedded (direct) classes.
• If you use a wildcard alone, it must be the only element in the select list. It is interpreted as though it
were applied to each class reference in the FROM clause.
select_list_element ::=
[ field_reference . ] *
| scalar_expression [ [ AS ] field_alias ]
However, it is possible to select fields in BaseObject itself, which is the more common case.
• You cannot query on fields of type ariba.base.core.LongString. LongString is a BaseObject that breaks a
string into chunks of 254 characters or less. You can't query it like a String field because the data is stored
in multiple rows in the database.
• You cannot query directly on fields of type ariba.util.core.Blob, because the results of such a query are
potentially huge. A query such as SELECT BlobField.BlobField FROM
test.ariba.base.core.ObjectWithLob generates a validation error.
• If you omit the select_list, the default select list is the base ID of the first class in the join_term_list.
You use the UNION operator to union two select lists. UNION eliminates duplicates. UNION ALL does not. The
select lists must have the same number of elements, and corresponding positions must be type-compatible.
The Ariba Query API supports UNION only with SELECT statements.
order_by_list ::=
order_by_element ( , order_by_element )*
You can specify the field on which to sort either by name (field_reference) or by position
(<integer_literal>). The first column position is 1.
Class Reference
A class_reference introduces a class name into a query. The class reference is usually a class name, but
can also be a SQL table or view name. You can specify the class reference in any of the following ways:
• By class name. You can query on any class that is defined as a ClusterRoot. Selecting from a class
produces all instances of that class. To restrict a query to specific subclasses, use the SUBCLASS modifier.
(See “Class Modifiers” on page 39.)
• By class name. You can query on specific fields of a class.
• By SQL table or view name. In this case, no class modifiers are allowed.
In general, you should use the full class_name (ariba.basic.core.Country) instead of the simple class_name
(Country), to avoid duplicate class name errors. (Even if the simple class name is unique now, later
extensions can always introduce duplication. It’s safest to always use the full class name.)
If you use the field_reference form and you don’t specify an alias, the simple name of the class is the
default alias. For example:
For compatibility with metadata XML field paths, the name ‘this’ (AQLFieldExpression.ThisFieldName) is
reserved as an implicit alias for the first class reference in the FROM list. For example, consider the following
query:
Field References
A field_reference introduces a field name into a query. A field_reference names a field, and can
potentially use dot notation to navigate the object model. When you use dot notation, the left operand of
each ‘.’ must be a class or field of a class type. The far left-most name must be a class_name (or class alias),
although you can omit the class name if the class can be uniquely determined from the names that are in
scope.
When you use dot notation, as in class.field1.field2, Ariba Query API uses automatic joins to navigate
the implied relationships. Auto-joining always does an inner join (using the same partition, subclass, and
active/inactive information). If you require anything other than the default join type, partition/variant,
subclass or inactive bit, you must use an explicit join, as described in “Join Clauses” on page 41.
Name Scope
Each SELECT statement introduces a new name scope. Scopes nest with names in inner scopes, potentially
hiding names in outer scopes. Each class_reference in a query introduces the following names into the
current scope:
• The class name itself, or the alias name if the class_reference has an alias.
• For the first class in the query, the name ‘this’ is introduced automatically as an alias.
• All field names, including inherited fields.
If a field name is uniquely determined in the current scope, you do not need to qualify it with the class name.
However, it is a validation-time error if the field name is ambiguous in the current scope.
Vector Subscripts
You use a vector_subscript expression to index an expression representing a vector. The subscript must be a
single non-negative integer value, which selects the vector element at that (0-based) position. The only
supported subscript is [0].
This notation is used in field aliases to provide backward compatibility for a field that changed from being
single-valued to being a vector. The original field can be aliased to the first (0th) element of the new vector
field. There are no ‘subscript-out-of-range’ errors. If no element exists for the given index, no element will
match.
Class Modifiers
A class reference in a select statement can include one or more optional class modifiers. Class modifiers are
SQL extensions that you use to select data based on Ariba-specific information, such as partitions and active
status.
class_modifier ::=
class_active
| class_inactive
| class_partition
| class_subclass
If you are using a statement with auto-join, the auto-join uses the active/inactive information from the class
being joined to. If you want to use different active/inactive information, you must use an explicit join.
Restricting by Partition
The PARTITION modifier specifies a partition in which to query for a specified class. If you don’t specify a
partition clause, the default is PARTITION default_partition_name, where default_partition_name is the
default partition from the query options.
If you are querying on a partitioned class, you must specify a partition either in the partition clause or in the
AQLOptions object. If you do not supply the partition clause, and there is no partition in the query options
object, the query results in an error.
partition_specifier ::=
ANY
| NONE
| partition_name
| ( partition_name_list )
partition_name_list ::=
partition_name ( , partition_name_list )*
The partition_specifier indicates which partition to search. You can specify the name of an individual
partition, a list of partitions, or the keywords ANY or NONE:
• Partition_name searches the named partition.
• Partition_name_list searches the listed partitions.
• ANY searches objects in all partitions as well as non-partitioned objects.
• NONE searches only non-partitioned objects.
In general, specifying a partition yields the same data users see in that partition, in the user interface. For
example, consider if you query on a partitioned class that has a unpartitioned superclass, the query results
include fields of that partitioned class that are in the unpartitioned superclass.
If you specify a list of partitions, the Ariba Query API cannot determine whether those partitions are in the
same variant. In this case, the query results include only intrinsic fields or extensions of the ‘Plain’ variant.
• subclass_name_list searches a list of classes and subclasses, recursively. If the list contains more than one
class, only the fields in the superclass named in the class reference may be referenced. You can specify
NOT (subclass_name_list), to search a list of all subclasses except those named and their subclasses.
class_subclass ::=
SUBCLASS subclass_specifier
subclass_name_list ::=
field_reference ( , field_reference )*
Join Clauses
You use a JOIN clause to express a query that selects from multiple tables. The following is a simple
example:
SELECT User.Name
FROM Requisition JOIN User USING Preparer
There are often many different ways to express the same query. For example, a SELECT statement that selects
from multiple table does an implicit inner join. You write an explicit JOIN clause only if you want options
that are not the defaults, or if you prefer the JOIN for readability.
For example, because INNER JOIN is the default, these statements are equivalent:
Join Terms
A JOIN clause must have either a USING clause or an ON clause, to specify the list of columns on which you are
doing the join.
The field specified in a USING clause uses a simplified form of dot notation. It must be either a field name
relative to the previous class or in the form of class.field or alias.field. Therefore, the following query:
SELECT User.Name
FROM Requisition JOIN User ON (Requisition.Preparer = User)
The terms of the condition can be class names, table names, or field names. To use field names on both sides
of the condition, you would use the following syntax:
You must always join on compatible types. For example, in situations where there is a BaseID stored in a
string field, you can use the BaseID function to force the type compatibility. The following query shows how
to join to a POLineItem field, which is a BaseID:
join_term ::=
join_primary
| join_term [ join_type ] JOIN join_primary USING
field_reference
| join_term [ join_type ] JOIN join_primary ON
conditional_expression
join_primary ::=
class_reference
Inner Joins
A join clause can specify a join type (inner or outer; left or right).
An inner join returns results only when the specified column exists in both tables. This is the most common
join. For example, this query:
returns only those User objects that have at least one associated role. It does not include users without roles,
or roles not associated with a user.
Note: Role and User are quoted because they are reserved words. For a list of reserved words, see “Reserved
Words” on page 67.
The auto-join used to implement dot notation always uses an INNER join. To use any other kind of join, you
must use an explicit join type clause. For example, to specify a left outer join from Java code, you could set
Java options as follows:
options.setDefaultAutoJoinType(AQLClassExpression.OpJoinLeftOuter);
SELECT User.Name
FROM Requisition JOIN User ON (Requisition.Preparer = User)
SELECT User.Name
FROM Requisition INNER JOIN User ON (Requisition.Preparer = User)
SELECT User.Name
FROM Requisition INNER JOIN User USING Preparer
Outer Joins
An outer join returns the same results as an inner join, and also includes all rows from either the first table,
or the second, or both. In the users/roles example, a left outer join includes all users, regardless of whether
they have roles, and a right outer join includes all roles, regardless of whether they are associated with a user.
This query always returns at least one row for each user, regardless of whether that user has a role. For users
who have 0 or 1 role this query returns one row. For users who have multiple roles, this query returns as
many rows as the number of roles.
The outer join between User and Role means that users who have 0 roles (column 1 is null) are also returned
in the query. That is, users who have no roles still have a row in the results. This is not true of an inner join.
For example, objects of type Money are embedded in a ClusterRoot, so there is no table created for Money.
You cannot write a query that uses Money as the right operand of a left outer join (such as LEFT OUTER
JOIN Money mon USING des.Price).
In this context, the join terms must be single tables. For example, this syntax causes an assert failed error:
Select c
From Table1,Table2 LEFT OUTER JOIN Table3 USING Table1.SomeField
Conditional Expressions
You use conditional expressions in WHERE clauses, to add constraints to your query. For example, a simple
condition is SELECT x, y FROM z WHERE x = 1 OR y = 1. In Java, the conditional expressions are subclasses
of AQLCondition. Ariba Query API conditionals are like those in SQL.
conditional_primary ::=
comparison_condition
| between_condition
| like_condition
| in_condition
| all_or_any_condition
| exists_condition
| test_for_null_condition
| function_condition
| ( conditional_expression )
Comparison Conditions
A comparison condition selects data using standard comparison operators.
comparison_operator ::=
= | == | < | <= | > | >= | <> | !=
equality_operator ::=
= | == | <> | !=
The Equal and NotEqual operators can be applied to operands of type BOOLEAN, NUMERIC, STRING, DATE, or
BASEID. The other comparison operators may only be applied to operands of type BOOLEAN, NUMERIC, STRING,
or DATE.
For all comparison operators, both operands must be of the same type.
Between Conditions
A between condition selects between two endpoints.
between_operator ::=
BETWEEN
| NOT BETWEEN
The BETWEEN operator is allowed on operands of type BOOLEAN, NUMERIC, STRING, or DATE. All operands must be
of the same type. As in SQL, the BETWEEN operator is inclusive of the end points. For example, this query is
not valid, because the operands are not of like types:
Like Conditions
A like operator selects string data that matches a specified pattern. You can use the following wildcards in
the pattern:
_ matches any single character
% matches a sequence of zero or more characters.
If you need to include one of these wildcard characters as a literal, use an ESCAPE clause to define an escape
character, and then use that escape character in the pattern, as shown in the second example below. An
ESCAPE clause must be a single-character string literal.
like_operator ::=
LIKE
| NOT LIKE
The LIKE operator is case-insensitive. If you want to do a case-sensitive LIKE, you can use the Like function
instead, passing in TRUE for the case-sensitivity flag. (See “Function Calls as Terms” on page 58).
In Conditions
An in condition specifies data that matches the specified list.
in_operator ::=
IN
| NOT IN
The IN operator is allowed on operands of type BOOLEAN, NUMERIC, STRING, DATE, or BASEID. All operands
must be of the same type.
Examples SELECT x.a FROM x WHERE x.b <> ALL (SELECT y FROM z)
SELECT x.a FROM x WHERE x.b = ANY (10, 20, 30)
SELECT x.a FROM x WHERE 10 = ANY x.vector.c
all_any_operator ::=
ALL
| ANY
| SOME
Exists Conditions
An exists condition selects objects that exist in the database.
null_operator ::=
IS [ NOT ] NULL
In the case of BASEOBJECT, baseobject IS [NOT] NULL will be treated as BaseId(baseobject) IS [NOT] NULL.
Note that as in SQL:
expression IS NULL
expression = NULL
Function Conditions
A function condition makes a function call to a function that returns a Boolean. The value of the condition is
the return value of the function.
Combining Conditionals
You can combine conditional expressions with AND, OR, and NOT.
Scalar Expressions
A scalar expression is an expression that represents a single basic data type. Scalar expressions are used
throughout Ariba Query API, in SELECT clauses, WHERE clauses, and conditions. This section describes the
syntax of scalar expressions.
scalar_expression ::=
bitwise_or_expression
Bitwise Or Operator
A scalar expression can use the bitwise OR operator. The bitwise OR operator takes two parameters, both of
INTEGER type.
Example SELECT x.a FROM x WHERE x.b + x.c – x.d > 100
SELECT ‘Name = ‘ || x.a FROM x WHERE x.b = 10
additive_operator ::=
+ | - | ||
For – both operands must be NUMERIC or both operands must be DATE. If you subtract two dates, the result is a
Double, representing the difference in days. For example, to return the number of PurchaseOrders submitted
in the last 30 days:
SELECT COUNT(*)
FROM PurchaseOrder
WHERE CurrentDate() - SubmitDate <= 30
Multiplicative Operator
A scalar expression can use standard multiplication and division operators.Both operands must be NUMERIC.
Unary Operators
A scalar expression can use the standard unary operator. The operand must be NUMERIC.
scalar_factor ::=
[ unary_operator ] scalar_primary
scalar_primary ::=
field_reference
| literal_or_parameter
| scalar_subquery
| case_expression
| ( scalar_expression )
| scalar_function_reference
| aggregate_function_reference
literal_or_parameter ::=
literal
| parameter
Literals as Terms
numeric_literal ::=
<floating_point_literal>
| <integer_literal>
Parameters as Terms
Scalar expressions can include references to query parameters, specified either by name or by position. In a
given query, you must refer to parameters either by name or by position, but you can’t mix the two within a
query. For information on how to supply the parameters at runtime, see “Specifying Query Options” on
page 14.
The type of a parameter is optional, and is usually derived by context. If the type is not specified, and can’t
be determined from context, the query raises a validation error).
Subqueries as Terms
A WHERE clause can use a subquery, within the WHERE clause. The subquery class expression must result in a
single column from a single row. The type of a scalar subquery is the type of its single select list element,
which must be BOOLEAN, NUMERIC, STRING, DATE, or BASEID.
Note that scalar subquery are permitted only in a WHERE clause. They are not permitted in the select list.
Example SELECT
CASE status
WHEN 1 THEN ‘Open’
WHEN 2 THEN ‘Closed’
ELSE ‘Unknown’
END
FROM x
aggregate_function_name ::=
AVG | COUNT | MAX | MIN | Stdev | SUM | Variance
The functions AVG, STDEV, SUM, and VARIANCE take a single argument of a NUMERIC type. The functions MAX and
MIN take a single argument of type BOOLEAN, NUMERIC, STRING, or DATE. The COUNT function can take a single
argument of type BOOLEAN, NUMERIC, STRING, DATE, BASEID, or BASEOBJECT.
The delete statement is only allowed on SQL tables, not classes, and there are restrictions on the update
statement. This section describes the limitations on each statement type.
Update Statements
An update statement changes rows in the database. You can perform an update either on a table or a class.
The only valid update statements are those that modify a single SQL table. If you write update statements
that reference classes, you must ensure that those update statements do not reference fields in more than one
table. For example:
This statement mentions only one class, but the ReceiptNotificationPreferences derives from
ApprovableNotificationPreferences, which is a normalized class—that is, a class that isn’t stored in a single
table. This query results in the following error message:
"ariba.base.core.aql.AQLValidateException:
ariba.base.core.aql.AQLVisitorException: Class ariba.procure.core.ReceiptNotificationPreferences
cannot be UPDATEd because the DML Statement references more than one table".
Also, note that unlike transactionCommit(), the AQL Update does not clear the local session cache. Instead,
the caller is responsible for clearing the cache after an AQL Update is done. In this example, a call to
transactionCommit() is used to clear the session cache:
update_set_list ::=
update_set_element ( , update_set_element )*
update_set_element ::=
field_reference = scalar_expression
Delete Statements
A delete statement deletes a record from a table. The only valid delete statements are those that modify a
single SQL table. You must delete from a table, and not from a class. These restrictions are enforced at
statement validation time.
Create Statements
You use a create statement to execute a SQL CREATE VIEW statement. The SQL CREATE VIEW statement
defines a view, which is a logical table based on one or more tables or views. A view does not contain any
data itself.
The create statement gives the view a name and includes a select statement that provides the columns and
rows of the view. You can then access the new view either from the Query API or directly from SQL, using
external tools.
create_view_statement ::=
CREATE VIEW field_expression [ ( field_reference_list ) ]
AS class_expression
The field_reference_list is an optional list that defines the names of the columns. In the example above,
the columns are UserName and RoleName. If you omit the column names, the default is to use the names
deduced from the SELECT statement. Those column names must be unique. It is a validation error to omit
field_reference_list if the default names are not unique. (In the example above, the default column names
would both be Name, so the explicit column names are required.)
Built-in Functions
This section describes the functions that Ariba Query API provides as built-in functions.
Notes:
• Function names are not keywords (except the ones that are SQL92 reserved words) and are not
case-sensitive.
• Ariba Query API recognizes the SQL standard functions CURRENT DATE, CURRENT TIME, and CURRENT
TIMESTAMP as synonyms for CurrentDate, CurrentTime, and CurrentTimestamp, respectively. For SQL
compatibility, these three functions (only) may appear with no argument list.
String Functions
This section describes string functions.
Returns true if s1 begins with s2. The optional boolean caseSense determines if the comparison is
case-sensitive:
If caseSense is FALSE (the default), BeginsWith is shorthand for
LOWER(s1) LIKE LOWER(s2 || ‘%’)
Returns true if s1 contains s2. The optional boolean caseSense determines if the comparison is
case-sensitive:
If caseSense is FALSE (the default), CONTAINS is shorthand for
LOWER(s1) LIKE LOWER(‘%’ || s2 || ‘%’)
Returns true if s1 ends with s2. The optional boolean caseSense determines if the comparison is
case-sensitive:
If caseSense is FALSE (the default), EndsWith is shorthand for
LOWER(s1) LIKE LOWER(‘%’ || s2)
Behaves as the LIKE function with no escape option, but with the option to be case-sensitive. If the case
parameter is omitted, the default is case-insensitive
Returns s lowercased.
Returns the starting position of s1 in s2, starting at character n. n defaults to 1. Returns 0 if s1 is not in s2.
Returns the portion of s starting at m that is n characters long. If n is omitted, returns the suffix of s
starting at m.
Returns the translation of s1 in the specified language if it exists, otherwise returns the default language
string. s1 is a multi-lingual string field, and s2 is a literal quoted string that is the unique name of a
language object (which is case-sensitive).
Returns s uppercased.
Returns true if the specified searchPattern is found within the binary data stored in the BLOB field;
returns false otherwise. For example:
SELECT ObjectWithLob
FROM test.ariba.base.core.ObjectWithLob
WHERE CONTAINS(SomeBlobField.BlobField, 'mySearchPattern')
• The first argument must be of type ariba.util.core.Blob. In metadata XML, fields are declared of type
ariba.base.core.Blob, which in turn contains a field (always called BlobField), of type
ariba.util.core.Blob. To search a BLOB, you must use dot notation to specify the BLOB field:
YourClass.YourBlobField.BlobField.
• BLOB search relies on content search support in the underlying database. You are responsible for
enabling content search support on your database. If you have not enabled appropriate database support,
the CONTAINS function throws a SQL exception.
Numeric Functions
This section lists the built-in functions related to numeric operations.
Return n rounded to m places to the right of the decimal (or to the left of the decimal if m is negative). m
defaults to 0.
Returns n rounded to m places to the right of the decimal or (to the left of the decimal if m is negative). m
defaults to 0.
Date Functions
This section lists the built-in functions related to dates. Also note that you can subtract dates, as described in
“Addition and Subtraction Operators” on page 53.
Constructs a literal representing a calendar date. The literal is always interpreted as a date in GMT. (To
include a timezone, use the Date function instead.) For example:
SELECT OrderDate FROM Requisition WHERE
OrderDate >= CalendarDate('2001-10-22 00:00:00')
Returns the day of the month (a value in the range 1-31) for the date d. For example:
SELECT xField FROM yClass WHERE DAY(xDate) = 1
Note that the DAY function always returns values in GMT, and does not correct for the timezone in which
the server is located.
Returns the month of the year (a value in the range 1-12) for the date d. For example:
SELECT xField FROM yClass WHERE MONTH(xDate) = 12
Note that the MONTH function always returns values in GMT, and does not correct for the timezone in which
the server is located.
Returns the (four digit) year for the date d. For example:
SELECT xField FROM yClass WHERE Year(xDate) = 1999
Note that the YEAR function always returns values in GMT, and does not correct for the timezone in which
the server is located.
Class Functions
String ClassCode (String class [, String variant] );
String ClassCode (BaseId id);
String ClassCode (BaseObject object);
Evaluates to the internal class code. If variant is omitted, Ariba Query API chooses a default. If the class
is partitioned, the default is the variant for the partition, as specified in the AQLOptions object. If the class
is not partitioned, the default is Plain.
Conversion Functions
The functions in this section convert between BaseIDs, BaseObjects, and the literal representations of those
objects.
Does nothing. Defined only for type safety, so that the conversion of a BaseID to a BaseID is defined as a
valid conversion.
Returns the BaseID corresponding to a string literal representing a BaseID. This is the equivalent of a
BaseID ‘literal’.
Returns the object corresponding to the BaseID. This function has been deprecated and support will be
removed in a future release.
No-op. Defined only for type safety, so that the conversion of a BaseObject to a BaseObject is defined as
a valid conversion. This function has been deprecated and support will be removed in a future release.
Returns the object corresponding to a string literal representation of a BaseId. This function has been
deprecated and support will be removed in a future release.
Miscellaneous Functions
AnyType COALESCE (AnyType Expression1, AnyType Expression2)
Provides the same functionality as the Oracle NVL function or the MSSQLServer ISNULL function. That
is, it evaluates to:
if (Expression1 IS NOT NULL)
then Expression1
else Expression2
The expressions may be of any type, but both expressions must be of the same time.
Known Limitations
The following are known limitations of Ariba Query API:
• There is no function or operator to do field-by-field comparisons on objects.
• GROUP BY and HAVING clauses are not allowed on queries that result in internally generated UNIONs.
• Java method invocation is not supported, (except for callback option).
• The USING clause in an explicit JOIN can only be used against classes.
• The maximum number of parameters in a statement is 254.
This appendix lists all reserved words in Ariba Query API, both those that are currently used by Ariba Query
API and those that are reserved for future use. In the list below, the words in bold are the keywords currently
used by Ariba Query API. The other words are reserved for future use.
This appendix provides reference information on the syntax of command-line tools described in this
document.
aribaquery
You use aribaquery to run database queries from the command line.
Syntax
To run aribquery, type the following at a command prompt in the bin directory:
The command line returns with an AQL> prompt. At that prompt, you can enter Ariba Query API queries. For
example:
To submit a query after entering it, you must either terminate the command with a semicolon, or type go on a
separate line. For example:
Options
The following command line options are available for the aribaquery command. Note that all options are
case-sensitive.
-host hostname
Use this option to specify a specific host name. The host must be explicitly specified; do not use
localhost.
-port port
This option is required. Use it to specify the RPC port used for client connections. In the default
multiserver configuration, the RPC port for the logical node Node1 is 8052; for logical node Node2, the port
is 8056. You can override the default port with any valid port number.
-username username
Use this option to log in as a specific user. The -username flag is almost always used with the -password
option.
-password password
-stdinPassword
Use this option to read a password from standard input. You can use it as an alternative to -password when
security is a concern.
For example, the syntax for -password includes the password immediately on the line:
aribaquery -username vlo -password myPassword
AQL>
But for -stdinPassword, the password is on a separate line, instead of immediately after the
-stdinPassword option:
The advantage of -stdinPassword is that the password is protected from commands like ‘ps’ which would
display the process running without the password.
-Ssl
This option enables secure (encrypted) RPCs when using Secure Socket Layer (SSL). This option is the
default. To run without SSL, use the -noSsl option.
-noSsl
This option disables secure (encrypted) RPCs when using Secure Sockets Layer (SSL). If you are not
using SSL in your configuration, you must specify this option to connect successfully.
-domain domain
Use this option to specify an NT domain to use for authentication. This option is relevant only when you
are using NT Domain Authentication.
-passwordAdapter passwordAdapter
Use this option to specify the password adapter to be used for authentication. This option is required only
if there are multiple password adapters available for the specified user.
-usecache
Use this option to specify that the query results cache should be used. The default is not to use the cache.
-noUsecache
-classupdate
Use this option to specify that queries can make updates to classes.
-noClassupdate
-unionlimit unionlimit
Use this option to specify the maximum number of unions allowed in a generated query.
-echo
Use this option to cause the commands you type to be echoed on the screen. The default is -noecho.
-noEcho
B D
base objects data types 32
fetching 18, 33 dates
baseID literals 31 creating from literals 31
between conditions 46 date format 31
bitwise operations Date function 31
bitwise and 53 expressing as literals 31
bitwise or 52 functions on dates 64
BLOB fields subtracting dates 53
queries on 35 debugging
searching 62 debugging long queries 10
built-in functions 58 log categories 10
delete statements 60
restrictions on 60
C derived fields, queries on 24
division operator 54
cache
dot notation
caching nametable queries 25
in queries 22, 37
query cache 25
OR queries 22
query cache size 26
T
terminal symbols 28
toString method 12
Translation function 62
type, result type 18
U
unary operator 54
update statements 16
restrictions on 16, 58
write access requirements 16
User, as reserved word 22
USING clause, in join 42
V
validating queries 14
vectors 21
accessing from queries 21
auto-join 23
dot notation 23
query example 24
subscripting vectors 38
views
creating SQL views 60
W
wildcard 47
wildcards
escape characters 47
select statements 33
write access, in update operations 16