An identifier is the name of an SQL entity, such as a table, a view, a column (field), a schema, a table alias, a column alias, an index, a stored procedure, a trigger, or some other SQL entity. An identifier name must be unique within its context; for example, two tables in the same schema, or two fields within the same table cannot have the same name. However, two tables in different schemas, or two fields in different tables can have the same name. In most cases, the same identifier name can be used for SQL entities of different types; for example, a schema, a table in that schema, and a field in that table can all have the same name without conflict. However, a table and a view in the same schema cannot have the same name.
Identifiers follow a set of naming conventions, which may be further restricted according to the use of the identifier. Identifiers are not case-sensitive.
The identifier-start is the first character of an SQL identifier. It must be one of the following:
An uppercase or lowercase letter. A letter is defined as any character that passes validation by the ObjectScript $ZNAME function; by default these are the uppercase letters A through Z (ASCII 6590), the lowercase letters a through z (ASCII 97122), and the letters with accent marks (ASCII 192255, exclusive of ASCII 215 and 247). If you have installed the Unicode version of Caché, you can use any valid Unicode (16-bit) letter character within an SQL identifier. Simple identifiers are not case-sensitive (however, see below). By convention they are represented with initial capital letters.
The Japanese locale does not support accented Latin letter characters in identifiers. Japanese identifiers may contain (in addition to Japanese characters) the Latin letter characters A-Z and a-z (6590 and 97122), and the Greek capital letter characters (913929 and 931937).
The identifier-part is any of the subsequent characters of an SQL identifier. These remaining characters may consist of zero or more:
Letters (including Unicode characters).
Numbers. A number is defined as the digits 0 through 9.
At signs (@).
Pound signs (#).
Dollar signs ($).
Some symbol characters are also used as operators. In SQL, the # sign is used as the modulo operator. In SQL, the underscore character can be used to concatenate two strings; this usage is provided for compatibility with ObjectScript, the preferred SQL concatenation operator is ||. The interpretation of a symbol as an identifier character always take precedence over its interpretation as an operator. Any ambiguity concerning the correct parsing of a symbol character as an operator can be resolved by adding spaces before and after the operator.
A simple identifier cannot contain blank spaces or non-alphanumeric characters (other than those symbol characters specified above). The InterSystems SQL import tool removes blank spaces from imported table names.
SQL cursor names do not follow identifier naming conventions. For details on cursor naming conventions, refer to the DECLARE statement.
Caché SQL includes reserved words that cannot be used as simple identifiers. For a list of these reserved words, see the Reserved Words section in the Caché SQL Reference; to test if a word is a reserved word use the $SYSTEM.SQL.IsReservedWord() method. However, a delimited identifier can be the same as an SQL reserved word.
Any identifier that does not follow these naming conventions must be represented as a delimited identifier within an SQL statement.
Caché SQL identifiers by default are not case-sensitive. Caché SQL implements this by comparing identifiers after converting them to all uppercase letters. This has no effect on the actual case of the names being used. (Note that other implementations of SQL may handle case sensitivity of identifiers differently. For this reason, it is recommended that you avoid case-based identifiers.)
Note that cursor names and passwords in Caché SQL are case-sensitive.
Caché provides the IsValidRegularIdentifier() method of the %SYSTEM.SQL class, which tests whether a string is a valid identifier. It tests both for character usage and for reserved words. It also performs a maximum length test of 200 characters (this is an arbitrary length used to avoid erroneous input; it is not an identifier validation). The following ObjectScript example shows the use of this method:
The first three method calls return 1, indicating a valid identifier. The fourth and fifth method calls also return 1; these are valid identifiers, although they are not valid for use as table or field names. The last three method calls return 0, indicating an invalid identifier. Two of these are invalid because they violate the character rules in these cases by beginning with a number or containing a blank. The final method call returns 0 because the specified string is a reserved word. Note that these rule tests are a minimum requirement; they do not certify an identifier as valid for all SQL uses.
This method can also be called as a stored procedure from ODBC or JDBC: %SYSTEM.SQL_IsValidRegularIdentifier("nnnn").
A namespace name (also referred to as a database name) follows identifier naming conventions, with additional restrictions on punctuation characters and maximum length. For further details, refer to the CREATE DATABASE command.
A namespace name can be delimited identifier and can be the same as an SQL reserved word. However, the same namespace name punctuation restrictions apply to both simple identifiers and delimited identifiers.
SQL table names, view names, field names, index names, trigger names, and procedure names are used to generate corresponding persistent class entities by stripping out non-alphanumeric characters. The generated names of class entities and globals follow these translation rules.
Namespace names and SQL schema names and corresponding package names do not follow these translation rules.
Identifiers that differ only in their inclusion of punctuation characters are valid. Because class object names cannot include punctuation characters, Caché generates corresponding unique object names by stripping out all punctuation characters. If stripping out the punctuation characters of an identifier results in a non-unique class object name, Caché creates a unique name by replacing the last alphanumeric character with an incremented character suffix.
For tables, views, fields, triggers, and procedure classmethod names, this is an integer suffix, beginning with 0. For example, myname and my_name generate myname and mynam0, adding my#name generates mynam1. If the number of generated unique names is larger than 10 (mynam9), additional names are generated by substituting a capital letter suffix, starting with A (mynamA). Because tables and views share the same name space, the same suffix counter is incremented for either a table or a view.
If you have defined a name that ends in a suffix character (for example my_name0 or my_indexA, Caché handles unique name generation by incrementing to the next unused suffix.
Identifiers that have a punctuation character as the first character and a number as the second character are not valid for table names, view names, or procedure names. They are valid for field names and index names. If the first character of an SQL field name or index name is a punctuation character (% or _) and the second character is a number, Caché appends a lowercase n as the first character of the corresponding property name.
Identifiers that consist entirely of punctuation characters, or begin with two underscore characters (__name), or contains two pound signs together (nn##nn) are generally invalid as SQL entity names and should be avoided in all contexts.
You can configure translation of specific characters in SQL identifiers to other characters in corresponding object identifiers. This facilitates the use of identifiers across environments where the rules for permitted identifier characters differ. Use the SetDDLIdentifierTranslations() method of the %SYSTEM.SQL class. To determine the current setting, call $SYSTEM.SQL.CurrentSettings().
When converting an SQL identifier to an Objects identifier at DDL runtime, the characters in the From string are converted to the characters in the To string.
Specifying SQL Names in a Class Definition
When you define a persistent class that projects SQL entities, the name of each SQL entity are the same as the name of its corresponding persistent class definition element. To make an SQL table, field, index, or procedure classmethod name different, use the SqlTableName, SqlFieldName, or SqlName (for an index) keyword to specify the SQL name within your class definition. For example:
The maximum length for SQL identifiers is 128 characters. When Caché maps an SQL identifier to the corresponding object entity, it creates the corresponding property, method, query, or index name with a maximum of 96 characters. If two SQL identifiers are identical for the first 96 characters, Caché replaces the 96th character of the corresponding object name with an integer (beginning with 0) to create a unique name.
A delimited identifier is a unique identifier enclosed by delimiter characters. Caché SQL supports double quote characters (") as delimiter characters. Delimited identifiers are generally used to avoid the naming restrictions of simple identifiers.
Note that Caché SQL uses single quote characters (') to delimit literals. For this reason, delimited identifiers must be specified using double quote characters ("), and literals must be specified using single quote characters ('). For example, '7' is the numeric literal 7, but "7" is a delimited identifier.
A delimited identifier must be a unique name. Delimited identifiers are not case-sensitive; by convention, identifiers are represented with initial capital letters.
A delimited identifier can be the same as an SQL reserved word. Delimited identifiers are commonly used to avoid concerns about naming conflicts with SQL reserved words.
A delimited identifier may contain almost any printable character, including blank spaces. Most delimited identifier names cannot contain the following characters: comma (,), period (.), caret (^), and the two-character arrow sequence (->); however delimited identifier role names and user names may contain these characters. A delimited identifier classname may contain periods (.). No delimited identifier may begin with an asterisk (*). The following term cannot be used as a delimited identifier: %vid. Violating these naming conventions results in an SQLCODE -1 error.
A delimited identifier used as a table, schema, column, or index name must be able to be converted to a valid class entity name. Therefore, it must contain at least one alphanumeric character. A delimited identifier that begins with a number (or punctuation followed by a number) generates a corresponding class entity name with the letter n prefix.
The following example shows a query that makes use of delimited identifiers for both column and table names:
SQL includes a long list of reserved words that cannot be used as simple identifiers, but can be used as delimited identifiers. For a list of these reserved words, see the Reserved Words section in the Caché SQL Reference.