SQL Server:在Service Broker中使用Schema Collection验证消息

这是我编写的一个手册中的一部分

    --第一步:创建一个XML架构集合
        --假设我们希望的XML数据格式如下(将它保存为OrderRequest.xml
        /*
        
        <?xml version="1.0"?>
            <OrderRequest OrderId="10248" CustomerID="ABCDEF" OrderDate="2010-1-25">
                <OrderItems>
                    <Item ProductId="1" UnitPrice="20.5" Quantity="6" />
                    <Item ProductId="2" UnitPrice="30" Quantity="6.8" />
                </OrderItems>

            </OrderRequest>
        */
    
        --使用xsd工具生成架构 >xsd OrderRequst.xml
        
        
        --创建架构集合
        CREATE XML SCHEMA COLLECTION OrderRequestSchema AS
        N'<?xml version="1.0"?>
        <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
          <xs:element name="OrderRequest">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="OrderItems" minOccurs="1">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="Item" minOccurs="1" maxOccurs="unbounded">
                        <xs:complexType>
                          <xs:attribute name="ProductId" type="xs:string" />
                          <xs:attribute name="UnitPrice" type="xs:string" />
                          <xs:attribute name="Quantity" type="xs:string" />
                        </xs:complexType>
                      </xs:element>
                    </xs:sequence>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
              <xs:attribute name="OrderId" type="xs:string" />
              <xs:attribute name="CustomerID" type="xs:string" />
              <xs:attribute name="OrderDate" type="xs:string" />
            </xs:complexType>
          </xs:element>
          <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
            <xs:complexType>
              <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="OrderRequest" />
              </xs:choice>
            </xs:complexType>
          </xs:element>
        </xs:schema>';


        --这个Schema中我们定义了数据类型,并且我们规定item必须至少出现一次,也就是说一个订单必须至少有一个明细
        
    
    --第二步:创建一个消息类型,使用该架构集合进行验证
      CREATE MESSAGE TYPE
    [//Adventure-Works.com/OrderRequest]
    VALIDATION = VALID_XML WITH SCHEMA COLLECTION OrderRequestSchema ;
    

    --第三步:创建合约
    CREATE CONTRACT [//AWDB/1DBSample/OrderContract]
      ([//Adventure-Works.com/OrderRequest]
       SENT BY INITIATOR
      );
    GO
    
    
    --第四步:创建队列和服务
    CREATE QUEUE InitOrderQueue
    CREATE QUEUE TargetOrderQueue
    
    CREATE SERVICE InitOrderService
    ON QUEUE InitOrderQueue([//AWDB/1DBSample/OrderContract])
    CREATE SERVICE TargetOrderService
    ON QUEUE TargetOrderQueue([//AWDB/1DBSample/OrderContract])
    --第五步:测试消息传输
    
    DECLARE @InitDlgHandle UNIQUEIDENTIFIER;--这是会话的句柄
    DECLARE @RequestMsg NVARCHAR(100);

    BEGIN TRANSACTION;
        BEGIN DIALOG @InitDlgHandle--BEGIN DIALOG语句会开始一个会话,并将会话的句柄赋予之前的变量
             FROM SERVICE
              InitOrderService  --FROM SERVICE是不要单引号的,直接引用对象。(为什么这样做?)
             TO SERVICE
              N'TargetOrderService' -- TO SERVICE则需要单引号
             ON CONTRACT
              [//AWDB/1DBSample/OrderContract]
             WITH
                 ENCRYPTION = OFF; --不做加密

        SELECT @RequestMsg =
               N'<RequestMsg>Message for Target service.</RequestMsg>'; --这里用SET语句应该也是一样的吧

        /*SEND ON CONVERSATION @InitDlgHandle
             MESSAGE TYPE 
             [//AWDB/1DBSample/RequestMessage]
             (@RequestMsg);
        */     
             --如果这里不改,那么会报告一个错误,因为服务不接受这种消息
             /*
消息 8431,级别 16,状态 1,第 18 行
消息类型 '//AWDB/1DBSample/RequestMessage' 不是服务约定的一部分。
             
             */
             
        SEND ON CONVERSATION @InitDlgHandle
            MESSAGE TYPE
            [//Adventure-Works.com/OrderRequest](@RequestMsg)

        SELECT @RequestMsg AS SentRequestMsg;  --显示一下发送出去的消息
        --请注意,我们的消息是不满足架构的,但这个代码执行是没有问题的
        

    COMMIT TRANSACTION;
    GO
    

    
    
    SELECT * FROM InitOrderQueue
    SELECT * FROM TargetOrderQueue
    --通过查看两个队列中的消息,我们发现目标队列中并没有消息,而来源队列中则有一个类型为http://schemas.microsoft.com/SQL/ServiceBroker/Error的消息,什么意思呢?就是说发送失败了.
    
    --下面我们来读取这个消息看看什么内容
    DECLARE @Msg NVARCHAR(1000);
    RECEIVE @Msg=message_body FROM InitOrderQueue;
    SELECT @Msg;
    
    --错误消息是下面这样的,意思就是说验证无法通过。
--<?xml version="1.0"?>
--    <Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error">
--        <Code>-9615</Code>
--        <Description>A message of type &apos;//Adventure-Works.com/OrderRequest&apos; failed XML validation on the target service.  XML Validation: Declaration not found for element &apos;RequestMsg&apos;. Location: /*:RequestMsg[1] This occurred in the message with Conversation ID &apos;2CEEFDE9-3E21-416E-B8FB-E731CF8FDA4C&apos;, Initiator: 1, and Message sequence number: 0.
--        </Description>
--    </Error>
posted @ 2010-01-26 14:47  陈希章  阅读(681)  评论(0编辑  收藏  举报