SQL Server 2014 中的本机编译表

  • Jonathan Allen
  • 孙镜涛

2013 年 9 月 29 日

话题:架构

到目前为止,所有版本的 SQL Server 都会将 T-SQL 编写的存储过程编译成中间语言的形式,然后再进行解释。在 SQL Server 2014 中,我们现在拥有了一个将存储过程一直向下编译成机器码然后再使用的选项。

类型

功能

决议

功能

表值参数

本机编译的存储过程的参数不能使用表类型。使用标量数据类型替代。

功能

内联表变量

声明变量时表类型不能被声明为内联的。必须使用 CREATE TYPE 声明显式地声明表类型。

功能

游标

在本机编译的存储过程上或者其内部并不支持游标。

·从客户端执行存储过程的时候需要使用 RPC 而不是游标 API。在 ODBC 中要避免使用 Transact-SQL 语句 EXECUTE,相反的要直接指定存储过程的名字。

·从一个 Transact-SQL 批处理命令或者从另外的存储过程中执行存储过程的时候,要避免在本机编译的存储过程中使用游标。

·创建一个本机编译的存储过程的时候,要使用基于集合的逻辑或者使用 WHILE 循环,不要使用游标。

功能

非常量参数默认值

在本机编译的存储过程上使用参数默认值的时候,值必须是常量。从参数声明中移除所有的通配符。

功能

 

本机编译的存储过程不能有编号。从 CREATE PROCEDURE 语句中移除 ; 编号。

功能

多行表值构造器

在一个本机编译的存储过程中不能使用同样的 INSERT 语句插入多行。要为每一行创建一个 INSERT 语句。

功能

WITH 子句

本机编译的存储过程并不支持通用表表达式(CTE)。需要重写查询。

功能

递归查询

不支持递归查询。从本机编译的存储过程中移除这种查询。

功能

子查询

不支持子查询。需要重写查询。

功能

COMPUTE

不支持 COMPUTE 子句。从查询中移除这种子句。

功能

SELECT INTO

不支持带 INTO 子句的 SELECT 语句。按照 INSERT INTO Table SELECT 的形式重写查询。

功能

OUTPUT

不支持 OUTPUT 子句。将它从查询中移除。

功能

不完全插入列列表

在 INSERT 语句中,必须为表中的所有列指定值。

函数

函数(Function)

本机编译的存储过程并不支持内置的函数。从存储过程中移除这些函数。

功能

CASE

本机编译的存储过程里面的查询并不支持 CASE 语句。为每一种情况创建一个查询。

功能

用户定义的函数

用户定义的函数不能在本机编译的存储过程中使用。从存储过程定义中移除对这种函数的引用。

功能

用户定义的聚合函数

用户定义的聚合函数不能在本机编译的存储过程中使用。从存储过程中移除对这种函数的引用。

功能

浏览模式元数据

本机编译的存储过程并不支持浏览模式元数据。确保将会话选项 NO_BROWSETABLE 设置为 OFF。

功能

DELETE 中的 FROM 子句

在本机编译的存储过程中 DELETE 语句并不支持 FROM 子句。

功能

UPDATE 中的 FROM 子句

在本机编译的存储过程中 UPDATE 语句并不支持 FROM 子句。

功能

临时过程

临时的存储过程并不能被本机编译。或者创建一个永久的本机编译的存储过程,或者创建一个临时解释的 Transact-SQL 存储过程。

隔离级别

READ UNCOMMITTED

本机编译的存储过程并不支持隔离级别 READ UNCOMMITTED。使用它所支持的隔离级别,例如 SNAPSHOT。

隔离级别

READ COMMITTED

本机编译的存储过程并不支持隔离级别 READ UNCOMMITTED。使用它所支持的隔离级别,例如 SNAPSHOT。

功能

临时表

不能在本机编译的存储过程中使用 tempdb 中的表。可以使用一个表变量或者使用一个 DURABILITY=SCHEMA_ONLY 的内存优化表。

功能

多种活动结果集(MARS)

本机编译的存储过程并不支持多种活动结果集(MARS)。这个错误还能表明链接服务器的使用。链接服务器可以使用 MARS。但是本机编译的存储过程并不支持链接服务器。你需要直接连接到本机编译的存储过程所寄宿的服务器和数据库。

功能

DTC

不能在分布式事务中访问内存优化表和本机编译的存储过程。使用 SQL 事务替代。

功能

non-bin2 排序规则

在本机编译的存储过程中,对字符型字符串的比较、排序以及其他操作必须使用 BIN2 排序规则。使用 COLLATE 子句或者使用带有恰当排序规则的列和变量。可以查看排序规则和代码页面获取更多信息。

功能

UTF-16 数据的截断

带有 _SC 排序规则的字符型字符串使用 UTF-16 编码。将一个 n(var)char 值转换成一个长度更短的 n(var)char 值涉及到截断。在本机编译的存储过程中 UTF-16 值并不支持这些功能。避免截断 UTF-16 编码的字符串。

功能

EXECUTE WITH RECOMPILE

本机编译的存储过程并不支持 WITH RECOMPILE 选项。

功能

从专有的管理连接中执行

本机编译的存储过程不能从专有的管理连接(DAC)中执行。使用一个常规的连接。

操作

ALTER PROCEDURE

本机编译的存储过程不能被改变。如果想要改变过程定义,丢弃(drop)并重新创建存储过程。

操作

保存点

不能在拥有一个活动保存点的事务中调用本机编译的存储过程。从事务中移除保存点。

操作

ALTER AUTHORIZATION

不能改变已有内存优化表和本机编译的存储过程的拥有者。如果想要改变所有关系那么需要丢弃并重新创建表或者存储过程。

操作符

OPENROWSET

不支持该操作符。从本机编译的存储过程中移除 OPENROWSET。

操作符

OPENQUERY

不支持该操作符。从本机编译的存储过程中移除 OPENQUERY。

操作符

OPENDATASOURCE

不支持该操作符。从本机编译的存储过程中移除 OPENDATASOURCE。

操作符

OPENXML

不支持该操作符。从本机编译的存储过程中移除 OPENXML。

操作符

CONTAINSTABLE

不支持该操作符。从本机编译的存储过程中移除 CONTAINSTABLE。

操作符

FREETEXTTABLE

不支持该操作符。从本机编译的存储过程中移除 FREETEXTTABLE。

功能

表值函数

不能在本机编译的存储过程中引用表值函数。使用引用表替代。

操作符

CHANGETABLE

不支持该操作符。从本机编译的存储过程中移除 CHANGETABLE。

操作符

GOTO

不支持该操作符。使用其他的过程式结构,例如 WHILE。

操作符

EXECUTE, INSERT EXEC

不支持嵌套的本机编译的存储过程。必须的操作可以被指定为内联的,作为存储过程定义的一部分。

操作符

OFFSET

不支持该操作符。从本机编译的存储过程中移除 OFFSET。

操作符

UNION

不支持该操作符。从本机编译的存储过程中移除 UNION。可以使用一个表变量将一些结果集连接到一个单独的结果集中。

操作符

INTERSECT

不支持该操作符。从本机编译的存储过程中移除 INTERSECT。 在某些情况下可以使用一个 INNER JOIN 获取同样的结果。

操作符

EXCEPT

不支持该操作符。从本机编译的存储过程中移除 EXCEPT。

操作符

OUTER JOIN

不支持该操作符。从本机编译的存储过程中移除 OUTER JOIN。

操作符

APPLY

不支持该操作符。从本机编译的存储过程中移除 APPLY。

操作符

PIVOT

不支持该操作符。从本机编译的存储过程中移除 PIVOT。

操作符

UNPIVOT

不支持该操作符。从本机编译的存储过程中移除 UNPIVOT。

操作符

OR, IN

本机编译的存储过程中的查询并不支持析取(OR、IN)。为每一种情况创建单独的查询。

操作符

CONTAINS

不支持该操作符。从本机编译的存储过程中移除 CONTAINS。

操作符

FREETEXT

不支持该操作符。从本机编译的存储过程中移除 FREETEXT。

操作符

NOT

不支持该操作符。从本机编译的存储过程中移除 NOT。在某些情况下,可以使用不等式替代 NOT。例如,NOT a=b 可以被替换为 a!=b。

操作符

TSEQUAL

不支持该操作符。从本机编译的存储过程中移除 TSEQUAL。

操作符

LIKE

不支持该操作符。从本机编译的存储过程中移除 LIKE。

操作符

NEXT VALUE FOR

在本机编译的存储过程内部不能引用序列。使用解释型 Transact-SQL 获取值,然后将其传入本机编译的存储过程。查看在内存优化表中实现 IDENTITY获取更多信息。

操作符

~, &, |, ^ (按位操作符)

不支持按位操作符。从本机编译的存储过程中移除它们。

操作符

% (modulo)

不支持模块操作符。从本机编译的存储过程中移除 %。

设置选项

选项

在本机编译的存储过程里面不能改变 SET 选项。可以使用 BEGIN ATOMIC 语句设置某些选项。可以查看本机编译的存储过程中的原子块章节。

操作数

TABLESAMPLE

不支持该操作数。从本机编译的存储过程中移除 TABLESAMPLE。

选项

RECOMPILE

本机编译的存储过程在创建的时候编译。如果想要重新编译一个本机编译的存储过程,需要丢弃并重新创建它。从过程定义中移除 RECOMPILE。

选项

ENCRYPTION

不支持该选项。从过程定义中移除 ENCRYPTION。

选项

FOR REPLICATION

本机编译的存储过程不能被重复创建。从过程定义中移除 FOR REPLICATION。

选项

FOR XML

不支持该选项。从本机编译的存储过程中移除 FOR XML。

选项

FOR BROWSE

不支持该选项。从本机编译的存储过程中移除 FOR BROWSE。

连接提示

HASH, MERGE

本机编译的存储过程仅支持嵌套循环的连接。并不支持哈希和合并连接。移除连接提示。

查询提示

Query 提示

在本机编译的存储过程内部并没有这个查询提示。查看查询提示(Transact-SQL)说明了解支持的查询提示。

选项

DISTINCT

不支持该选项。从本机编译的存储过程中的查询中移除 DISTINCT。

选项

PERCENT

TOP 子句并不支持该选项。从本机编译的存储过程中的查询中移除 PERCENT。

选项

WITH TIES

TOP 子句并不支持该选项。从本机编译的存储过程中的查询中移除 WITH TIES。

聚合函数

聚合函数(Aggregate function)

不支持这些子句。想要获取与本机编译的存储过程中的聚合函数相关的更多信息,可以查看本机编译的存储过程指南。

排名函数

排名函数(Ranking function)

本机编译的存储过程并不支持排名函数。将它们从过程定义中移除。

函数

函数(Function)

不支持该函数。从本机编译的存储过程中移除它。

语句

语句(Statement)

不支持该语句。从本机编译的存储过程中移除它。

功能

深类型的 MIN/MAX

在本机编译的存储过程内不能将聚合函数 MIN 和 MAX 用于字符和二进制字符串值。

功能

没有聚合函数的 GROUP BY

在本机编译的存储过程中,如果一个查询有一个 GROUP BY 子句,那么该查询也必须使用一个聚合函数。向查询中添加一个聚合函数。

功能

不在 GROUP BY 列表中的 ORDER BY 表达式

对于既包含 GROUP BY 又包含 ORDER BY 子句的查询,ORDER BY 列表中的每一个条目也必须出现在 GROUP BY 列表中。

功能

ROLLUP

在本机编译的存储过程中 ROLLUP 不能和 GROUP BY 子句一起使用。从过程定义中移除 ROLLUP。

功能

CUBE

在本机编译的存储过程中 CUBE 不能和 GROUP BY 子句一起使用。从过程定义中移除 CUBE。

功能

GROUPING SETS

在本机编译的存储过程中 GROUPING SETS 不能和 GROUP BY 子句一起使用。从过程定义中移除 GROUPING SETS。

在大多数内存数据库关注无模式设计的时候,Microsoft 则是走了另一条路子。本机编译的存储过程必须要使用“SCHEMABINDING”选项。这个选项将它们锁定到它们关联的表。如果没有丢弃引用表的所有存储过程,那么这些过程引用的任何表都不能被丢弃。

最初,这个报告被题为“本机编译的查询”,但是这不能公正地表达出它运行的深入程度。在创建一个内存优化表的时候,SQL Server 将会明确地为该表逐字地创建一个 DLL。这个 DLL 包含了为了修改表中的数据而编写的机器码。甚至索引也会被编译成这种 DLL,所以修改一个索引意味着重新构建表。

文档上有一些不明确的内容,但是好像 DLL 也是为存储过程创建的。这可能解释了本机编译的存储过程为什么不能被改变的原因。作为替代你必须丢弃旧的过程,然后创建它的替代品。

架构