MSSQL之二十四 实现服务器代理

举报
tea_year 发表于 2021/12/30 01:09:14 2021/12/30
【摘要】 /*AdventureWorks.Inc的管理层想知道在一年的任何点的确切的年销售表以帮助它们计划未来的策略。集合年销售数据是在SalesDB数据库的SalesDetails表中维护的.SalesOrderHeader:包含常规或父级销售订单信息;与销售订单关联的特定产品存储在 SalesOrderDetail 表中。SalesOrde...

  
  1. /*
  2. AdventureWorks.Inc的管理层想知道在一年的任何点的确切的年销售表以帮助它们计划未来的策略。
  3. 集合年销售数据是在SalesDB数据库的SalesDetails表中维护的.
  4. SalesOrderHeader:包含常规或父级销售订单信息;与销售订单关联的特定产品存储在 SalesOrderDetail 表中。
  5. SalesOrderDetail:包含与特定销售订单关联的各个产品。一个销售订单可以订购多个产品。每个销售订单的常规
  6. 或父级信息存储在 SalesOrderHeader 中。每个订购的产品或子级信息存储在 SalesOrderDetail 中。
  7. 销售详情被存储在AdventureWorks数据库的SalesOrderHeader和SalesOrderDetail表中.为了保持
  8. 年销售数据更新,你需要确保无论何时任何订单被处理和在AdventureWorks数据库中交货日期被更新的
  9. 时候,订单的总钱数,存储在SalesOrderHeader表的SubTotal列中,应该被添加到SalesDB数据库的总年销售中.
  10. */
  11. --SalesDB数据库应该在服务器上,这个数据库被用于产生报告.
  12. /*
  13. 解决方案:需要在服务器上实现服务代理.为了实现服务代理,你需要完成如下任务:
  14. 1.创建一个服务程序。
  15. 2.创建消息类型、协议、队列和服务对象
  16. 3.在表上创建触发器
  17. 4.验证功能
  18. */
  19. --select count(*) from Sales.SalesOrderHeader 31465行
  20. --Select count(*) from Sales.SalesOrderDetail 121317行
  21. --1.创建SalesDB
  22. CREATE DATABASE SalesDB;
  23. GO
  24. drop database SalesDB
  25. USE SalesDB
  26. go
  27. CREATE TABLE SalesDetails--年销售详情表
  28. (
  29. Year varchar(4),--年
  30. TotalSales money--年销售额
  31. )
  32. INSERT INTO SalesDetails VALUES ('2006',25000)--插入数据
  33. use SalesDB
  34. go
  35. --建立Robert的登录名,使用SQL SERVER验证模式
  36. sp_addlogin 'Robert','niit#1234','SalesDB'
  37. CREATE USER Robert FOR LOGIN Robert
  38. --登录名:到SQL SERVER2005服务器
  39. --角色:数据库的职权分类,相当于现实生活中的职位
  40. --用户:针对数据库来说
  41. -- to grant permission
  42. EXEC sp_addrolemember 'db_owner', 'Robert'
  43. -- to give ownership of teh database to the sa
  44. ALTER DATABASE AdventureWorks SET TRUSTWORTHY ON
  45. ALTER DATABASE SalesDB SET TRUSTWORTHY ON
  46. ALTER AUTHORIZATION ON DATABASE::[AdventureWorks] TO [SA];--修改授权,给sa
  47. ALTER AUTHORIZATION ON DATABASE::[SalesDB] TO [SA];
  48. -- to crate master encryption key
  49. USE AdventureWorks--创建数据库主密钥。
  50. CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'niit#1234'
  51. USE SalesDB
  52. CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'niit#1234'
  53. select * FROM SalesDetails
  54. --使服务代理可用
  55. use AdventureWorks
  56. go
  57. alter database AdventureWorks set Enable_Broker--
  58. go
  59. use SalesDB
  60. go
  61. alter database SalesDB set Enable_broker
  62. go
  63. --先让某一个触发器停用,基于SalesOrderHeader表
  64. USE AdventureWorks
  65. GO
  66. DISABLE TRIGGER SalesOrderHeader.uSalesOrderHeader ON
  67. Sales.SalesOrderHeader
  68. --创建存储过程,以实现自动化的服务代理
  69. USE SalesDB
  70. GO
  71. CREATE PROCEDURE OnReceiveMessage--OnReceiveMessage存储过程
  72. AS
  73. declare @message_type int--消息类型变量
  74. declare @dialog uniqueidentifier,--会话变量
  75. @ErrorSave INT,--错误点保存变量
  76. @ErrorDesc NVARCHAR(100),--错误描述变量
  77. @message_body int;--消息主体变量
  78. while (1 = 1)
  79. begin
  80. begin transaction --开始事务.
  81. WAITFOR (--等待到某个时间执行语句
  82. RECEIVE top(1)--从队列中选择第一条语句
  83. @message_type=message_type_id,--说明消息的消息类型的 SQL Server 对象标识符
  84. @message_body=message_body,
  85. @dialog = conversation_handle
  86. FROM SalesQueue
  87. ), TIMEOUT 3000--如果超时时间已到,则 RECEIVE 返回一个空结果集,即0行
  88. if (@@ROWCOUNT = 0)--受上一语句影响的行数
  89. BEGIN
  90. Rollback Transaction
  91. BREAK
  92. END
  93. SET @ErrorSave = @@ERROR ;--执行的上一个 Transact-SQL 语句的错误号
  94. IF (@ErrorSave <> 0)--有错误
  95. BEGIN
  96. ROLLBACK TRANSACTION ;
  97. SET @ErrorDesc = N'An error has occurred.' ;--给错误信息赋值;以字母 N 为前缀标识 Unicode 字符串常量
  98. --在服务器上执行的代码中(例如在存储过程和触发器中)显示的 Unicode 字符串常量必须以大写字母 N
  99. --为前缀。即使所引用的列已定义为 Unicode 类型,也应如此。如果不使用 N 前缀,
  100. --字符串将转换为数据库的默认代码页。这可能导致不识别某些字符。
  101. END CONVERSATION @dialog
  102. WITH ERROR = @ErrorSave DESCRIPTION = @ErrorDesc ; --结束对话
  103. END
  104. ELSE
  105. IF (@message_type <> 2)--部分消息的“状态”列设为 2(禁用)。
  106. BEGIN
  107. UPDATE SalesDetails SET TotalSales = TotalSales + @message_body;
  108. --更新年销售总额表,让年销售总额自动加上消息里面的金额
  109. END
  110. ELSE
  111. BEGIN
  112. END CONVERSATION @dialog--金额会话
  113. END
  114. COMMIT TRANSACTION--提交事务
  115. END
  116. --2.在AdventureWorks库中创建消息类型、协议、队列和服务对象
  117. USE AdventureWorks
  118. GO
  119. CREATE MESSAGE TYPE SendMessage --创建消息类型:发送消息
  120. VALIDATION = NONE--不验证
  121. CREATE MESSAGE TYPE AcknowledgeMessage--创建消息类型:接收消息
  122. VALIDATION = NONE--不验证
  123. --**********************************
  124. CREATE CONTRACT MyContract--创建协议
  125. (SendMessage SENT BY INITIATOR,--初始化服务为:发送消息类型
  126. AcknowledgeMessage SENT BY TARGET)--目标服务为:接收消息类型
  127. --*********************************
  128. CREATE QUEUE AdvQueue;--创建队列
  129. --*********************************
  130. CREATE SERVICE SalesService--创建基于使用MyContact协议的队列消息服务
  131. ON QUEUE AdvQueue (MyContract)--
  132. --3.在SalesDB库中创建消息类型、协议、队列和服务对象******************
  133. --*******************************************************************
  134. USE SalesDB
  135. GO
  136. CREATE MESSAGE TYPE SendMessage
  137. VALIDATION = NONE
  138. CREATE MESSAGE TYPE AcknowledgeMessage
  139. VALIDATION = NONE
  140. CREATE CONTRACT MyContract
  141. (SendMessage SENT BY INITIATOR,
  142. AcknowledgeMessage SENT BY INITIATOR)
  143. --**********************************
  144. CREATE QUEUE SalesQueue--销售队列
  145. WITH STATUS=ON,--状态为打开
  146. ACTIVATION(--指定使用的存储过程
  147. PROCEDURE_NAME = OnReceiveMessage,--OnReceiveMessage为存储过程.
  148. MAX_QUEUE_READERS = 5,--最大队列数为5个
  149. Execute AS SELF) ;--当前用户执行
  150. --*****************************
  151. CREATE SERVICE RecieveService--接收服务
  152. ON QUEUE SalesQueue (MyContract)
  153. --*********************************************************************
  154. --4.在SalesOrderHeader表上创建触发器,实现:当完成任何销售的时候更新SalesDB数据库
  155. USE AdventureWorks
  156. GO
  157. --select * from Sys.sysobjects where name='SendTrigger'
  158. --drop trigger SendTrigger
  159. --sp_helptext SendTrigger
  160. create TRIGGER SendTrigger--创建触发器
  161. ON Sales.SalesOrderHeader FOR UPDATE AS--基于SalesOrderHeader的更新触发器
  162. DECLARE @amt AS int--定义变量
  163. SELECT @amt = SubTotal FROM INSERTED--总数,从插入的临时表中获得
  164. DECLARE @dialog_handle UNIQUEIDENTIFIER ; --定义会话变量
  165. BEGIN DIALOG CONVERSATION @dialog_handle FROM --开始会话,从销售服务到接收服务
  166. SERVICE [SalesService] TO SERVICE 'RecieveService' ON CONTRACT [MyContract] ;
  167. SEND ON CONVERSATION --发送消息,类型为SendMessage,内容为@amt,即更新的总数
  168. @dialog_handle MESSAGE TYPE[SendMessage] (@amt)
  169. select @amt
  170. --5.AdventureWorks表,
  171. USE AdventureWorks
  172. GO
  173. select subtotal from Sales.SalesOrderHeader where SalesOrderId=43692
  174. --6.执行更新操作,来响应触发器
  175. update Sales.SalesOrderHeader
  176. set SubTotal =5000
  177. where SalesOrderID = 43692
  178. --7.查看SalesDB库年度销售表的数据
  179. use SalesDB
  180. go
  181. select * from SalesDetails
  182. select * from sys.transmission_queue


 

 


  
  1. --创建建库 Test1
  2. create database Test1
  3. on
  4. (
  5. name='Test1_data',
  6. filename='c:\pk\Test1_data.mdf',
  7. size=3mb,
  8. filegrowth=15%
  9. )
  10. log on
  11. (
  12. name= 'Test1_log',
  13. filename='c:\pk\Test1_log.ldf',
  14. size=3mb,
  15. filegrowth=15%
  16. )
  17. --创建建库 Test2
  18. create database Test2
  19. on
  20. (
  21. name='Test2_data',
  22. filename='c:\uk\Test2_data.mdf',
  23. size=3mb,
  24. filegrowth=15%
  25. )
  26. log on
  27. (
  28. name= 'Test2_log',
  29. filename='c:\uk\Test2_log.ldf',
  30. size=3mb,
  31. filegrowth=15%
  32. )
  33. --===============================================
  34. use Test1
  35. go
  36. create table userinfo --用户信息表
  37. (
  38. customerid int identity(1,1),
  39. customername char(8) not null,
  40. pid char(18) not null,
  41. telephone char(13) not null,
  42. address varchar(50)
  43. )
  44. go
  45. --==============================================
  46. use Test2
  47. go
  48. create table cardinfo --银行卡信息表
  49. (
  50. cardid char(19) not null,
  51. curtype char(5) not null,
  52. savingtype char(8) not null,
  53. opendate datetime not null,
  54. openmoney money not null,
  55. balance int not null,
  56. pass char(6) not null,
  57. isreportloss bit not null,
  58. customerid int not null
  59. )
  60. go
  61. drop table cardinfo
  62. --==============================================
  63. select * from Test1.dbo.userinfo
  64. select * from Test2.dbo.cardinfo
  65. insert into cardinfo(cardid,curtype,savingtype,opendate,openmoney,balance,pass,isreportloss,customerid)
  66. values('1010 3576 1234 5678','rmb','活期','2000-12-12',1000,1000,'888888',0,1)
  67. insert into userinfo(customername,pid,telephone,address)
  68. values('张三','123456789012345','010-67898978','北京海淀')
  69. delete from userinfo
  70. --==================
  71. --=创建服务程序(存储过程)实现对银行卡信息表进行修改操作===================================
  72. use Test2
  73. go
  74. alter procedure OnReceiveMessage
  75. as
  76. declare @message_type int
  77. declare @dialog uniqueidentifier,
  78. @ErrorSave int,
  79. @ErrorDesc nvarchar(100),
  80. @message_body int;
  81. while(1=1)
  82. begin
  83. begin transaction
  84. waitfor(
  85. receive top(1)
  86. @message_type = message_type_id,
  87. @message_body = message_body,
  88. @dialog = conversation_handle
  89. from SalesQueue
  90. ),timeout 3000
  91. if(@@rowcount = 0)
  92. begin
  93. rollback tran
  94. break
  95. end
  96. set @ErrorSave = @@error;
  97. if(@ErrorSave <> 0)
  98. begin
  99. rollback tran;
  100. set @ErrorDesc = '错误发生,请注意!';
  101. end conversation @dialog
  102. with error = @ErrorSave description = @ErrorDesc;
  103. end
  104. else
  105. if(@message_type <> 2)
  106. begin
  107. update Test2.dbo.cardinfo set balance = balance + @message_body;
  108. end
  109. else
  110. begin
  111. end conversation @dialog
  112. end
  113. commit tran
  114. end
  115. --======================================
  116. use Test1
  117. -- 创建 消息类型
  118. create message type SendMessage
  119. validation = none
  120. create message type AcknowledgeMessage
  121. validation = none
  122. -- 创建 协议
  123. create contract MyContract
  124. (
  125. SendMessage sent by initiator,
  126. AcknowledgeMessage sent by target
  127. )
  128. -- 创建 队列
  129. create queue AdvQueue
  130. -- 创建 服务
  131. create service SalesService
  132. on queue AdvQueue(MyContract)
  133. --======================================
  134. use Test2
  135. -- 创建 消息类型
  136. create message type SendMessage
  137. validation = none
  138. create message type AcknowledgeMessage
  139. validation = none
  140. -- 创建 协议
  141. create contract MyContract
  142. (
  143. SendMessage sent by initiator,
  144. AcknowledgeMessage sent by initiator
  145. )
  146. -- 创建 队列
  147. create queue SalesQueue
  148. with status = on,
  149. activation(
  150. procedure_name = OnReceiveMessage,
  151. max_queue_readers = 5,
  152. execute as self
  153. );
  154. -- 创建 服务
  155. create service RecieveService
  156. on queue SalesQueue(MyContract)
  157. --===================================
  158. use Test1
  159. go
  160. alter trigger SendTrigger
  161. on userinfo
  162. for update
  163. as
  164. declare @amt int
  165. select @amt = customerid from inserted
  166. declare @dialog_handle uniqueidentifier;
  167. begin dialog conversation @dialog_handle from
  168. service [SalesService] to service 'RecieveService'
  169. on contract MyContract;
  170. send on conversation @dialog_handle
  171. message type SendMessage(@amt)
  172. --===============
  173. select * from userinfo
  174. insert into userinfo(customername,pid,telephone,address)
  175. values('张三','123456789012345','010-67898978','北京海淀')
  176. --==================
  177. update userinfo
  178. set pid = '111111111111111'
  179. where customerid = 2
  180. --=========断开Test2数据库===============
  181. exec sp_detach_db 'Test2','true'
  182. -------------查看队列中暂存的数据
  183. select * from sys.transmission_queue
  184. --=========================================================
  185. --恢复数据库Test2
  186. exec sp_attach_db @dbname = N'Test2',
  187. @filename1 = N'C:\uk\Test2_data.mdf',
  188. @filename2 = N'C:\uk\Test2_log.ldf'
  189. --=========================
  190. alter database Test2
  191. set enable_broker
  192. --ENABLE_BROKER。
  193. --此选项可激活 Service Broker 消息传递功能,
  194. --并保留数据库的现有 Service Broker 标识符。
  195. --============================
  196. select * from Test2.dbo.cardinfo
  197. select * from Test1.dbo.userinfo


 

视频课 https://edu.csdn.net/course/play/7940

文章来源: aaaedu.blog.csdn.net,作者:tea_year,版权归原作者所有,如需转载,请联系作者。

原文链接:aaaedu.blog.csdn.net/article/details/52518505

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。