第一章 InterSystems SQL简介
InterSystems SQL提供对InterSystems IRIS®Data Platform数据库中存储的数据的无懈可击的标准关系访问。
InterSystems SQL提供以下优势:
- 高性能和可扩展性-InterSystems SQL提供优于其他关系数据库产品的性能和可扩展性。此外,InterSystems SQL可以在各种硬件和操作系统上运行;从笔记本电脑到高端多CPU系统。
- 与InterSystems IRIS对象技术集成-InterSystems SQL与InterSystems IRIS Object技术紧密集成。可以混合使用关系访问和对象访问数据,而不会牺牲任何一种方法的性能。
- 维护成本低-与其他关系数据库不同,InterSystems IRIS应用程序不需要在已部署的应用程序中重建索引和压缩表格。
- 支持标准SQL查询-InterSystems SQL支持SQL-92标准语法和命令。在大多数情况下,可以毫不费力地将现有关系应用程序迁移到InterSystems IRIS,并自动利用InterSystems IRIS更高的性能和对象功能。
可以将InterSystems SQL用于多种目的,包括:
- 基于对象和基于Web的应用程序-可以在InterSystems IRIS对象和Web Server Page应用程序中使用SQL查询来执行强大的数据库操作,如查找和搜索。
- 在线事务处理-InterSystems SQL为INSERT和UPDATE操作以及事务处理应用程序中常见的查询类型提供了出色的性能。
- 商业智能和数据仓库-InterSystems IRIS多维数据库引擎和位图索引技术的结合使其成为数据仓库式应用程序的最佳选择。
- 即时查询和报告-可以使用InterSystems SQL附带的功能齐全的ODBC和JDBC驱动程序连接到流行的报告和查询工具。
- 企业应用程序集成-InterSystems SQL Gateway使能够无缝地通过SQL访问ODBC或JDBC兼容的外部关系数据库中存储的数据。这使得在InterSystems IRIS应用程序中集成来自各种来源的数据变得容易。
架构
InterSystems SQL的核心由以下组件组成:
- 统一数据字典-存储为一系列类定义的所有元信息的存储库。InterSystems IRIS自动为统一字典中存储的每个持久类创建关系访问(表)。
- SQL处理器和优化器-一组程序,用于解析和分析SQL查询,确定给定查询的最佳搜索策略(使用复杂的基于成本的优化器),并生成执行查询的代码。
- InterSystems SQL Server-一组InterSystems IRIS服务器进程,负责与InterSystems ODBC和JDBC驱动程序的所有通信。它还管理频繁使用的查询的高速缓存;当同一查询被多次执行时,可以从查询高速缓存中检索其执行计划,而不必由优化器再次处理。
特点
InterSystems SQL包括一整套标准的关系型功能。这些措施包括:
- 定义表和视图(DDL或数据定义语言)的能力。
- 对表和视图(DML或数据操作语言)执行查询的能力。
- 能够执行事务,包括插入、更新和删除操作。执行并发操作时,InterSystems SQL使用行级锁。
- 为更高效的查询定义和使用索引的能力。
- 能够使用各种数据类型,包括用户定义的类型。
- 定义用户和角色并为其分配权限的能力。
- 定义外键和其他完整性约束的能力。
- 定义INSERT、UPDATE和DELETE触发器的能力。
- 定义和执行存储过程的能力。
- 能够以不同的格式返回数据:用于客户端访问的ODBC模式;用于在基于服务器的应用程序中使用的显示模式。
符合SQL-92
SQL-92标准在算术运算符优先级方面是不精确的;关于这一问题的假设因SQL实现而异。InterSystems SQL支持将系统配置为以下任一系统范围的SQL算术运算符优先级替代方案:
- InterSystems SQL可以配置为严格按照从左到右的顺序解析算术表达式,没有运算符优先级。这与ObjectScript中使用的约定相同。因此,3+35=30。可以使用括号来强制执行所需的优先顺序。因此,3+(35)=18。
- InterSystems SQL可以配置为使用ANSI优先级分析算术表达式,这为乘法和除法运算符提供了比加法、减法和串联运算符更高的优先级。因此,3+35=18。如果需要,可以使用括号覆盖此优先级。因此,(3+3)5=30。
SQL运算符优先级的默认值取决于InterSystems IRIS版本。
InterSystems SQL支持完整的入门级SQL-92标准,但有以下例外:
- 不支持向表定义添加附加的CHECK约束。
- 不支持SERIALIZABLE(序列化)隔离级别。
- 分隔标识符不区分大小写;标准规定它们应该区分大小写。
- 在HAVING子句中包含的子查询中,应该能够引用该HAVING子句中“可用”的聚合。这不受支持。
拓展
- InterSystems SQL支持许多有用的扩展。其中许多都与InterSystems IRIS提供对数据的同步对象和关系访问这一事实有关。
其中一些扩展包括:
- 支持用户可定义的数据类型和函数。
- 以下对象引用的特殊语法。
- 支持子类化和继承。
- 支持对存储在其他数据库中的外部表进行查询。
- 用于控制表的存储结构以实现最高性能的多种机制。
互操作性
- InterSystems SQL支持多种与其他应用程序和软件工具互操作的方法。
JDBC
InterSystems IRIS包括一个符合标准的第4级JDBC客户机(全部是纯Java代码)。
InterSystems JDBC驱动程序提供以下特性:
- 高性能
- 纯JAVA代码实现
- UNICODE支持
- 线程安全
可以将InterSystems JDBC与任何支持JDBC的工具、应用程序或开发环境一起使用。
ODBC
InterSystems SQL的c语言调用级接口是ODBC。与其他数据库产品不同,InterSystems ODBC驱动程序是一个本机驱动程序——它不是构建在任何其他专有接口之上的。
InterSystems ODBC驱动程序提供以下功能:
- 高性能
- 可移植性
- 原生Unicode支持
- 线程安全
可以将InterSystems ODBC与支持ODBC的任何工具,应用程序或开发环境一起使用。
嵌入式SQL
在ObjectScript中,InterSystems SQL支持嵌入式SQL: 将SQL语句放置在方法(或其他代码)主体中的能力。使用嵌入式SQL,可以查询单个记录,或定义一个游标,然后使用该游标查询多个记录。嵌入式SQL已编译。默认情况下,它是在第一次执行(运行时)时进行编译的,而不是在包含它的例程进行编译时进行的。因此,在运行时检查SQLCODE错误很重要。 还可以与包含嵌入式SQL的ObjectScript例程同时编译嵌入式SQL。
与InterSystems IRIS的对象访问功能结合使用时,嵌入式SQL的功能非常强大。例如,以下方法查找具有给定Name值的记录的RowID:
/// w ##class(PHA.TEST.SQL).FindByName("姚鑫")
ClassMethod FindByName(fullname As %String)
{
&sql(SELECT %ID INTO :id FROM Sample.Person WHERE Name = :fullname)
IF SQLCODE < 0 {
SET baderr="SQLCODE ERROR:"_SQLCODE_" "_%msg
RETURN baderr
} ELSEIF SQLCODE = 100 {
SET nodata="Query returns no data"
RETURN nodata
}
RETURN "RowID="_id
}
DHC-APP>w ##class(PHA.TEST.SQL).FindByName("姚鑫")
RowID=6
注意: 如果 Name 查处多条的话 id为查询的第一条数据
指定倒序,为最后一条。
&sql(SELECT %ID INTO :id FROM Sample.Person WHERE Name = :fullname order by ID desc)
DHC-APP>w ##class(PHA.TEST.SQL).FindByName("姚鑫")
RowID=14
动态SQL
作为其标准库的一部分,InterSystems IRIS提供了一个%SQL.Statement类,可以使用它来执行动态(即在运行时定义的)SQL语句。可以在ObjectScript方法中使用动态SQL。例如,下面的方法查询指定数量的21世纪出生的人。该查询选择1999年12月31日之后出生的所有人,按出生日期对所选记录进行排序,然后选择前x条记录:
/// w ##class(PHA.TEST.SQL).Born21stC("姚鑫")
ClassMethod Born21stC(x)
{
/// w ##class(PHA.TEST.SQL).Born21stC("1")
ClassMethod Born21stC(x)
{
SET myquery=2
SET myquery(1) = "SELECT TOP ? Name,%EXTERNAL(DOB) FROM Sample.Person "
SET myquery(2) = "WHERE DOB > 58073 ORDER BY DOB"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(.myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rset = tStatement.%Execute(x)
DO rset.%Display()
WRITE !,"End of data"
q ""
}
DHC-APP>w ##class(PHA.TEST.SQL).Born21stC("2")
Name Expression_2
Ingrahm,Susan N. 02/10/2001
Goldman,Will H. 09/22/2002
2 Rows(s) Affected
End of data
准备查询时,该查询的优化版本将存储为缓存查询。该缓存查询被执行用于查询的后续调用,从而避免了每次执行查询时重新优化查询的开销。
限制
请注意InterSystems SQL的以下限制:
NLS可用于为单个全局变量以及当前运行的进程中的局部变量指定特定国家区域设置行为的$ORDER行为。InterSystems SQL可以在任何国家语言环境中使用和良好地工作。然而,InterSystems SQL当前的一个限制是,对于任何特定进程,它引用的所有相关全局变量都必须使用与当前进程区域设置相同的国家区域设置。