Developer Reference : Data Access Methods : SQL Engine Reference : SQL Syntax Reference : WHILE
 
WHILE
Use a WHILE statement is used to control flow. It allows code to be executed repeatedly as long as the WHILE condition is true. Optionally, you may use the WHILE statement with DO and END WHILE.
Note You cannot use a mixed syntax for the WHILE statement. You may use either WHILE with DO and END WHILE, or only WHILE.
If you are using multiple statements with a WHILE condition, you must use BEGIN and END to indicate the beginning and ending of the statement blocks.
Syntax
[ label-name : ] WHILE proc-search-condition [ DO ] [ proc-stmt [; proc-stmt ] ]...
[ END WHILE ][ label-name ]
Remarks
A WHILE statement can have a beginning label, in which case it is called a labeled WHILE statement.
Examples
The following example increments the variable vInteger by 1 until it reaches a value of 10, when the loop ends.
WHILE (:vInteger < 10) DO
SET :vInteger = vInteger + 1;
END WHILE
See Also
CREATE PROCEDURE
CREATE TRIGGER
Grammar Element Definitions
The following is an alphabetical list of element definitions used in the grammar syntax.
alter-options ::= alter-option-list1 | alter-option-list2
 
alter-option-list1 ::= alter-option |(alter-option [, alter-option ]...)
 
alter-option ::= ADD [ COLUMN ] column-definition
| ADD table-constraint-definition
| ALTER [ COLUMN ] column-definition
| DROP [ COLUMN ] column-name
| DROP CONSTRAINT constraint-name
| DROP PRIMARY KEY
| MODIFY [ COLUMN ] column-definition
 
alter-option-list2 ::= PSQL_MOVE [ COLUMN ] column-name TO [ [ PSQL_PHYSICAL ] PSQL_POSITION ] new-column-position | RENAME COLUMN column-name TO new-column-name
 
as-or-semicolon ::= AS | ;
 
before-or-after ::= BEFORE | AFTER
 
call-arguments ::= positional-argument [ , positional-argument ]...
 
col-constraint ::= NOT NULL
| NOT MODIFIABLE
| UNIQUE
| PRIMARY KEY
| REFERENCES table-name [ ( column-name ) ] [ referential-actions ]
 
collation-name ::= 'string'
 
column-constraint ::= [ CONSTRAINT constraint-name ] col-constraint
 
column-definition ::= column-name data-type [ DEFAULT Expression ] [ column-constraint [ column-constraint ]... [CASE | COLLATE collation-name ]
 
column-name ::= user-defined-name
 
commit-statement ::= see COMMIT statement
 
comparison-operator ::= < | > | <= | >= | = | <> | !=
 
constraint-name ::= user-defined-name
 
correlation-name ::= user-defined-name
 
cursor-name ::= user-defined-name
 
data-type ::= data-type-name [ (precision [ , scale ] ) ]
 
data-type-name ::= see Zen Supported Data Types
 
db-name ::= user-defined-name
 
expression::= expression - expression
| expression + expression
| expression * expression
| expression / expression
| expression & expression
| expression | expression
| expression ^ expression
| ( expression )
| -expression
| +expression
| ~expression
| ?
| literal
| scalar-function
| { fn scalar-function }
| USER
 
 
literal ::= 'string' | N'string'
| number
| { d 'date-literal' }
| { t 'time-literal' }
| { ts 'timestamp-literal' }
 
scalar-function :: = See Scalar Functions
 
expression-or-subquery ::= expression | ( query-specification )
 
fetch-orientation ::= NEXT
 
group-name ::= user-defined-name
 
index-definition ::= ( index-segment-definition [ , index-segment-definition ]... )
 
index-name ::= user-defined-name
 
index-number ::= user-defined-value (an integer between 0 and 118)
index-segment-definition ::= column-name [ ASC | DESC ]
 
ins-upd-del ::= INSERT | UPDATE | DELETE
 
insert-values ::= values-clause
| query-specification
 
join-definition ::= table-reference [ INNER ] JOIN table-reference ON search-condition
| table-reference CROSS JOIN table-reference
| outer-join-definition
 
label-name ::= user-defined-name
 
literal ::= 'string' | N'string'
| number
| { d 'date-literal' }
| { t 'time-literal' }
| { ts 'timestamp-literal' }
 
order-by-expression ::= expression [ CASE | COLLATE collation-name ] [ ASC | DESC ]
 
outer-join-definition ::= table-reference outer-join-type JOIN table-reference ON search-condition
 
outer-join-type ::= LEFT [ OUTER ]| RIGHT [ OUTER ] | FULL [ OUTER ]
 
parameter ::= parameter-type-name data-type [ DEFAULT proc-expr | = proc-expr ]
| SQLSTATE
 
parameter-type-name ::= parameter-name
| parameter-type parameter-name
| parameter-name parameter-type
 
parameter-type ::= IN | OUT | INOUT | IN_OUT
 
parameter-name ::= [ : ] user-defined-name
 
password ::= user-defined-name | 'string'
 
positional-argument ::= expression
 
precision ::= integer
 
predicate ::= expression [ NOT ] BETWEEN expression AND expression
| expression comparison-operator expression-or-subquery
| expression [ NOT ] IN ( query-specification )
| expression [ NOT ] IN ( value [ , value ]... )
| expression [ NOT ] LIKE value
| expression IS [ NOT ] NULL
| expression comparison-operator ANY ( query-specification )
| expression comparison-operator ALL ( query-specification )
| EXISTS ( query-specification )
 
proc-expr ::= same as normal expression but does not allow IF expression, or scalar functions
 
proc-search-condition ::= same as search-condition but does not allow expressions with subqueries
 
proc-stmt ::= [ label-name : ] BEGIN [ ATOMIC ] [ proc-stmt [ ; proc-stmt ]... ] END [ label-name ]
| CALL procedure-name ( proc-expr [ , proc-expr ]... )
| CLOSE cursor-name
| DECLARE cursor-name CURSOR FOR select-statement [ FOR UPDATE | FOR READ ONLY ]
| DECLARE variable-name data-type [ DEFAULT proc-expr | = proc-expr ]
| DELETE WHERE CURRENT OF cursor-name
| delete-statement
| FETCH [ fetch-orientation [ FROM ] ] cursor-name [ INTO variable-name [ , variable-name ] ]
| IF proc-search-condition THEN proc-stmt [ ; proc-stmt ]... [ ELSE proc-stmt [ ; proc-stmt ]... ] END IF
| IF proc-search-condition proc-stmt [ELSE proc-stmt]
| insert-statement
| LEAVE label-name
| [ label-name : ] LOOP proc-stmt [ ; proc-stmt ]... END LOOP [ label-name ]
| OPEN cursor-name
| PRINT proc-expr [ , 'string' ]
| RETURN [ proc-expr ]
| transaction-statement
| select-statement-with-into
| select-statement
| SET variable-name = proc-expr
| SIGNAL [ ABORT ] sqlstate-value
| START TRANSACTION [tran-name]
| update-statement
| UPDATE SET column-name = proc-expr [ , column-name = proc-expr ]... WHERE CURRENT OF cursor-name
| [ label-name : ] WHILE proc-search-condition DO [ proc-stmt [ ; proc-stmt ] ]... END WHILE [ label-name ]
| [ label-name : ] WHILE proc-search-condition proc-stmt
| alter-table-statement
| create-index-statement
| create-table-statement
| create-view-statement
| drop-index-statement
| drop-table-statement
| drop-view-statement
| grant-statement
| revoke-statement
| set-statement
 
procedure-name ::= user-defined-name
 
public-or-user-group-name ::= PUBLIC | user-group-name
 
query-specification [ [ UNION [ ALL ] query-specification ]...
[ limit-clause ][ ORDER BY order-by-expression [ , order-by-expression ]... ] [ FOR UPDATE ]
 
query-specification ::= ( query-specification )
| SELECT [ ALL | DISTINCT ] [ top-clause ] select-list
FROM table-reference [ , table-reference ]...
[ WHERE search-condition ]
[ GROUP BY expression [ , expression ]...
[ HAVING search-condition ] ]
 
referencing-alias ::= OLD [ AS ] correlation-name [ NEW [ AS ] correlation-name ]
| NEW [ AS ] correlation-name [ OLD [ AS ] correlation-name ]
 
referential-actions ::= referential-update-action [ referential-delete-action ]
| referential-delete-action [ referential-update-action ]
 
referential-update-action ::= ON UPDATE RESTRICT
 
referential-delete-action ::= ON DELETE CASCADE
| ON DELETE RESTRICT
 
release-statement ::= see RELEASE statement
 
result ::= user-defined-name data-type
 
rollback-statement ::= see ROLLBACK WORK statement
 
savepoint-name ::= user-defined-name
 
scalar-function ::= see Scalar Function list
 
scale ::= integer
 
search-condition ::= search-condition AND search-condition
| search-condition OR search-condition
| NOT search-condition
| ( search-condition )
| predicate
 
select-item ::= expression [ [ AS ] alias-name ] | table-name.*
 
select-list ::= * | select-item [ , select-item ]...
 
set-function ::= AVG ( [ DISTINCT | ALL ] expression )
| COUNT ( < * | [ DISTINCT | ALL ] expression > )
| COUNT_BIG ( < * | [ DISTINCT | ALL ] expression > )
| MAX ( [ DISTINCT | ALL ] expression )
| MIN ( [ DISTINCT | ALL ] expression )
| STDEV ( [ DISTINCT | ALL ] expression )
| STDEVP ( [ DISTINCT | ALL ] expression )
| SUM ( [ DISTINCT | ALL ] expression )
| VAR ( [ DISTINCT | ALL ] expression )
| VARP ( [ DISTINCT | ALL ] expression )
 
sqlstate-value ::= 'string'
 
table-constraint-definition ::= [ CONSTRAINT constraint-name ] table-constraint
 
table-constraint ::= UNIQUE (column-name [ , column-name ]... )
| PRIMARY KEY ( column-name [ , column-name ]... )
| FOREIGN KEY ( column-name [ , column-name ] )
REFERENCES table-name
[ ( column-name [ , column-name ]... ) ]
[ referential-actions ]
 
table-element ::= column-definition
| table-constraint-definition
 
table-expression ::=
FROM table-reference [ , table-reference ]...
[ WHERE search-condition ]
[ GROUP BY expression [ , expression ]...
[ HAVING search-condition ]
 
table-name ::= user-defined-name
 
table-permission ::= ALL
| SELECT [ ( column-name [ , column-name ]... ) ]
| UPDATE [ ( column-name [ , column-name ]... ) ]
| INSERT [ ( column-name [ , column-name ]... ) ]
| DELETE
| ALTER
| REFERENCES
 
table-reference ::= { OJ outer-join-definition }
| [db-name.]table-name [ [ AS ] alias-name ]
| join-definition
| ( join-definition )
 
table-subquery ::= query-specification [ [ UNION [ ALL ]
query-specification ]...][ limit-clause ][ ORDER BY order-by-expression [ , order-by-expression ]...]
 
limit-clause ::= [ LIMIT [offset,] row_count | row_count OFFSET offset | ALL [OFFSET offset] ]
 
offset ::= number | ?
row_count ::= number | ?
 
transaction-statement ::= commit-statement
| rollback-statement
| release-statement
 
trigger-name ::= user-defined-name
 
user_and_password ::= user-name [ : ] password
 
user-group-name ::= user-name | group-name
 
user-name ::= user-defined-name
 
value ::= literal | USER | NULL | ?
 
value-list ::= ( value [ , value ]... )
 
values-clause ::= DEFAULT VALUES | VALUES ( expression [ , expression ]... )
 
variable-name ::= user-defined-name
 
view-name ::= user-defined-name
SQL Statement List
SqlStatementList is defined as:
SqlStatementList
statement ';' | SqlStatementList ';'
statement ::= statement-label ':' statement
| BEGIN ... END block
| CALL statement
| CLOSE CURSOR statement
| COMMIT statement
| DECLARE CURSOR statement
| DECLARE variable statement
| DELETE statement
| FETCH statement
| IF statement
| INSERT statement
| LEAVE statement
| LOOP statement
| OPEN statement
| PRINT statement
| RELEASE SAVEPOINT statement
| RETURN statement
| ROLLBACK statement
| SAVEPOINT statement
| SELECT statement
| SET statement
| SIGNAL statement
| START TRANSACTION statement
| UPDATE statement
| WHILE statement
Predicate
A predicate is defined as:
expression compare-operator expression
| expression [ NOT ] BETWEEN expression AND expression
| expression [ NOT ] LIKE string-literal
| expression IS [ NOT ] NULL
| NOT predicate
| predicate AND predicate
| predicate OR predicate
| '(' predicate ')'compare-operator ::= '=' | '>=' | '>' | '<=' | '<' | '<>' | '!='
| [ NOT ] IN value-list
Expression
An expression is defined as:
number
| string-literal
| column-name
| variable-name
| NULL
| CONVERT '(' expression ',' data-type ')'
| '-' expression
| expression '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression
| expression '&' expression
| '~' expression
| expression '|' expression
| expression '^' expression
| function-name '(' [ expression-list ] ')'
| '(' expression')'
| '{' D string-literal '}'
| '{' T string-literal '}'
| '{' TS string-literal '}'
| @:IDENTITY
| @:ROWCOUNT
| @@BIGIDENTITY
| @@IDENTITY
| @@ROWCOUNT
| @@VERSION
An expression list is defined as:
expression-list ::= expression [ , expression ... ]
Global Variables
Zen supports the following global variables:
@@IDENTITY and @@BIGIDENTITY
@@ROWCOUNT
@@SESSIONID
@@SPID
@@VERSION
Global variables are prefaced with two at signs, @@. All global variables are variables per connection. Each database connection has its own @@IDENTITY, @@BIGIDENTITY, @@ROWCOUNT, and @@SPID values. The value of @@VERSION is information about the version of the engine that executes the statement where it is used.
@@IDENTITY and @@BIGIDENTITY
Either of these variables returns its most recently inserted column value. The value is a signed integer value. The initial value is NULL.
The variable can refer to only a single column. If the target table includes more than one IDENTITY column, the value of this variable refers to the IDENTITY column serving as the table primary key. If no such column exists, then the value of this variable refers to the first IDENTITY column in the table.
If the most recent insert was to a table without an IDENTITY column, then the value of @@IDENTITY is set to NULL.
For BIGIDENTITY values, use @@BIGIDENTITY. For SMALLIDENTITY values, use @@IDENTITY.
Examples
SELECT @@IDENTITY
Returns NULL if no records have been inserted in the current connection, otherwise returns the IDENTITY column value of the most recently inserted row.
SELECT * FROM t1 WHERE @@IDENTITY = 12
Returns the most recently inserted row if it has an IDENTITY column value of 12. Otherwise, returns no rows.
INSERT INTO t1(c2) VALUES (@@IDENTITY)
Inserts the IDENTITY value of the last row inserted into column C2 of the new row.
UPDATE t1 SET t1.c1 = (SELECT @@IDENTITY) WHERE t1.c1 = @@IDENTITY + 10
Updates column C1 with the IDENTITY value of the last row inserted, if the value of C1 is 10 greater than the IDENTITY column value of the last row inserted.
UPDATE t1 SET t1.c1 = (SELECT NULL FROM t2 WHERE t2.c1 = @@IDENTITY)
Updates column C1 with the value NULL if the value of C1 equals the IDENTITY column value of the last row inserted.
The example below creates a stored procedure and calls it. The procedure sets variable V1 equal to the sum of the input value and the IDENTITY column value of the last row updated. The procedure then deletes rows from the table anywhere column C1 equals V1. The procedure then prints a message stating how many rows were deleted.
CREATE PROCEDURE TEST (IN :P1 INTEGER);
BEGIN
DECLARE :V1 INTERGER;
SET :V1 = :P1 + @@IDENTITY;
DELETE FROM t1 WHERE t1.c1 = :V1;
IF (@@ROWCOUNT = 0) THEN
PRINT 'No row deleted';
ELSE
PRINT CONVERT(@@ROWCOUNT, SQL_CHAR) + ' rows deleted';
END IF;
END;
CALL TEST (@@IDENTITY)
@@ROWCOUNT
This variable returns the number of rows that were affected by the most recent operation in the current connection. The value is an unsigned integer. The initial value is zero.
The @@ROWCOUNT variable is valid only when used after an INSERT, UPDATE, or DELETE statement.
Examples
SELECT @@ROWCOUNT
Returns zero if no records were affected by the previous operation in the current connection, otherwise returns the number of rows affected by the previous operation.
CREATE TABLE t1 (c1 INTEGER, c2 INTEGER)
INSERT INTO t1 (c1, c2) VALUES (100,200)
INSERT INTO t1(c1, c2) VALUES (300, @@ROWCOUNT)
SELECT @@ROWCOUNT
Results:
1 (in @@ROWCOUNT variable)
In line four, the @@ROWCOUNT variable has the value of 1 because the previous INSERT operation affected one row.
Also see the example for @@IDENTITY.
@@SESSIONID
This variable returns an eight-byte integer value that identifies the connection to a Zen server engine, reporting engine, or workgroup engine. The integer is a combination of a time value and an incremental counter. This variable can be used to identify uniquely each Zen connection.
@@SESSIONID requires a connection to the database engine to return a value. If the connection to the database engine is lost, the variable cannot return an identifier.
Example
SELECT @@SESSIONID
The example returns an integer identifier such as 26552653137523.
@@SPID
This variable, the server process identifier, returns the identifier integer value of the system thread for the Zen connection.
If the connection to the database engine is lost, the SPID variable cannot return an identifier. Instead, the statement returns an error with a SqlState of 08S01.
Example
SELECT @@SPID
The example returns an integer identifier, such as 402.
@@VERSION
SQL statements that use this variable return a value based on the Zen server engine, reporting engine, or workgroup engine to which the session is connected.
For a Zen server, the value is the version of the local engine and the bitness, name, and version of the local operating system.
For Zen Client Reporting Engine, it is the version of the local reporting engine and the bitness, name, and version of the local operating system.
For Zen Client, it is the version of the engine on the remote Zen server to which the client is connected and the bitness, name, and version of the operating system where the server is running.
For Zen Workgroup Engine, the value is the version of the local engine and the bitness, name, and version of the local operating system.
Example
SELECT @@version
The example returns text information resembling the following:
Actian Zen - 14.10.020.000 (x86_64) Server Engine - Copyright (C) Actian Corporation 2019 on (64-bit) Windows NT 6.2 7d
Other Characteristics
This topic describes other characteristics of the SQL grammar. It is divided into the following sections:
Temporary Files
Working with NULL Values
Working with Binary Data
Creating Indexes
Comma as Decimal Separator
Temporary Files
When Zen must generate a temporary table in order to process a given query, it creates the file in a location determined in one of the following ways:
If you have manually added the string key value PervasiveEngineOptions\TempFileDirectory to ODBC.INI, Zen uses the path set for TempFileDirectory. The proper location for both 32- and 64-bit Zen installations on Windows is the registry location HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI. For Linux, macOS, and Raspbian, the ODBC.INI file is located in /usr/local/actianzen/etc.
If you have set the temporary file directory property for a Zen engine using ZenCC or bcfg, Zen uses this location. For more information, see Temporary Files in Advanced Operations Guide.
If you have not used either of the first two options listed here, then Zen checks for the file location using the following sequence on Window platforms:
1 The path specified by the TMP environment variable
2 The path specified by the TEMP environment variable
3 The path specified by the USERPROFILE environment variable
4 The Windows directory
For example, if the TMP environment variable is not defined, Zen uses the path specified in the TEMP environment variable, and so on.
On Linux and macOS distributions, Zen uses the current directory for the server process. No attempt is made to use TMP.
Zen deletes all temporary files used to process a query after the query is finished. If the query is a SELECT statement, then the temporary files exist as long as the result set is active, meaning until the result set is freed by the calling application.
When Are Temporary Files Created?
Zen uses three types of temporary files: in-memory, on-disk, and Btrieve (MicroKernel Engine).
In-Memory Temporary File
In-memory temporary files are used for the following circumstances:
Forward-only cursor
Number of bytes in the temporary file is less than 250,000.
SELECT statements with ORDER BY, GROUP BY, or DISTINCT that do not use an index, that have no BLOB or CLOB in the ORDER BY, GROUP BY, or DISTINCT, and that have no BLOB or CLOB in selection list with UNION.
On-Disk Temporary File
On-disk temporary files are used for the following circumstances:
Forward-only cursor
Number of bytes in the temporary file is greater than 250,000.
SELECT statements with ORDER BY, GROUP BY, or DISTINCT that do not use an index, that have no BLOB or CLOB in the ORDER BY, GROUP BY, or DISTINCT, and that have no BLOB or CLOB in selection list with UNION.
Btrieve Temporary File
Btrieve temporary files are used for the following circumstances:
Forward-only cursor with BLOB or CLOB in ORDER BY, GROUP BY, or DISTINCT or with BLOB or CLOB in selection list with UNION
Dynamic or static cursor with UNION queries or SELECT statements with ORDER BY, GROUP BY, or DISTINCT that do not use an index.
Zen does not create a Btrieve temporary file for each base table in a static cursor SELECT query. Instead, each base table is opened by using the MicroKernel to reserve pages in the file as a static representation of the file. Any change made through a static cursor cannot be seen by that cursor.
Working with NULL Values
Zen interprets a NULL as an unknown value. Thus, if you try to compare two NULL values, they will compare as not equal.
An expression that evaluates to WHERE NULL=NULL returns FALSE.
Working with Binary Data
Consider the following scenario: you insert the literal value '1' into a BINARY(4) column named c1, in table t1. Next, you enter the statement, SELECT * FROM t1 WHERE c1='1'.
The engine can retrieve data using the same binary format as was used to input the data. That is, the SELECT example above works properly and returns the value, 0x01000000, even though there is no literal match.
Note The engine always adds a zero (‘0’) to the front of odd-digit binary values that are inserted. For example, if you insert the value '010', then the value '0x00100000' is stored in the data file.

Currently, Zen does not support suffix 0x to denote binary constants. Binary constants are a string of hexadecimal numbers enclosed by single quotation marks.
This behavior is the same as for Microsoft SQL Server.
Creating Indexes
The maximum column size for indexable VARCHAR columns is 254 bytes if the column does not allow Null values and 253 bytes if the column is nullable.
The maximum column size for CHAR columns is 255 bytes if the column does not allow Null values and 254 bytes if the column is nullable.
The maximum column size for indexable NVARCHAR columns is NVARCHAR(126). This limit applies to both nullable and not-null columns. The NVARCHAR size is specified in UCS-2 character units.
The maximum column size for NCHAR columns is NCHAR(127). This limit applies to both nullable and not-null columns. The NCHAR size is specified in UCS-2 character units.
The maximum Btrieve key size is 255. When a column is nullable and indexed a segmented key is created with 1 byte for the null indicator and a maximum 254 bytes from the column indexed. VARCHAR columns differ from CHAR columns in that either length byte (Btrieve lstring) or a zero terminating byte (Btrieve zstring) are reserved, increasing the effective storage by 1 byte. NVARCHAR (Btrieve wzstring) columns differ from NCHAR columns in that a zero terminating character is reserved, increasing the effective storage by 2 bytes.
Comma as Decimal Separator
Many locales use a comma to separate whole numbers from fractional numbers within a floating point numeric field. For example, they would use 1,5 instead of 1.5 to represent the number one-and-one-half.
Zen supports both the period and the comma as decimal separators. Zen accepts input values using the period or the comma, based on the regional settings for the operating system. By default, the database engine displays values using the period.
Note When the decimal separator is not a period, numbers appearing in SQL statements must be enclosed in quotes.
For output and display only, the session-level command SET DECIMALSEPARATORCOMMA can be used to specify output (for example, SELECT results) that uses the comma as the decimal separator. This command has no effect on data entry or storage.
Client-Server Considerations
Support for the comma as decimal separator is based on the locale setting in the operating system. Both the client operating system and the server operating system have a locale setting. The expected behavior varies according to both settings.
If either the server or client locale setting uses the comma as decimal separator, then Zen accepts both period-separated values and quoted comma-separated values.
If neither the server nor the client locale setting uses the comma decimal separator, then Zen does not accept comma-separated values.
Changing the Locale Setting
Decimal separator information can be retrieved or changed only for a machine running a Windows operating system. The decimal setting for Linux and macOS cannot be configured, and it is set to a period. If you have a Linux and macOS server engine and you want to use a comma as decimal separator, you must ensure that all your client computers are set to a locale that uses the decimal separator.
To change the regional settings on a Windows operating system, access the settings from the Control Panel. Stop and restart Zen services after your change to enable the database engine to use the setting.
Examples
Example A - Server locale uses a comma for decimal separator
Client locale uses a comma as decimal separator:
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1.232')
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 FROM c1 = '10,123'
The above two SELECT statements, if executed from the client, return:
10.123, 1.232
10.123, 1.232
SET DECIMALSEPARATORCOMMA=ON
SELECT * FROM t1 FROM c1 = '10,123'
The above SELECT statement, if executed from the client after setting the decimal separator, returns:
10,123, 1,232
Client locale uses period as decimal separator, and these statements are issued from a new connection (meaning default behavior for SET DECIMALSEPARATORCOMMA):
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1.232')
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 WHERE c1 = '10,123'
The above two SELECT statements, if executed from the client, return:
10.123, 1.232
10.123, 1.232
Example B - Server locale uses the period for decimal separator
Client locale uses comma as decimal separator:
Same as client using comma in Example A.
Client locale uses period as decimal separator:
CREATE TABLE t1 (c1 DECIMAL(10,3), c2 DOUBLE)
INSERT INTO t1 VALUES (10.123, 1.232)
INSERT INTO t1 VALUES ('10,123', '1,232') -- error in assignment
SELECT * FROM t1 WHERE c1 = 10.123
SELECT * FROM t1 WHERE c1 = '10,123' -- error in assignment
The first select statement above, if executed from the client, returns:
10.123, 1.232
SET DECIMALSEPARATORCOMMA=ON
SELECT * FROM t1 FROM c1 = 10.123
The above SELECT statement, if executed after setting the decimal separator for display, returns:
10,123, 1,232