`
xiaoer_1982
  • 浏览: 1812310 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

[学习SQL SERVER 2005系列]关于INSERT、UPDATE 或 DELETE的OUTPUT及OUTPUT...INTO...用法

阅读更多
  1. [学习SQLSERVER2005系列]关于INSERT、UPDATE或DELETE的OUTPUT及OUTPUT...INTO...用法
  2.      作者:Flystone,转载注明出处
  3. 在INSERT、UPDATE、DELETE语句中使用OUTPUT得到语句影响的每行信息,今天我们来学习这个语法。
  4. 1、OUTPUT_CLAUSE定义(语法参Transact-SQL语法约定):
  5. <OUTPUT_CLAUSE>::=
  6. {
  7. [OUTPUT<dml_select_list>INTO{@table_variable|output_table}[(column_list)]]
  8. [OUTPUT<dml_select_list>]
  9. }
  10. <dml_select_list>::=
  11. {<column_name>|scalar_expression}[[AS]column_alias_identifier]
  12. [,...n]
  13. <column_name>::=
  14. {DELETED|INSERTED|from_table_name}.{*|column_name}
  15. 2、OUTPUT_CLAUSE说明:
  16. 返回受INSERT、UPDATE或DELETE语句影响的每行的信息,或者返回基于上述每行的表达式。这些结果可以返回到处理应用程序,以供在确认消息、存档以及其他类似的应用程序要求中使用。此外,也可以将结果插入表或表变量。
  17. 3、典型应用:
  18. 1、根据当前表的数据有条件的生成历史或新的初始化数据;
  19. 2、把INSERT、UPDATE或DELETE语句影响的每行的信息暂存处理或反馈给应用程序完成业务或逻辑的完整性;
  20. 3、OUTPUT子句对于在INSERT或UPDATE操作之后检索标识列或计算列的值可能非常有用;
  21. 4、示列:
  22. 1、根据当前表的数据有条件的生成历史数据;
  23. 记得我以前做零售及水厂应用系统时都会有一个月未数据的处理功能,无非根据当前的数据自动生成下一个月数据的初始值。下面我以一个简化了例子来说明,例子是记录员工每个月工分变化中,我们以12月的数据生成下个月的月初数据。
  24. ------------------------------------
  25. --Author:happyflsytone
  26. --Date:2008-10-0216:39:39
  27. --Description:根据当前数据生成下个月的月初数据,并删除历史数据
  28. ------------------------------------
  29. DECLARE@sTABLE([年]INT,[月]INT,[工号]INT,[上月工分值]INT,[本月工分值]INT);
  30. INSERT@sSELECT2008,12,1,10,11;
  31. INSERT@sSELECT2008,12,2,11,12;
  32. INSERT@sSELECT2008,12,3,11,13;
  33. INSERT@sSELECT2008,12,4,3,5;
  34. INSERT@sSELECT2008,12,5,1,7;
  35. INSERT@sSELECT2008,12,6,2,11;
  36. DELETEFROM@s
  37. OUTPUTCASEWHENDELETED.[月]=12THENDELETED.[年]+1ELSEDELETED.[年]END,
  38. CASEWHENDELETED.[月]=12THEN1ELSEDELETED.[月]+1END,
  39. DELETED.[工号],DELETED.[本月工分值],NULLas[上月工分值]
  40. INTO@s;
  41. SELECT*
  42. FROM@s
  43. ORDERBY1,2,3
  44. /*
  45. 年月工号上月工分值本月工分值
  46. -------------------------------------------------------
  47. 20091111NULL
  48. 20091212NULL
  49. 20091313NULL
  50. 2009145NULL
  51. 2009157NULL
  52. 20091611NULL
  53. (6行受影响)
  54. */
  55. 2、根据业务规则的需要保证数据完整性。
  56. 在这个例程里我假设在更新员工的最后登录时间同时增加一条日志信息。先看测试数据:
  57. ------------------------------------
  58. --Author:happyflsytone
  59. --Date:2008-10-0216:39:39
  60. --Description:员工登录时更新员工表的最后登录时间,同时在日志表增加一条登录信息
  61. ------------------------------------
  62. --操作员信息表(本例只关心最后登录时间,所以员工的信息不深入表述)
  63. DECLARE@PTABLE([工号]INT,[姓名]varchar(16),[最后登录时间]datetime);
  64. INSERT@PSELECT1,'test1',getdate()-1;
  65. INSERT@PSELECT2,'test2',getdate()-1;
  66. INSERT@PSELECT3,'test3',getdate()-1;
  67. INSERT@PSELECT4,'test4',getdate()-1;
  68. INSERT@PSELECT5,'test5',getdate()-1;
  69. INSERT@PSELECT6,'test6',getdate()-1;
  70. --操作员操作日志(象征性列举一些字段)
  71. DECLARE@LOGTABLE([工号]INT,[操作时间]DATETIME,[操作类型]CHAR(6),[操作说明]VARCHAR(200));
  72. --模拟工号为3的操作员登录,并记录相应日志
  73. UPDATE@p
  74. SET[最后登录时间]=GETDATE()
  75. OUTPUTDELETED.[工号],DELETED.[最后登录时间],'出舱','成功出舱行走,身体状况良好,仪器工作正常,请主席放心!'
  76. INTO@log
  77. WHERE[工号]=3;
  78. --查看日志
  79. SELECT*
  80. FROM@LOG;
  81. /*
  82. 工号操作时间操作类型操作说明
  83. ----------------------------------------------------------------------------
  84. 32008-10-0117:06:58.790出舱成功出舱行走,身体状况良好,仪器工作正常,请主席放心!
  85. (1行受影响)
  86. */
  87. 注:其实我们可以通过这个OUTPUT_CLAUSE向应用程序提供数据操作的历史信息,或是把数据缓存在表变量中以备程序再次调用,关于这方面的例子就不多说明,因为这是最基本的OUTPUT_CLAUSE应用。
  88. 3、标识列或计算列方面的应用
  89. 对于标识列我们可能通过@@IDENTITY、SCOPE_IDENTITY和IDENT_CURRENT几个相似的函数获得,他们都返回插入到表的IDENTITY列的最后一个值(本身这几个函数还是有差异的,主要是它们的作用域,请查联机帮助)。我们注意到它们只是返回最后一个值,对于批量时就无能无力了。对于实时并发多的系统时我们可以利用OUTPUT_CLAUSE语句把标识列的值提取出来。
  90. ------------------------------------
  91. --Author:happyflsytone
  92. --Date:2008-10-0216:39:39
  93. ------------------------------------
  94. CREATETABLEScrapReason(scrapreasonidINTIDENTITY,[name]VARCHAR(50),modifieddateDATETIME)
  95. ;
  96. --接受标识列值的表变量
  97. DECLARE@MyTableVarTABLE(ScrapReasonIDSMALLINT,
  98. NameVARCHAR(50),
  99. ModifiedDateDATETIME);
  100. --模拟插入数据
  101. INSERTScrapReason
  102. OUTPUTINSERTED.ScrapReasonID,INSERTED.Name,INSERTED.ModifiedDate
  103. INTO@MyTableVar
  104. SELECTN'OperatorIDENTITY',GETDATE()
  105. FROMsys.objects;
  106. --查看记录的标识列数据
  107. SELECTScrapReasonID,Name,ModifiedDateFROM@MyTableVar;
  108. GO
  109. droptableScrapReason;
  110. /*
  111. ScrapReasonIDNameModifiedDate
  112. --------------------------------------------------------------------------------------
  113. 1OperatorIDENTITY2008-10-0217:42:19.000
  114. 2OperatorIDENTITY2008-10-0217:42:19.000
  115. 3OperatorIDENTITY2008-10-0217:42:19.000
  116. 4OperatorIDENTITY2008-10-0217:42:19.000
  117. 5OperatorIDENTITY2008-10-0217:42:19.000
  118. 6OperatorIDENTITY2008-10-0217:42:19.000
  119. .....
  120. .....
  121. 62OperatorIDENTITY2008-10-0217:42:19.000
  122. 63OperatorIDENTITY2008-10-0217:42:19.000
  123. (63行受影响)
  124. */
  125. 下面我们再来看看触发器使用OUTPUT_CLAUSE的情况,
  126. ------------------------------------
  127. --Author:happyflsytone
  128. --Date:2008-10-0216:39:39
  129. ------------------------------------
  130. CREATETABLETA(
  131. scrapreasonidINTIDENTITYPRIMARYKEY,
  132. [name]VARCHAR(50),
  133. modifieddateDATETIME
  134. )
  135. ;
  136. CREATETABLETB(
  137. IDINTREFERENCESTA(SCRAPREASONID),
  138. [name]VARCHAR(50),
  139. MODIFIEDDATEDATETIME
  140. );
  141. GO
  142. CREATETRIGGERTR_INSERT
  143. ONTA
  144. INSTEADOFINSERT
  145. AS
  146. BEGIN
  147. --接受标识列值的表变量
  148. DECLARE@MyTableVarTABLE(IDINT,
  149. [NAME]VARCHAR(10),
  150. ModifiedDateDATETIME);
  151. INSERTTA
  152. OUTPUTINSERTED.scrapreasonid,INSERTED.[NAME],INSERTED.ModifiedDate
  153. INTO@MyTableVar
  154. SELECT[name],modifieddateFROMINSERTED
  155. INSERTINTOTBSELECT*FROM@MyTableVar
  156. END
  157. GO
  158. --模拟插入数据
  159. INSERTTASELECT'TEST',GETDATE();
  160. INSERTTASELECT'TEST2',GETDATE();
  161. --查看记录的标识列数据
  162. SELECT*FROMTB;
  163. /*
  164. IDnameMODIFIEDDATE
  165. ------------------------------------------------------------------------------------
  166. 1TEST2008-10-0217:53:46.780
  167. 2TEST22008-10-0217:53:46.870
  168. (2行受影响)
  169. */
  170. DROPTABLETB,TA;
  171. 最后说明一下使用OUTPUT子句的注意事项:
  172. 以下语句中不支持OUTPUT子句:
  173. 1、引用本地分区视图、分布式分区视图或远程表的DML语句。
  174. 2、包含EXECUTE语句的INSERT语句。
  175. 3、不能将OUTPUTINTO子句插入视图或行集函数。
  176. 4、参数或变量作为UPDATE语句的一部分进行了修改,则OUTPUT子句将始终返回语句执行之前的参数或变量的值而不是已修改的值
  177. Flystone于常州
分享到:
评论

相关推荐

    SQLServer2008技术内幕T-SQL查询包含源代码及附录A

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化...

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    微软内部资料-SQL性能优化3

     Analyze the output of blocking scripts and Microsoft® SQL Server™ Profiler to troubleshoot locking and blocking issues.  Formulate hypothesis to resolve locking and blocking issues. ...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录 中文版

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    sqlserver存储过程

    Set @Sql='Insert into Users Values(''jilongliang'',''123456'',''广东阳春'')' Exec &#40;@Sql&#41; set @n=@n+1 End End ------------查询一下是不是插入--------------- Select *from Users; ---------...

    微软内部资料-SQL性能优化5

    On a qualified select, update, or delete, the correct leaf page will be the lowest page of the tree in which one or more rows with the specified key or keys reside. A qualified operation is one that ...

    PL/SQL 基础.doc

    PL/SQL 基础,一个不错的 PL/SQL 参考手册。内容预览: ---- 第一章 PL/SQL 简介 ---- 1. Oracle应用编辑方法概览 1) Pro*C/C++/... : C语言和数据库打交道的方法,比OCI更常用; 2) ODBC 3) OCI: C语言和...

    oracle实验报告

    (1)触发器可以声明为在对记录进行操作之前,在之前(检查约束之前和 INSERT,UPDATE 或 DELETE 执行前)或之后(在检查约束之后和完成 INSERT, UPDATE 或 DELETE 操作)触发.。 (2)一个 FOR EACH ROW 执行指定操作...

    sql总结.doc

    (1)若视图的字段是来自字段表达式或常数,则不允许对此视图执行INSERT、UPDATE操作,允许执行DELETE操作; (2)若视图的字段是来自库函数,则此视图不允许更新; (3)若视图的定义中有GROUP BY子句或聚集函数时...

    SQL sever 实训

    SQL sever 2008 Rar! ?s X祕BwL0 17240671-1.sql ?年3月9日 --1.查询course表的所有信息(所有行所有列) USE Xk GO SELECT * FROM Course --有哪些种类的选修课?学分是多少 USE XK GO SELECT Kind,Credit FROM ...

    VB编程资源大全(英文源码 数据库)

    as well as ample remarks.&lt;END&gt;&lt;br&gt;9 , pb_test.zip Test project illustrating high performance Data Access for SQL Server using ADO command objects and Stored Procedures for Insert, Update, Delete ...

    存储过程的安全及性能优化

    delete、insert、update命令 存储过程开始或结束 存储过程中的每一条语句 写入sql server错误日志的错误 打开游标 向数据对象添加或释放锁 Profiler事件 SQL Server Profiler里Standard模板的事件类 ...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    例如:INSERT(插入)、UPDATE(修改)、DELETE(删除)语句  数据查询语言 (Data Query Language, DQL) 是SQL语言中,负责进行数据查询而不会对数据本身进行修改的语句,这是最基本的SQL语句。例如:SELECT(查询...

    PL/SQL Developer8.04官网程序_keygen_汉化

     2) 数据操纵语言(DML):Update,Insert,Delete,…  3) 数据控制语言(DCL):Commit,Rollback,Savapoint,…  4) 其他:Alter System,Connect,Allocate, …  具体的语法结构可以参阅其他关于SQL语言的资料...

    Oracle事例

    insert into TABLENAME@DBLNKNAME (a,b) values (va,vb); update TABLENAME@DBLNKNAME set a=\'this\'; delete from TABLENAME@DBLNKNAME; 怎样执行远程的内嵌过程 begin otherdbpro@to_html(参数); end; ...

    精髓Oralcle讲课笔记

    --(函数nvl() 求出员工的"年薪 + 提成(或奖金)问题") 45、select max(sal) from emp; -- (函数max() 求出emp表中sal字段的最大值) 46、select min(sal) from emp; -- (函数max() 求出emp表中sal字段的最小值) ...

    xls转mdb代码以及.exe执行软件

    insert into openquery(mailser,'select disorder,catago from yulin')values(333,777) 补充: 对于用bcp导出,是没有字段名的. 用openrowset导出,需要事先建好表. 用openrowset导入,除ACCESS及EXCEL外,均不支持...

    Toad 使用快速入门

    用户可以使用快捷方式或模板来快速编写PL/SQL,也可以根据需要生成自己的模板。使用Toad可以非常方便地进行编辑工作,可如设置书签、取消注释、格式化SQL语句等等。 PL/SQL Debugger选项: Toad 提供简单易用的PL/...

    Oracle8i_9i数据库基础

    §6.4 insert、delete及update 的提交和撤消 176 §6.4.1 自动提交的设置 176 §6.4.2 保留点和撤消 177 第七章 复杂查询语句的使用 180 §7.1 复杂查询语句的使用 180 §7.1.1 相关子查询 180 §7.1.2 外连接 180 ...

    BobBuilder_app

    These tests were done on a HP ML120G6 system with 12Gb Ram, 10k raid disk drives running Windows 2008 Server R2 64 bit. For a measure of relative performance to RaptorDb v1 I have included a 20 ...

Global site tag (gtag.js) - Google Analytics