CREATE QUEUE (Transact-SQL)
在数据库中创建一个新队列。队列可以存储消息。当一条针对某项服务的消息到达时,Service Broker 会将该消息放入与该服务关联的队列中。
语法
CREATE QUEUE <object>
[ WITH
[ STATUS = { ON | OFF } [ , ] ]
[ RETENTION = { ON | OFF } [ , ] ]
[ ACTIVATION (
[ STATUS = { ON | OFF } , ]
PROCEDURE_NAME = <procedure> ,
MAX_QUEUE_READERS = max_readers ,
EXECUTE AS { SELF | 'user_name' | OWNER }
) [ , ] ]
[ POISON_MESSAGE_HANDLING (
[ STATUS = { ON | OFF } )
]
[ ON { filegroup | [ DEFAULT ] } ]
[ ; ]
<object> ::=
{
[ database_name. [ schema_name ] . | schema_name. ]
queue_name
}
<procedure> ::=
{
[ database_name. [ schema_name ] . | schema_name. ]
stored_procedure_name
}
参数
database_name(对象)
要在其中创建新队列的数据库的名称。database_name 必须指定现有数据库的名称。如果未提供 database_name,将在当前数据库中创建队列。schema_name(对象)
新队列所属架构的名称。默认情况下,该架构为执行该语句的用户的默认架构。如果 CREATE QUEUE 语句由 sysadmin 固定服务器角色成员或者 database_name 指定的数据库中的 db_dbowner 或 db_ddladmin 固定数据库角色成员执行,则 schema_name 可以指定与当前连接的登录名关联的架构以外的架构。否则,schema_name 必须是执行该语句的用户的默认架构。queue_name
要创建的队列的名称。此名称必须符合有关 SQL Server 标识符指南。STATUS(队列)
指定队列是可用 (ON) 还是不可用 (OFF)。如果队列不可用,则不能向队列添加消息或从队列中删除消息。可以以不可用状态创建队列,从而在使用 ALTER QUEUE 语句将该队列更改为可用之前,使消息无法到达该队列。如果省略此子句,则默认值为 ON,该队列可用。RETENTION
指定队列的保持期设置。如果 RETENTION = ON,则使用此队列的会话发送或接收的所有消息都将保持在队列中,直到会话结束为止。这样就可以保留消息以便审核,或者用于在出现错误时执行补偿事务。如果未指定此子句,则默认的保留设置为 OFF。注意 设置 RETENTION = ON 会降低性能。应仅在应用程序需要时才使用此设置。有关详细信息,请参阅消息保持。
ACTIVATION
指定与为了处理此队列中的消息而必须启动的存储过程有关的信息。STATUS(激活)
指定 Service Broker 是否启动存储过程。当 STATUS = ON 时,如果当前运行的过程数小于 MAX_QUEUE_READERS,并且消息抵达队列的速度比存储过程接收消息的速度快,则队列启动用 PROCEDURE_NAME 指定的存储过程。当 STATUS = OFF 时,队列不启动存储过程。如果未指定该子句,则默认为 ON。PROCEDURE_NAME = <过程>
指定处理此队列中的消息时要启动的存储过程的名称。此值必须是一个 SQL Server 标识符。有关详细信息,请参阅了解发生激活的条件。database_name(过程)
包含存储过程的数据库的名称。schema_name(过程)
包含存储过程的架构的名称。procedure_name
存储过程的名称。MAX_QUEUE_READERS = max_readers
指定队列同时启动的激活存储过程的最大实例数。max_readers 的值必须是 0 到 32767 之间的数字。EXECUTE AS
指定用于运行激活存储过程的 SQL Server 数据库用户帐户。SQL Server 必须能够在队列启动存储过程时检查此用户的权限。对于域用户,在启动过程时服务器必须与域连接,否则激活将失败。对于 SQL Server 用户,服务器始终可检查权限。SELF
指定存储过程以当前用户身份执行。(执行该 CREATE QUEUE 语句的数据库主体。)'user_name'
执行存储过程时所用的用户名。user_name 参数必须是指定为 SQL Server 标识符的有效 SQL Server 用户。当前用户必须对指定的 user_name 具有 IMPERSONATE 权限。OWNER
指定存储过程以队列的所有者身份执行。POISON_MESSAGE_HANDLING
指定是否对队列启用有害消息处理。默认值为 ON。将有害消息处理设置为 OFF 的队列在五个连续的事务回滚之后不会被禁用。这样,应用程序就可以定义自定义的有害消息处理系统。
ON filegroup | [ DEFAULT ]
指定从中创建此队列的 SQL Server 文件组。可使用 filegroup 参数标识文件组,也可使用 DEFAULT 标识符以使用 Service Broker 数据库的默认文件组。在此子句的上下文中,DEFAULT 不是关键字,必须作为标识符进行分隔。如果未指定文件组,该队列使用数据库的默认文件组。
注释
队列可以是 SELECT 语句的目标。但是,只能使用在 Service Broker 会话中运行的语句(如 SEND、RECEIVE 和 END CONVERSATION)来修改队列的内容。队列不能是 INSERT、UPDATE、DELETE 或 TRUNCATE 语句的目标。
队列可能不是临时对象。因此,以 # 开头的队列名称无效。
通过以不可用状态创建队列,可以先准备好服务的基础结构,然后再允许在队列中接收消息。
如果队列中没有消息,则 Service Broker 不会停止激活存储过程。如果队列中在短时间内没有可用消息,应退出激活存储过程。
在 Service Broker 启动存储过程时将检查激活存储过程的权限,而不是在创建队列时检查。CREATE QUEUE 语句不验证 EXECUTE AS 子句中指定的用户是否有权限执行 PROCEDURE NAME 子句中指定的存储过程。
队列不可用时,Service Broker 将在数据库的传输队列中保存使用该队列的服务的消息。sys.transmission_queue 目录视图提供传输队列的视图。
队列是一种属于架构的对象。队列显示在 sys.objects 目录视图中。
下表列出了队列中的列:
列名 |
数据类型 |
说明 |
---|---|---|
status |
tinyint |
消息的状态。RECEIVE 语句将返回状态为 1 的所有消息。如果启用了消息保持,则将状态设置为 0。如果禁用了消息保持,则将消息从队列中删除。队列中的消息可以包含下列值之一: 0=保留收到的消息 1=准备接收 2=尚未完成 3=已保留发送消息 |
priority |
tinyint |
为此消息指定的优先级。 |
queuing_order |
bigint |
消息在队列中的序号。 |
conversation_group_id |
uniqueidentifier |
此消息所属会话组的标识符。 |
conversation_handle |
uniqueidentifier |
此消息所属会话的句柄。 |
message_sequence_number |
bigint |
消息在会话中的序列号。 |
service_name |
nvarchar(512) |
要进行会话的服务的名称。 |
service_id |
int |
要进行会话的服务的 SQL Server 对象标识符。 |
service_contract_name |
nvarchar(256) |
会话遵循的约定的名称。 |
service_contract_id |
int |
会话遵循的约定的 SQL Server 对象标识符。 |
message_type_name |
nvarchar(256) |
对消息进行说明的消息类型的名称。 |
message_type_id |
int |
对消息进行说明的消息类型的 SQL Server 对象标识符。 |
validation |
nchar(2) |
对消息所用的验证。 E = 空 N = 无 X = XML |
message_body |
varbinary(MAX) |
消息的内容。 |
message_id |
uniqueidentifier |
消息的唯一标识符。 |
权限
db_ddladmin 或 db_owner 固定数据库角色和 sysadmin 固定服务器角色的成员拥有创建队列的权限。
默认情况下,队列所有者、db_ddladmin 或 db_owner 固定数据库角色的成员以及 sysadmin 固定服务器角色的成员拥有队列的 REFERENCES 权限。
默认情况下,队列所有者、db_owner 固定数据库角色的成员以及 sysadmin 固定服务器角色的成员具有队列的 RECEIVE 权限。
示例
A. 不使用参数创建队列
下面的示例创建一个可用于接收消息的队列。没有为该队列指定激活存储过程。
CREATE QUEUE ExpenseQueue ;
B. 创建不可用队列
以下示例创建了一个不可用于接收消息的队列。没有为该队列指定激活存储过程。
CREATE QUEUE ExpenseQueue WITH STATUS=OFF ;
C. 创建队列并指定内部激活信息
下面的示例创建一个可用于接收消息的队列。消息进入队列时,队列将启动存储过程 expense_procedure。该存储过程以用户 ExpenseUser 的身份执行。该队列最多启动存储过程的 5 个实例。
CREATE QUEUE ExpenseQueue
WITH STATUS=ON,
ACTIVATION (
PROCEDURE_NAME = expense_procedure,
MAX_QUEUE_READERS = 5,
EXECUTE AS 'ExpenseUser' ) ;
D. 在特定文件组中创建一个队列
以下示例将在文件组 ExpenseWorkFileGroup 中创建一个队列。
CREATE QUEUE ExpenseQueue
ON ExpenseWorkFileGroup ;
E. 创建具有多个参数的队列
以下示例在 DEFAULT 文件组中创建一个队列。该队列不可用。消息被保留在队列中,直到消息所属的会话结束。通过 ALTER QUEUE 启用队列后,该队列将启动存储过程 2008R2.dbo.expense_procedure 来处理消息。此存储过程以运行 CREATE QUEUE 语句的用户的身份执行。该队列最多启动存储过程的 10 个实例。
CREATE QUEUE ExpenseQueue
WITH STATUS = OFF,
RETENTION = ON,
ACTIVATION (
PROCEDURE_NAME = AdventureWorks2008R2.dbo.expense_procedure,
MAX_QUEUE_READERS = 10,
EXECUTE AS SELF )
ON [DEFAULT] ;