在 SQL 中执行 EJB 查询的语法依赖于数据库。通过参考本信息,可以了解在不同的数据库供应商后端上运行 EJB 查询时应该使用哪种经过转换的 SQL 语句。
数据库供应商 | 后端标识 | 描述 |
---|---|---|
DB2 | DB2UDB_V81 | DB2® 通用数据库版本 8.1 Windows® 和 UNIX® 版 |
DB2UDB_V82 | DB2 通用数据库版本 8.2 Windows 和 UNIX 版 | |
DB2UDBOS390_V7 | DB2 通用数据库™ z/OS® 和 OS/390® 版 V7 | |
DB2UDBOS390_V8 | DB2 通用数据库 z/OS 和 OS/390 版 V8 | |
DB2UDBISERIES | DB2 iSeries™ 版 | |
DB2UDBISERIES_V52 | DB2 iSeries V5R2 版 | |
DB2UDBISERIES_V53 | DB2 iSeries V5R3 版 | |
Oracle | ORACLE_V8 | Oracle V8.0 |
ORACLE_V9I | Oracle V9i | |
ORACLE_V10G | Oracle V10g | |
Informix | INFORMIX_V73 | Informix® Dynamic Server.2000 V7.3 |
INFORMIX_V93 | Informix Dynamic Server.2000 V9.3 | |
INFORMIX_V94 | Informix Dynamic Server.2000 V9.4 | |
Sybase | SYBASE_V1200 | Sybase Adaptive Server Enterprise V12.0 |
SYBASE_V1250 | Sybase Adaptive Server Enterprise V12.5 | |
SQL Server | MSSQLSERVER_2000 | Microsoft® SQL Server 2000 |
MSSQLSERVER_V7 | Microsoft SQL Server V7.0 | |
Cloudscape | CLOUDSCAPE_V5 | Cloudscape™ V5.1 |
在 SQL 语句中指定列名的语法依赖于数据库。在 DB2、Oracle 和 Cloudscape 中,列名都要用双引号引起来。以下是适用于 DB2 的经过转换的 SQL 语句的一个示例:
SELECT q1."EMPID", q1."NAME",q1."SALARY" FROM Emp q1
然而,Informix、SQL Server 和 Sybase 则不需要将列名用双引号引起来。以下是适用于 Sybase 的经过转换的 SQL 语句的一个示例:
SELECT q1.EMPID, q1.NAME, q1.SALARY FROM Emp q1
在 SQL 中执行外连接的语法依赖于数据库。
SELECT ... FROM t1 LEFT OUTER JOIN t2 ON t1.col1=t2.col2在 Oracle 中执行外连接的语法不符合 SQL92。Oracle 中的“+”语法用于 SQL 语句的 WHERE 子句中:
SELECT ... FROM t1, t2 WHERE t1.col1=t2.col2 (+)
EJB 查询中包含一些标量函数,用于执行类型转换、字符串处理以及处理日期时间值。有关标量函数的列表的更多信息,请参阅 EJB 查询:标量函数这一主题。
该表中左边的一列列示了 EJB 查询可以包含的标量函数。在 EJB 查询函数列的右边,列示了下推至每列标题中列示的相应后端数据库供应商的 SQL 语法。不包含任何文本的空单元格表示无法将 EJB 查询函数下推至特定的后端数据库供应商,因此,产生无法下推查询这种错误情况。
EJB 查询函数 | DB2 OS390 | DB2 | Oracle | Informix | Sybase | SQL Server | Cloudscape |
---|---|---|---|---|---|---|---|
ABS | abs | abs | abs | abs | abs | abs | abs |
SQRT | sqrt | sqrt | sqrt | sqrt | sqrt | sqrt | sqrt |
CONCAT | concat | concat | concat | || | + | + | || |
LENGTH | length | length | length | length | char_length | len | char_length |
LOCATE | locate | locate | instr | locate | charindex | charindex | locate |
SUBSTRING | substr | substr | substr | substr | substring | substring | substr |
MOD | mod | mod | mod | mod | mod | % | mod |
ucase | upper | upper | upper | upper | upper | upper | upper |
upper | upper | upper | upper | upper | upper | upper | upper |
lcase | lower | lower | lower | lower | lower | lower | lower |
lower | lower | lower | lower | lower | lower | lower | lower |
char | char | char | to_char | char | char | ||
bigint | bigint | ||||||
date | date | date | |||||
decimal | decimal | decimal | |||||
double | double | ||||||
float | float | float | |||||
integer | integer | integer | |||||
real | real | real | |||||
smallint | smallint | ||||||
time | time | time | |||||
timestamp | timestamp | timestamp | |||||
digits | digits | digits | |||||
day | day | day | |||||
days | days | days | |||||
hour | hour | hour | |||||
microsecond | microsecond | microsecond | |||||
minute | minute | minute | |||||
month | month | month | |||||
second | second | second | |||||
year | year | year |
有关日期时间运算和比较的一般知识,请参阅“WebSphere 信息中心”中的日期时间运算和比较这一主题。
DB2 系列支持对 DATE、TIME 和 TIMESTAMP 值使用字符串表示;还支持在 EJB 查询语言中指定运算和比较操作。有关 DB2 中的 DATE、TIME 和 TIMESTAMP 值的详细信息,请参阅日期时间值这一主题。
对于除了 DB2 系列之外的数据库,则不支持对 DATE、TIME 和 TIMESTAMP 值使用字符串表示;也不支持在 EJB 查询语言中指定运算和比较操作。但是,通过使用 Java long 数据类型,就可以用毫秒来表示日期、时间或时间戳记值。日期、时间或时间戳记文字应该是数字文字。要生成毫秒值,可以使用 java.util.Calendar 类。使用 java.util.Calendar 接口来比较不同的 Calendar 对象。
示例对于每个数据库供应商,下表都列示了一个 EJB 查询以及经过转换的 SQL 查询的示例:
后端数据库供应商 | 样本 EJB 查询语句 | 经过转换的 SQL 查询语句 |
---|---|---|
DB2 | SELECT e FROM EmpBean e WHERE e.emp_ts=71039082 | SELECT q1."no", q1."name", q1."emp_ts" FROM userid.iEmp q1 WHERE q1."emp_ts" = '2001-11-12-12.45.55.000123' |
Oracle | SELECT e FROM EmpBean e WHERE e.emp_ts=71039082 | SELECT q1."no", q1."name", q1."emp_ts" FROM userid.iEmp q1 WHERE q1."emp_ts" = TO_DATE ( '1970-1-1-11.43.59','YYYY-MM-DD-HH24.MI.SS') |
Informix | SELECT e FROM EmpBean e WHERE e.emp_ts>71039082 | SELECT q1.no, q1.name, q1.emp_ts FROM userid.iEmp q1 WHERE q1.emp_ts > DATETIME (1970-1-1 11:43:59.082) YEAR TO FRACTION) |
Cloudscape | SELECT e FROM EmpBean e WHERE e.emp_ts<71039082 | SELECT q1."no", q1."name", q1."emp_ts" FROM userid.iEmp q1 WHERE q1."emp_ts" < '1970-1-1-11.43.59.082' |
SQL Server | SELECT e FROM EmpBean e WHERE e.emp_ts=71039082 | SELECT q1.no, q1.name, q1.emp_ts FROM userid.iEmp q1 WHERE q1.emp_ts = 'Jan 1 1970 11:43:59.82 AM' |
Sybase | SELECT e FROM EmpBean e WHERE e.emp_ts=71039082 | SELECT q1.no, q1.name,emp_ts FROM userid.iEmp q1 WHERE q1.emp_ts = 'Jan 1 1970 11:43:59.82 AM' |
并置运算符(CONCAT)将两个字符串操作数连接起来组成一个字符串表达式。并置的操作数必须是兼容的字符串。子串运算符(SUBSTR)将返回一个字符串的子串。
DB2 与其它数据库供应商
在 DB2 中,SUBSTR 和 CONCAT 函数要求使用 CAST 语法,而其它数据库供应商则不要求对 SUBSTR 和 CONCAT 函数执行 CAST。
示例:
SELECT e FROM EmpBean e WHERE SUBSTRING(e.name, 1) = 'John Smith'以下是 z/OS 或 OS/390 上的 DB2 通用数据库的经过转换的 SQL 语句:
SELECT q1."EMPID", q1."NAME" FROM Emp q1 WHERE (CAST(SUBSTR ( q1."NAME", 1) AS VARCHAR(255)) = 'John Smith')以下是 Informix 的经过转换的 SQL 语句:
SELECT q1.EMPID, q1.NAME FROM Emp q1 WHERE SUBSTR(q1.NAME,1)='John Smith'您会发现其它数据库供应商(在本例中为 Informix)对 SUBSTR 函数并不要求使用 CAST 语法。
DB2 iSeries 版和通用数据库 Windows 和 UNIX 版
对于 DB2 iSeries 版和通用数据库 Windows 和 UNIX 版,CONCAT 函数将把组合长度属性 CAST 为 4000,并将结果数据类型强制为 VARCHAR。如果有数据类型为 CHAR 或 VARCHAR 的参数标记,则 CONCAT 函数会将该参数标记的长度属性 CAST 为 32672。
示例:
示例 #1:将组合长度属性 CAST 为 VARCHAR(4000)
SELECT e FROM EmpBean e WHERE concat(e.name, 'ahmad') = 'deptahmad'经过转换的 SQL 语句:
SELECT q2."no", q2."name" FROM userid.Emp q1 WHERE (CAST(concat ( q1."name", 'ahmad') AS VARCHAR(4000)) = 'deptahmad')
SELECT d.name FROM DeptBean d WHERE CONCAT(?1,?2) = 'Firstname1' {_varchar,_varchar}
SELECT q1."name" FROM userid.Deptc q1 WHERE (CAST(concat (CAST(? AS VARCHAR(32672)), CAST(? AS VARCHAR(32672))) AS VARCHAR(4000)) = 'Firstname1')
DB2 通用数据库 z/OS 和 OS/390 版
SELECT e FROM EmpBean e WHERE SUBSTRING(e.name, 1) = 'John Smith'经过转换的 SQL 语句:
SELECT q1."EMPID", q1."NAME" FROM Emp q1 WHERE (CAST(SUBSTR ( q1."NAME", 1) AS VARCHAR(255)) = 'John Smith')
UPDATE SET X=? WHERE X = ?
使用 SELECT 语句获得更新锁定的语法依赖于数据库。下表总结了每个数据库供应商后端的经过转换的 SQL 语句:
数据库后端 | 经过转换的 SQL 语句 |
---|---|
DB2UDB_V81 | SELECT ... FOR UPDATE OF column_name |
DB2UDB_V82 | SELECT ... FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS |
DB2UDBOS390_V7 | SELECT ... FOR UPDATE OF column_name WITH RS KEEP UPDATE LOCKS |
DB2UDBOS390_V8 | SELECT ... FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS |
DB2UDBISERIES | SELECT ....FOR UPDATE OF column_name |
DB2UDBISERIES_V52 | SELECT ....FOR UPDATE OF column_name |
DB2UDBISERIES_V53 | SELECT ....FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS |
Oracle | SELECT ..FOR UPDATE |
Informix | SELECT ..FOR UPDATE |
Sybase | SELECT ..FOR UPDATE |
SQL Server | SELECT .. FROM TABLE t1 (UPDLOCK) |
Cloudscape | SELECT ..FOR UPDATE OF column_name |