CREATE QUEUE (Transact-SQL)
适用于: SQL Server Azure 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.queue_name | schema_name.queue_name | queue_name }
<procedure> ::=
{ database_name.schema_name.stored_procedure_name | schema_name.stored_procedure_name | stored_procedure_name }
参数
Database_name(对象)
要在其中创建新队列的数据库的名称。 database_name 须指定现有数据库的名称。 如果未提供 database_name,将在当前数据库中创建队列。
schema_name(对象)
新队列所属架构的名称。 默认情况下,该架构为执行该语句的用户的默认架构。 如果由 sysadmin 固定服务器角色成员或者 database_name 指定的数据库中的 db_dbowner 或 db_ddladmin 固定数据库角色成员执行 CREATE QUEUE 语句,则 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 = <procedure>
指定处理此队列中的消息时要启动的存储过程的名称。 此值必须是一个 SQL Server 标识符。
database_name(procedure) 包含存储过程的数据库的名称。
schema_name(procedure) 包含存储过程的架构的名称。
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 文件组 | [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(128) | 要进行会话的服务的名称。 |
service_id |
int | 要进行会话的服务的 SQL Server 对象标识符。 |
service_contract_name |
nvarchar(128) | 会话遵循的约定的名称。 |
service_contract_id |
int | 会话遵循的约定的 SQL Server 对象标识符。 |
message_type_name |
nvarchar(128) | 对消息进行说明的消息类型的名称。 |
message_type_id |
int | 对消息进行说明的消息类型的 SQL Server 对象标识符。 |
validation |
nchar(2) | 对消息所用的验证。E =EmptyN =NoneX =XML |
message_body |
varbinary(max) | 消息的内容。 |
message_enqueue_time |
datetime | 消息进行排队的时间。 |
权限
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
启用队列后,该队列将启动存储过程 AdventureWorks2022.dbo.expense_procedure
来处理消息。 此存储过程以运行 CREATE QUEUE
语句的用户的身份执行。 该队列最多启动存储过程的 10
个实例。
CREATE QUEUE ExpenseQueue
WITH STATUS = OFF
, RETENTION = ON
, ACTIVATION (
PROCEDURE_NAME = AdventureWorks2022.dbo.expense_procedure
, MAX_QUEUE_READERS = 10
, EXECUTE AS SELF )
ON [DEFAULT];