├── CHANGELOG.md ├── Examples ├── AzureSQLDbExample.ps1 ├── LoadTestExample.cmd ├── SQLServerExample.ps1 └── SingleQuery01.sql ├── LICENSE ├── README.md ├── RunWorkload.ps1 ├── RunWorkload ├── RunWorkload.psd1 └── RunWorkload.psm1 ├── SqlScripts ├── AdventureWorks2008R2BOLWorkload.sql ├── AdventureWorks2008R2BOLWorkload_Setup.sql ├── AdventureWorks2012BOLWorkload.sql ├── AdventureWorks2012BOLWorkload_Setup.sql ├── AdventureWorksAzureBOLWorkload.sql ├── AdventureWorksWorkload.sql └── AdventureWorksWorkload_Setup.sql ├── Tests └── RunWorkload.Tests.ps1 └── appveyor.yml /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log for SqlWorkloadGenerator 2 | 3 | ## Unreleased 4 | 5 | * None 6 | 7 | ### 1.1.0.0 8 | 9 | * Created version independant .sql files 10 | * Moved the Example_RunWorkload.ps1 to .\Examples 11 | * Renamed Example_RunWorkload.ps1 to AzureSQLDbExample.ps1 12 | * Created .\Examples\SQLServerExample.ps1 13 | * Created .\Examples\LoadTestExample.cmd 14 | * Improved error handling 15 | * SQL Assemblies are loaded by importing either SqlServer or SQLPS module 16 | 17 | ### 0.1.2 18 | 19 | * Moved functions to a module for better code coverage 20 | * Improved test coverage through AppVeyor 21 | 22 | ### 0.1.1 23 | 24 | * Added Duration parameter and better error verbatim (Issue4) 25 | 26 | ### 0.1.0 27 | 28 | * Added functions Invoke-Workload, Invoke-WorkloadSetup, Invoke-WorkloadQuery (Issue6) 29 | 30 | ### 0.0.3 31 | 32 | * Added ability to specify frequency for improved control over workload level 33 | 34 | ### 0.0.2 35 | 36 | * Added minor fixes (issue #1) removal of Write-Host 37 | 38 | 39 | ### 0.0.1 40 | 41 | * Initial release includes basic functionality and sample scripts 42 | 43 | -------------------------------------------------------------------------------- /Examples/AzureSQLDbExample.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | 4 | Script: AzureSqlDbExample.ps1 5 | Author: Matt Lavery (https://github.com/Matticusau/SqlWorkloadGenerator) 6 | Created: 29/05/2015 7 | Version: 0.0.1 8 | 9 | Change History 10 | Version Who When What 11 | -------------------------------------------------------------------------------------------------- 12 | 0.0.1 MLavery 29/05/2015 Initial Coding 13 | 0.0.2 MLavery 09/11/2017 Renamed from Example_RunWorkload.ps1 to AzureSQLDbExample.ps1 14 | 15 | DISCLAIMER 16 | This Sample Code is provided for the purpose of illustration only and is not intended to be 17 | used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED 18 | "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant 20 | You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 21 | distribute the object code form of the Sample Code, provided that You agree: (i) to not use 22 | Our name, logo, or trademarks to market Your software product in which the Sample Code is 23 | embedded; (ii) to include a valid copyright notice on Your software product in which the 24 | Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our 25 | suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise 26 | or result from the use or distribution of the Sample Code. 27 | #> 28 | 29 | Set-Location C:\WorkLoad 30 | 31 | .\RunWorkload.ps1 -SQLServer myazuredb.database.windows.net -Database DemoDB01 -UserName DemoUsr -Password ?????? -TSQLFile C:\WorkLoad\SqlScripts\AdventureWorksAzureBOLWorkload.sql 32 | -------------------------------------------------------------------------------- /Examples/LoadTestExample.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM Script: LoadTestExample.cmd 3 | REM Author: Matt Lavery (https://github.com/Matticusau/SqlWorkloadGenerator) 4 | REM Created: 09/11/2017 5 | REM Version: 0.0.1 6 | REM 7 | REM DISCLAIMER 8 | REM This Sample Code is provided for the purpose of illustration only and is not intended to be 9 | REM used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED 10 | REM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 11 | REM TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant 12 | REM You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 13 | REM distribute the object code form of the Sample Code, provided that You agree: (i) to not use 14 | REM Our name, logo, or trademarks to market Your software product in which the Sample Code is 15 | REM embedded; (ii) to include a valid copyright notice on Your software product in which the 16 | REM Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our 17 | REM suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise 18 | REM or result from the use or distribution of the Sample Code. 19 | 20 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SQLNode01\Prd01" -Database "AdventureWorks2014" -TSQLFile "C:\Workload\SqlScripts\AdventureWorksWorkload.sql" -Frequency "Fast" 21 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SQLNode01\Prd01" -Database "AdventureWorks2014" -TSQLFile "C:\Workload\SqlScripts\AdventureWorksWorkload.sql" -Frequency "Fast" 22 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SQLNode01\Prd01" -Database "AdventureWorks2014" -TSQLFile "C:\Workload\SqlScripts\AdventureWorksWorkload.sql" -Frequency "Normal" 23 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SQLNode01\Prd01" -Database "AdventureWorks2014" -TSQLFile "C:\Workload\SqlScripts\AdventureWorksWorkload.sql" -Frequency "Fast" 24 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SQLNode01\Prd01" -Database "AdventureWorks2014" -TSQLFile "C:\Workload\SqlScripts\AdventureWorksWorkload.sql" -Frequency "Fast" 25 | PAUSE -------------------------------------------------------------------------------- /Examples/SQLServerExample.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | 4 | Script: SQLServerExample.ps1 5 | Author: Matt Lavery (https://github.com/Matticusau/SqlWorkloadGenerator) 6 | Created: 09/11/2017 7 | Version: 0.0.1 8 | 9 | Change History 10 | Version Who When What 11 | -------------------------------------------------------------------------------------------------- 12 | 0.0.1 MLavery 09/11/2017 Initial Coding 13 | 14 | DISCLAIMER 15 | This Sample Code is provided for the purpose of illustration only and is not intended to be 16 | used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED 17 | "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 18 | TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant 19 | You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 20 | distribute the object code form of the Sample Code, provided that You agree: (i) to not use 21 | Our name, logo, or trademarks to market Your software product in which the Sample Code is 22 | embedded; (ii) to include a valid copyright notice on Your software product in which the 23 | Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our 24 | suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise 25 | or result from the use or distribution of the Sample Code. 26 | #> 27 | 28 | Set-Location C:\WorkLoad 29 | 30 | .\RunWorkload.ps1 -SQLServer svrSqlDev01.contoso.com -Database AdventureWorks2017 -UserName DemoUsr -Password ?????? -TSQLFile C:\WorkLoad\SqlScripts\AdventureWorksWorkload.sql 31 | -------------------------------------------------------------------------------- /Examples/SingleQuery01.sql: -------------------------------------------------------------------------------- 1 | SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ', 2 | p.Name AS ProductName 3 | FROM Production.Product AS p 4 | INNER JOIN Sales.SalesOrderDetail AS sod 5 | ON p.ProductID = sod.ProductID 6 | ORDER BY ProductName ASC -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/54s91yyoc7n70ceh/branch/master?svg=true)](https://ci.appveyor.com/project/Matticusau/sqlworkloadgenerator/branch/master) 2 | 3 | # SqlWorkloadGenerator 4 | PowerShell scripts to general SQL Server workload against AdventureWorks database schemas 5 | 6 | ## Description 7 | Provides sample SQL Scripts and PowerShell scripts to automate the generation of load against the AdventureWorks schema. 8 | 9 | Current supported versions are: 10 | - SQL 2008 / R2 11 | - SQL 2012 12 | - SQL 2014 13 | - SQL 2016 14 | - SQL 2017 15 | - SQL Azure 16 | 17 | This tool is currently only supported on Windows and PowerShell. It has not yet been tested on PowerShell Core. It will though work remotely against SQL Server on Linux. 18 | 19 | NOTE: For SQL Server 2014 and higher, use the non-version specific scripts. 20 | 21 | ## Installation 22 | To install and use this toolset follow these steps. 23 | 1. Create a folder *C:\Workload* or other suitable location 24 | 2. Download the project source or one of the releases to that location you just created 25 | 3. Create a wrapper script or start the RunWorkload.ps1 script from the console depending on your needs. Refer to the examples for various ways to execute this workload. 26 | 27 | ## Example 28 | 29 | This example runs a single workload session against a database running in SQL Azure with a fast frequency between batches 30 | 31 | ``` 32 | Set-Location C:\WorkLoad 33 | .\RunWorkload.ps1 -SQLServer myazuredb.database.windows.net -Database DemoDB01 -UserName DemoUsr -Password ?????? -TSQLFile C:\WorkLoad\AdventureWorksAzureBOLWorkload.sql -Frequency 'Fast' 34 | ``` 35 | 36 | For further examples see the files provided in [.\Examples](Examples\) folder. 37 | 38 | ## Running Larger Workloads 39 | 40 | To run a larger workload you may need to execute this script multiple times. To achieve this create a .cmd file with multiple lines such as: 41 | ``` 42 | Start PowerShell.exe -File "C:\Workload\RunWorkload.ps1" -SQLServer "SqlServer.contoso.com" -Database "DemoDB01" -TSQLFile "C:\Workload\AdventureWorks2012BOLWorkload.sql" -Frequency "Fast" 43 | ``` 44 | 45 | For an example see the file [.\Examples\LoadTestExample.cmd](Examples\LoadTestExample.cmd) 46 | 47 | ## PowerShell Execution Policies 48 | 49 | As this workload is generated through a PowerShell script, it is not excempt from PowerShell Execution Policies. The default policy is Restricted which will stop you from executing the workload script. In production environments it is **not** recommended to set this to Unrestricted, instead you should use `RemoteSigned` or `AllSigned` and then code sign the script files with your organisations certificate. 50 | 51 | As a workaround you could run the workload script from a .cmd file with the PowerShell.exe -ExecutionPolicy parameter set to RemoteSigned or as appropriate. This will only change the policy for the process and still allow you to execute the workload. However, if your policy is set through Group Policy then this will not take effect. 52 | ``` 53 | Start PowerShell.exe -ExecutionPolicy RemoteSigned -File "C:\Workload\RunWorkload.ps1" -SQLServer "SqlServer.contoso.com" -Database "DemoDB01" -TSQLFile "C:\Workload\AdventureWorks2012BOLWorkload.sql" -Frequency "Fast" 54 | ``` 55 | For further information see: 56 | Get-Help about_Execution_Policies 57 | https://technet.microsoft.com/en-au/library/hh847748.aspx 58 | 59 | ## Parameters 60 | 61 | ### SQLServer 62 | The SQL Server host name and instance to connect to (e.g. Server01\Prd01) 63 | 64 | ### Database 65 | The name of the database to run the script against. This allows for restoring the AdventureWorks database schema to custom databases. 66 | 67 | ### UserName 68 | If SQL Authentication is required this is the UserName to authenticate with. If not provided then Windows Auth is used. 69 | 70 | ### Password 71 | If SQL Authentication is required this is the Password to authenticate with. Not required for Windows Auth. 72 | Warning: This is currently stored in plain text 73 | 74 | ### TSQLFile 75 | The path to the TSQL file which contains the sample statements to execute. 76 | 77 | ### TSQLSetupFile 78 | The path to the TSQL file which contains the setup statements to execute before starting the process (if required). 79 | 80 | ### Frequency 81 | The frequency of which to run the statements at (Fast, Normal, or Slow) 82 | 83 | ### Duration 84 | The duration to run the workload for (seconds). 0 is unlimited, otherwise maximum allowed is 172800 (48hrs) 85 | 86 | ## Change log 87 | A full list of changes in each version can be found in the [change log](CHANGELOG.md). 88 | 89 | -------------------------------------------------------------------------------- /RunWorkload.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | 4 | Script: RunWorkload.ps1 5 | Author: Matt Lavery (https://github.com/Matticusau/SqlWorkloadGenerator) 6 | Created: 29/05/2015 7 | Version: 0.1.2 8 | 9 | Change History 10 | Version Who When What 11 | -------------------------------------------------------------------------------------------------- 12 | 0.0.1 MLavery 29/05/2015 Initial Coding 13 | 0.0.2 MLavery 03/08/2015 Minor fixes (issue #1) removal of Write-Host 14 | 0.0.3 MLavery 10/08/2015 Added Frequency parameter 15 | 0.1.0 MLavery 04/05/2016 Added functions Invoke-Workload, Invoke-WorkloadSetup, Invoke-WorkloadQuery (Issue6) 16 | 0.1.1 MLavery 05/05/2016 Added Duration parameter and better error verbatim (Issue4) 17 | 0.1.2 MLavery 05/05/2016 Moved functions to a module for better code coverage 18 | 19 | DISCLAIMER 20 | This Sample Code is provided for the purpose of illustration only and is not intended to be 21 | used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED 22 | "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 23 | TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant 24 | You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 25 | distribute the object code form of the Sample Code, provided that You agree: (i) to not use 26 | Our name, logo, or trademarks to market Your software product in which the Sample Code is 27 | embedded; (ii) to include a valid copyright notice on Your software product in which the 28 | Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our 29 | suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise 30 | or result from the use or distribution of the Sample Code. 31 | 32 | .SYNOPSIS 33 | A script to run SQL workload against an AdventureWorks database for demos 34 | 35 | .DESCRIPTION 36 | A script to run SQL workload against an AdventureWorks database for demos. Uses a collection of 37 | sample SQL statements taken from MSDN BOL for the various versions of SQL Server. 38 | Current supported versions are: 39 | - SQL 2008 / R2 40 | - SQL 2012 41 | - SQL 2014 (via 2012 script) 42 | - SQL Azure 43 | 44 | #> 45 | 46 | [cmdletbinding()] 47 | param ( 48 | # The SQL Server host name and instance to connect to (e.g. Server01\Prd01) 49 | [Parameter(Mandatory=$true)] 50 | [string]$SQLServer, 51 | 52 | # The name of the database to run the script against. This allows for restoring the AdventureWorks database schema to custom databases. 53 | [Parameter(Mandatory=$true)] 54 | [string]$Database, 55 | 56 | # If SQL Authentication is required this is the UserName to authenticate with. If not provided then Windows Auth is used. 57 | [Parameter(Mandatory=$false)] 58 | [string]$UserName, 59 | 60 | # If SQL Authentication is required this is the Password to authenticate with. Not required for Windows Auth. 61 | [Parameter(Mandatory=$false)] 62 | [string]$Password, 63 | 64 | # The path to the TSQL file which contains the sample statements to execute. 65 | [Parameter(Mandatory=$true)] 66 | [string]$TSQLFile, 67 | 68 | # The path to the TSQL file which contains the setup statements to execute before starting the process (if required). 69 | [Parameter(Mandatory=$false)] 70 | [string]$TSQLSetupFile, 71 | 72 | # The frequency of which to run the statements at (Fast, Normal, or Slow) 73 | [Parameter(Mandatory=$false)] 74 | [string][ValidateSet("Fast", "Normal", "Slow")]$Frequency = "Normal", 75 | 76 | # The duration to run the workload for (seconds). 0 is unlimited, otherwise maximum allowed is 172800 (48hrs) 77 | [parameter(mandatory=$false)] 78 | [int64][ValidateRange(0,172800)]$Duration = 0 79 | ) 80 | 81 | Clear-Host 82 | 83 | Write-Output "SQL Workload Generator" 84 | Write-Output "Starting..." 85 | 86 | [string]$workloadModulePath = ".\RunWorkload" 87 | if (-not(Test-Path -Path $workloadModulePath)) 88 | { 89 | Write-Output "Cannot find RunWorkload module at path '$($workloadModulePath)'"; 90 | $workloadModulePath = Read-Host -prompt "Please enter path to '.\RunWorkload' Module included with this toolset"; 91 | } 92 | 93 | Import-Module $workloadModulePath 94 | 95 | Invoke-SqlWorkload -SQLServer $SQLServer -Database $Database -UserName $UserName -Password $Password -TSQLFile $TSQLFile -TSQLSetupFile $TSQLSetupFile -Frequency $Frequency -Duration $Duration -Verbose; 96 | 97 | Write-Output "Done..." 98 | 99 | 100 | -------------------------------------------------------------------------------- /RunWorkload/RunWorkload.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'RunWorkload' 3 | # 4 | # Generated by: matticusau 5 | # 6 | # Generated on: 05/05/2016 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = 'RunWorkload.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '1.1.0.0' 16 | 17 | # ID used to uniquely identify this module 18 | GUID = 'cd04fe86-97b8-473b-b104-b8e8040df9fe' 19 | 20 | # Author of this module 21 | Author = 'matticusau' 22 | 23 | # Company or vendor of this module 24 | CompanyName = 'Unknown' 25 | 26 | # Copyright statement for this module 27 | Copyright = '2016' 28 | 29 | # Description of the functionality provided by this module 30 | Description = 'Provides functions for generating a workload against a SQL Server instance' 31 | 32 | # Minimum version of the Windows PowerShell engine required by this module 33 | PowerShellVersion = '4.0' 34 | 35 | # Name of the Windows PowerShell host required by this module 36 | # PowerShellHostName = '' 37 | 38 | # Minimum version of the Windows PowerShell host required by this module 39 | # PowerShellHostVersion = '' 40 | 41 | # Minimum version of Microsoft .NET Framework required by this module 42 | # DotNetFrameworkVersion = '' 43 | 44 | # Minimum version of the common language runtime (CLR) required by this module 45 | # CLRVersion = '' 46 | 47 | # Processor architecture (None, X86, Amd64) required by this module 48 | # ProcessorArchitecture = '' 49 | 50 | # Modules that must be imported into the global environment prior to importing this module 51 | # RequiredModules = @() 52 | 53 | # Assemblies that must be loaded prior to importing this module 54 | # RequiredAssemblies = @() 55 | 56 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 57 | # ScriptsToProcess = @() 58 | 59 | # Type files (.ps1xml) to be loaded when importing this module 60 | # TypesToProcess = @() 61 | 62 | # Format files (.ps1xml) to be loaded when importing this module 63 | # FormatsToProcess = @() 64 | 65 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 66 | # NestedModules = @() 67 | 68 | # Functions to export from this module 69 | FunctionsToExport = 'Invoke-SqlWorkload' 70 | 71 | # Cmdlets to export from this module 72 | CmdletsToExport = '*' 73 | 74 | # Variables to export from this module 75 | VariablesToExport = '*' 76 | 77 | # Aliases to export from this module 78 | AliasesToExport = '*' 79 | 80 | # DSC resources to export from this module 81 | # DscResourcesToExport = @() 82 | 83 | # List of all modules packaged with this module 84 | # ModuleList = @() 85 | 86 | # List of all files packaged with this module 87 | # FileList = @() 88 | 89 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 90 | PrivateData = @{ 91 | 92 | PSData = @{ 93 | 94 | # Tags applied to this module. These help with module discovery in online galleries. 95 | # Tags = @() 96 | 97 | # A URL to the license for this module. 98 | # LicenseUri = '' 99 | 100 | # A URL to the main website for this project. 101 | # ProjectUri = '' 102 | 103 | # A URL to an icon representing this module. 104 | # IconUri = '' 105 | 106 | # ReleaseNotes of this module 107 | # ReleaseNotes = '' 108 | 109 | } # End of PSData hashtable 110 | 111 | } # End of PrivateData hashtable 112 | 113 | # HelpInfo URI of this module 114 | # HelpInfoURI = '' 115 | 116 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 117 | # DefaultCommandPrefix = '' 118 | 119 | } 120 | 121 | -------------------------------------------------------------------------------- /RunWorkload/RunWorkload.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Script: RunWorkload.psm1 3 | Author: Matt Lavery (https://github.com/Matticusau/SqlWorkloadGenerator) 4 | Created: 05/05/2016 5 | Version: 1.1.0.0 6 | 7 | Change History 8 | Version Who When What 9 | -------------------------------------------------------------------------------------------------- 10 | 1.0.0.0 MLavery 05/05/2016 Initial Coding from existing scripts (Issue6) 11 | 1.1.0.0 MLavery 09/11/2017 Better error handling and uses the SQL modules to load assemblies 12 | 13 | 14 | DISCLAIMER 15 | This Sample Code is provided for the purpose of illustration only and is not intended to be 16 | used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED 17 | "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 18 | TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant 19 | You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and 20 | distribute the object code form of the Sample Code, provided that You agree: (i) to not use 21 | Our name, logo, or trademarks to market Your software product in which the Sample Code is 22 | embedded; (ii) to include a valid copyright notice on Your software product in which the 23 | Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our 24 | suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise 25 | or result from the use or distribution of the Sample Code. 26 | 27 | #> 28 | 29 | function Invoke-SqlWorkload 30 | { 31 | [CmdLetBinding()] 32 | Param( 33 | # The SQL Server host name and instance to connect to (e.g. Server01\Prd01) 34 | [Parameter(Mandatory=$true)] 35 | [string]$SQLServer, 36 | 37 | # The name of the database to run the script against. This allows for restoring the AdventureWorks database schema to custom databases. 38 | [Parameter(Mandatory=$true)] 39 | [string]$Database, 40 | 41 | # If SQL Authentication is required this is the UserName to authenticate with. If not provided then Windows Auth is used. 42 | [Parameter(Mandatory=$false)] 43 | [string]$UserName, 44 | 45 | # If SQL Authentication is required this is the Password to authenticate with. Not required for Windows Auth. 46 | [Parameter(Mandatory=$false)] 47 | [string]$Password, 48 | 49 | # The path to the TSQL file which contains the sample statements to execute. 50 | [Parameter(Mandatory=$true)] 51 | [string]$TSQLFile, 52 | 53 | # The path to the TSQL file which contains the setup statements to execute before starting the process (if required). 54 | [Parameter(Mandatory=$false)] 55 | [string]$TSQLSetupFile, 56 | 57 | # The frequency of which to run the statements at (Fast, Normal, or Slow) 58 | [Parameter(Mandatory=$false)] 59 | [string][ValidateSet("Fast", "Normal", "Slow")]$Frequency = "Normal", 60 | 61 | # The duration to run the workload for (seconds). 0 is unlimited, otherwise maximum allowed is 172800 (48hrs) 62 | [parameter(mandatory=$false)] 63 | [int64][ValidateRange(0,172800)]$Duration = 0 64 | ) 65 | 66 | # Run the setup file if supplied 67 | if ($TSQLSetupFile.Length -gt 0) 68 | { 69 | Invoke-SqlWorkloadSetup -SQLServer $SQLServer -Database $Database -UserName $UserName -Password $Password -TSQLSetupFile $TSQLSetupFile; 70 | } 71 | 72 | # set the start time 73 | $startTime = Get-Date; 74 | 75 | # Split the input on the delimeter 76 | $queries = Get-Content -Delimiter "----Query----" -Path $TSQLFile #"AdventureWorks2012BOLWorkload.sql" 77 | 78 | [int]$loopCount = 0; 79 | 80 | WHILE(1 -eq 1) 81 | { 82 | # increment the count 83 | $loopCount = $loopCount + 1; 84 | 85 | # check if we have exceeded the timespan for execution 86 | if ($Duration -gt 0 -and ((New-TimeSpan -Start $startTime -End (Get-Date)).Seconds -ge $Duration)) 87 | { 88 | Write-Verbose "Duration of $Duration seconds reached"; 89 | Break; 90 | } 91 | 92 | try 93 | { 94 | # Pick a Random Query from the input object 95 | $query = Get-Random -InputObject $queries; 96 | 97 | Write-Output "Query ($($loopCount))" 98 | 99 | #Run the Query 100 | Invoke-SqlWorkloadQuery -SQLServer $SQLServer -Database $Database -UserName $UserName -Password $Password -Query $query; 101 | 102 | } 103 | catch 104 | { 105 | #Report the error 106 | Write-Warning "Could not execute via Invoke-SqlWorkloadQuery" 107 | Write-Warning "$($PSItem.Exception.Message)"; 108 | #throw $PSItem; 109 | } 110 | finally 111 | { 112 | #Wait for a random delay to make this more realistic when running multiple workloads 113 | if ($Frequency = "Fast") {$sleepMilSecs = Get-Random -Minimum 1 -Maximum 500} 114 | elseif ($Frequency = "Slow") {$sleepMilSecs = Get-Random -Minimum 1000 -Maximum 5000} 115 | else {$SleepMilSecs = Get-Random -Minimum 100 -Maximum 5000}; 116 | 117 | Write-Verbose "Waiting for $($sleepMilSecs) milliseconds"; 118 | Start-Sleep -Milliseconds $sleepMilSecs 119 | } 120 | 121 | } 122 | 123 | } 124 | 125 | function Invoke-SqlWorkloadQuery 126 | { 127 | [CmdLetBinding()] 128 | Param( 129 | # The SQL Server host name and instance to connect to (e.g. Server01\Prd01) 130 | [Parameter(Mandatory=$true)] 131 | [string]$SQLServer, 132 | 133 | # The name of the database to run the script against. This allows for restoring the AdventureWorks database schema to custom databases. 134 | [Parameter(Mandatory=$true)] 135 | [string]$Database, 136 | 137 | # If SQL Authentication is required this is the UserName to authenticate with. If not provided then Windows Auth is used. 138 | [Parameter(Mandatory=$false)] 139 | [string]$UserName, 140 | 141 | # If SQL Authentication is required this is the Password to authenticate with. Not required for Windows Auth. 142 | [Parameter(Mandatory=$false)] 143 | [string]$Password, 144 | 145 | [Parameter(Mandatory=$true)] 146 | [string]$Query 147 | 148 | ) 149 | 150 | try 151 | { 152 | #Get a server object which corresponds to the default instance 153 | $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server $SQLServer 154 | 155 | # Use the database 156 | $srv.ConnectionContext.set_DatabaseName($Database) 157 | 158 | # Set the credentials if needed 159 | if ($UserName.Length -gt 0) 160 | { 161 | $srv.ConnectionContext.LoginSecure = $false; 162 | $srv.ConnectionContext.Login = $UserName; 163 | $srv.ConnectionContext.Password = $Password; 164 | } 165 | 166 | # Execute the query with ExecuteNonQuery 167 | $result = $srv.ConnectionContext.ExecuteNonQuery($Query); 168 | 169 | # Disconnect from the server 170 | $srv.ConnectionContext.Disconnect(); 171 | 172 | Write-Debug "`$Query = $($Query)"; 173 | 174 | } 175 | # SQL Exception 176 | catch [System.Data.SqlClient.SqlException],[Microsoft.SqlServer.Management.Common.ExecutionFailureException] 177 | { 178 | # Use Verbose for troubleshooting 179 | Write-Verbose "Failed to execute: $($Query)"; 180 | # we need to go a few levels deep to get the actual exception from sql 181 | Write-Verbose "$($PSItem.Exception.InnerException.InnerException.Message)"; 182 | # throw $PSItem; 183 | } 184 | # All Other Exception 185 | catch 186 | { 187 | # Use Verbose for troubleshooting 188 | Write-Verbose "Failed to execute: $($Query)"; 189 | # General error so just use the exception 190 | Write-Verbose "$($PSItem.Exception.Message)"; 191 | # throw $PSItem; 192 | } 193 | finally 194 | { 195 | #remove the SQL Server object if required 196 | if ($srv){ 197 | $srv.ConnectionContext.Disconnect(); 198 | } 199 | } 200 | } 201 | 202 | 203 | 204 | 205 | function Invoke-SqlWorkloadSetup 206 | { 207 | [CmdLetBinding()] 208 | Param( 209 | # The SQL Server host name and instance to connect to (e.g. Server01\Prd01) 210 | [Parameter(Mandatory=$true)] 211 | [string]$SQLServer, 212 | 213 | # The name of the database to run the script against. This allows for restoring the AdventureWorks database schema to custom databases. 214 | [Parameter(Mandatory=$true)] 215 | [string]$Database, 216 | 217 | # If SQL Authentication is required this is the UserName to authenticate with. If not provided then Windows Auth is used. 218 | [Parameter(Mandatory=$false)] 219 | [string]$UserName, 220 | 221 | # If SQL Authentication is required this is the Password to authenticate with. Not required for Windows Auth. 222 | [Parameter(Mandatory=$false)] 223 | [string]$Password, 224 | 225 | # The path to the TSQL file which contains the setup statements to execute before starting the process (if required). 226 | [Parameter(Mandatory=$false)] 227 | [string]$TSQLSetupFile 228 | ) 229 | 230 | try 231 | { 232 | # get the setup queries 233 | $setupTSQL = Get-Content -Path $TSQLSetupFile; 234 | 235 | #Get a server object which corresponds to the default instance 236 | $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server $SQLServer 237 | 238 | # Use the database 239 | $srv.ConnectionContext.set_DatabaseName($Database) 240 | 241 | # Set the credentials if needed 242 | if ($UserName.Length -gt 0) 243 | { 244 | $srv.ConnectionContext.LoginSecure = $false; 245 | $srv.ConnectionContext.Login = $UserName; 246 | $srv.ConnectionContext.Password = $Password; 247 | } 248 | 249 | #Write-Output $Query; 250 | 251 | # Execute the query with ExecuteNonQuery 252 | $result = $srv.ConnectionContext.ExecuteNonQuery($setupTSQL); 253 | 254 | # Disconnect from the server 255 | $srv.ConnectionContext.Disconnect(); 256 | 257 | Write-Output "Setup Script Executed" 258 | 259 | } 260 | catch 261 | { 262 | #Write an error 263 | Write-Error "Setup Script Failed" 264 | #throw $PSItem; 265 | Exit; # stop the script execution 266 | } 267 | } 268 | 269 | 270 | # Load the SMO assembly 271 | # [void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo"); 272 | # Import the SQL Module to load the assemblies 273 | if ($null -ne (Get-module -Name SqlServer -ListAvailable -ErrorAction SilentlyContinue)) 274 | { 275 | Import-Module -Name SqlServer; 276 | } 277 | elseif ($null -ne (Get-module -Name SQLPS -ListAvailable -ErrorAction SilentlyContinue)) 278 | { 279 | Import-Module -Name SQLPS -DisableNameChecking; 280 | } 281 | else 282 | { 283 | Write-Error "Neither the SqlServer or SQLPS PowerShell Modules are installed" 284 | #throw $PSItem; 285 | Exit; # stop the script execution 286 | } 287 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorks2008R2BOLWorkload.sql: -------------------------------------------------------------------------------- 1 | ----Query---- 2 | -- http://msdn.microsoft.com/en-us/library/ms178544.aspx 3 | SELECT SalesQuota, SUM(SalesYTD) 'TotalSalesYTD', GROUPING(SalesQuota) AS 'Grouping' 4 | FROM Sales.SalesPerson 5 | GROUP BY SalesQuota WITH ROLLUP; 6 | GO 7 | 8 | ----Query---- 9 | 10 | -- http://msdn.microsoft.com/en-us/library/bb510624.aspx 11 | SELECT D.Name 12 | ,CASE 13 | WHEN GROUPING_ID(D.Name, E.JobTitle) = 0 THEN E.JobTitle 14 | WHEN GROUPING_ID(D.Name, E.JobTitle) = 1 THEN N'Total: ' + D.Name 15 | WHEN GROUPING_ID(D.Name, E.JobTitle) = 3 THEN N'Company Total:' 16 | ELSE N'Unknown' 17 | END AS N'Job Title' 18 | ,COUNT(E.BusinessEntityID) AS N'Employee Count' 19 | FROM HumanResources.Employee E 20 | INNER JOIN HumanResources.EmployeeDepartmentHistory DH 21 | ON E.BusinessEntityID = DH.BusinessEntityID 22 | INNER JOIN HumanResources.Department D 23 | ON D.DepartmentID = DH.DepartmentID 24 | WHERE DH.EndDate IS NULL 25 | AND D.DepartmentID IN (12,14) 26 | GROUP BY ROLLUP(D.Name, E.JobTitle); 27 | 28 | ----Query---- 29 | 30 | -- http://msdn.microsoft.com/en-us/library/bb510624.aspx 31 | SELECT D.Name 32 | ,E.JobTitle 33 | ,GROUPING_ID(D.Name, E.JobTitle) AS 'Grouping Level' 34 | ,COUNT(E.BusinessEntityID) AS N'Employee Count' 35 | FROM HumanResources.Employee AS E 36 | INNER JOIN HumanResources.EmployeeDepartmentHistory AS DH 37 | ON E.BusinessEntityID = DH.BusinessEntityID 38 | INNER JOIN HumanResources.Department AS D 39 | ON D.DepartmentID = DH.DepartmentID 40 | WHERE DH.EndDate IS NULL 41 | AND D.DepartmentID IN (12,14) 42 | GROUP BY ROLLUP(D.Name, E.JobTitle) 43 | HAVING GROUPING_ID(D.Name, E.JobTitle) = 0; --All titles 44 | 45 | ----Query---- 46 | 47 | -- http://msdn.microsoft.com/en-us/library/bb510624.aspx 48 | SELECT D.Name 49 | ,E.JobTitle 50 | ,GROUPING_ID(D.Name, E.JobTitle) AS 'Grouping Level' 51 | ,COUNT(E.BusinessEntityID) AS N'Employee Count' 52 | FROM HumanResources.Employee AS E 53 | INNER JOIN HumanResources.EmployeeDepartmentHistory AS DH 54 | ON E.BusinessEntityID = DH.BusinessEntityID 55 | INNER JOIN HumanResources.Department AS D 56 | ON D.DepartmentID = DH.DepartmentID 57 | WHERE DH.EndDate IS NULL 58 | AND D.DepartmentID IN (12,14) 59 | GROUP BY ROLLUP(D.Name, E.JobTitle) 60 | HAVING GROUPING_ID(D.Name, E.JobTitle) = 1; --Group by Name; 61 | 62 | ----Query---- 63 | 64 | --http://msdn.microsoft.com/en-us/library/bb677202.aspx 65 | 66 | DECLARE @CurrentEmployee hierarchyid 67 | SELECT @CurrentEmployee = OrganizationNode 68 | FROM HumanResources.Employee 69 | WHERE LoginID = 'adventure-works\david0' 70 | 71 | SELECT OrganizationNode.ToString() AS Text_OrganizationNode, * 72 | FROM HumanResources.Employee 73 | WHERE OrganizationNode.GetAncestor(1) = @CurrentEmployee ; 74 | GO 75 | 76 | DECLARE @CurrentEmployee hierarchyid 77 | SELECT @CurrentEmployee = OrganizationNode 78 | FROM HumanResources.Employee 79 | WHERE LoginID = 'adventure-works\ken0' 80 | 81 | SELECT OrganizationNode.ToString() AS Text_OrganizationNode, * 82 | FROM HumanResources.Employee 83 | WHERE OrganizationNode.GetAncestor(2) = @CurrentEmployee ; 84 | GO 85 | 86 | DECLARE @CurrentEmployee hierarchyid 87 | SELECT @CurrentEmployee = OrganizationNode 88 | FROM HumanResources.Employee 89 | WHERE LoginID = 'adventure-works\david0' 90 | 91 | SELECT OrganizationNode.ToString() AS Text_OrganizationNode, * 92 | FROM HumanResources.Employee 93 | WHERE OrganizationNode.GetAncestor(0) = @CurrentEmployee ; 94 | GO 95 | 96 | DECLARE @CurrentEmployee hierarchyid ; 97 | DECLARE @TargetEmployee hierarchyid ; 98 | SELECT @CurrentEmployee = '/2/3/1.2/5/3/' ; 99 | SELECT @TargetEmployee = @CurrentEmployee.GetAncestor(2) ; 100 | SELECT @TargetEmployee.ToString(), @TargetEmployee ; 101 | GO 102 | 103 | ----Query---- 104 | 105 | -- http://msdn.microsoft.com/en-us/library/ms181708.aspx 106 | SELECT CustomerID, OrderDate, SubTotal, TotalDue 107 | FROM Sales.SalesOrderHeader 108 | WHERE SalesPersonID = 35 109 | ORDER BY OrderDate 110 | COMPUTE SUM(SubTotal), SUM(TotalDue); 111 | GO 112 | 113 | 114 | SELECT SalesPersonID, CustomerID, OrderDate, SubTotal, TotalDue 115 | FROM Sales.SalesOrderHeader 116 | ORDER BY SalesPersonID, OrderDate 117 | COMPUTE SUM(SubTotal), SUM(TotalDue) BY SalesPersonID; 118 | 119 | ----Query---- 120 | 121 | -- http://msdn.microsoft.com/en-us/library/ms187731.aspx 122 | 123 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 124 | A. Using SELECT to retrieve rows and columns 125 | The following example shows three code examples. This first code 126 | example returns all rows (no WHERE clause is specified) and all 127 | columns (using the *) from the Product table in the 128 | AdventureWorks2008R2 database. 129 | */ 130 | 131 | SELECT * 132 | FROM Production.Product 133 | ORDER BY Name ASC; 134 | -- Alternate way. 135 | SELECT p.* 136 | FROM Production.Product AS p 137 | ORDER BY Name ASC; 138 | GO 139 | 140 | /* 141 | This example returns all rows (no WHERE clause is specified), and 142 | only a subset of the columns (Name, ProductNumber, ListPrice) from 143 | the Product table in the AdventureWorks2008R2 database. Additionally, 144 | a column heading is added. 145 | */ 146 | 147 | SELECT Name, ProductNumber, ListPrice AS Price 148 | FROM Production.Product 149 | ORDER BY Name ASC; 150 | GO 151 | 152 | 153 | /* 154 | This example returns only the rows for Product that have a product 155 | line of R and that have days to manufacture that is less than 4. 156 | */ 157 | 158 | SELECT Name, ProductNumber, ListPrice AS Price 159 | FROM Production.Product 160 | WHERE ProductLine = 'R' 161 | AND DaysToManufacture < 4 162 | ORDER BY Name ASC; 163 | GO 164 | 165 | ----Query---- 166 | 167 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 168 | B. Using SELECT with column headings and calculations 169 | The following examples return all rows from the Product table. The 170 | first example returns total sales and the discounts for each product. 171 | In the second example, the total revenue is calculated for each 172 | product. 173 | */ 174 | 175 | SELECT p.Name AS ProductName, 176 | NonDiscountSales = (OrderQty * UnitPrice), 177 | Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount) 178 | FROM Production.Product AS p 179 | INNER JOIN Sales.SalesOrderDetail AS sod 180 | ON p.ProductID = sod.ProductID 181 | ORDER BY ProductName DESC; 182 | GO 183 | 184 | 185 | /* 186 | This is the query that calculates the revenue for each product in 187 | each sales order. 188 | */ 189 | 190 | SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ', 191 | p.Name AS ProductName 192 | FROM Production.Product AS p 193 | INNER JOIN Sales.SalesOrderDetail AS sod 194 | ON p.ProductID = sod.ProductID 195 | ORDER BY ProductName ASC; 196 | GO 197 | 198 | ----Query---- 199 | 200 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 201 | C. Using DISTINCT with SELECT 202 | The following example uses DISTINCT to prevent the retrieval 203 | of duplicate titles. 204 | */ 205 | 206 | SELECT DISTINCT JobTitle 207 | FROM HumanResources.Employee 208 | ORDER BY JobTitle; 209 | GO 210 | 211 | ----Query---- 212 | 213 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 214 | D. Creating tables with SELECT INTO 215 | The following first example creates a temporary table named 216 | #Bicycles in tempdb. 217 | */ 218 | 219 | USE tempdb; 220 | GO 221 | IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL 222 | DROP TABLE #Bicycles; 223 | GO 224 | SELECT * 225 | INTO #Bicycles 226 | FROM Production.Product 227 | WHERE ProductNumber LIKE 'BK%'; 228 | GO 229 | 230 | 231 | ----Query---- 232 | 233 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 234 | E. Using correlated subqueries 235 | The following example shows queries that are semantically 236 | equivalent and illustrates the difference between using the 237 | EXISTS keyword and the IN keyword. Both are examples of a 238 | valid subquery that retrieves one instance of each product 239 | name for which the product model is a long sleeve logo jersey, 240 | and the ProductModelID numbers match between the Product and 241 | ProductModel tables. 242 | */ 243 | 244 | SELECT DISTINCT Name 245 | FROM Production.Product AS p 246 | WHERE EXISTS 247 | (SELECT * 248 | FROM Production.ProductModel AS pm 249 | WHERE p.ProductModelID = pm.ProductModelID 250 | AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'); 251 | GO 252 | 253 | -- OR 254 | 255 | SELECT DISTINCT Name 256 | FROM Production.Product 257 | WHERE ProductModelID IN 258 | (SELECT ProductModelID 259 | FROM Production.ProductModel 260 | WHERE Name LIKE 'Long-Sleeve Logo Jersey%'); 261 | GO 262 | 263 | /* 264 | The following example uses IN in a correlated, or repeating, 265 | subquery. This is a query that depends on the outer query for 266 | its values. The query is executed repeatedly, one time for each 267 | row that may be selected by the outer query. This query 268 | retrieves one instance of the first and last name of each 269 | employee for which the bonus in the SalesPerson table is 5000.00 270 | and for which the employee identification numbers match in the 271 | Employee and SalesPerson tables. 272 | */ 273 | 274 | SELECT DISTINCT p.LastName, p.FirstName 275 | FROM Person.Person AS p 276 | JOIN HumanResources.Employee AS e 277 | ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN 278 | (SELECT Bonus 279 | FROM Sales.SalesPerson AS sp 280 | WHERE e.BusinessEntityID = sp.BusinessEntityID); 281 | GO 282 | 283 | /* 284 | The previous subquery in this statement cannot be evaluated 285 | independently of the outer query. It requires a value for 286 | Employee.BusinessEntityID, but this value changes as the SQL 287 | Server Database Engine examines different rows in Employee. 288 | 289 | A correlated subquery can also be used in the HAVING clause of 290 | an outer query. This example finds the product models for which 291 | the maximum list price is more than twice the average for the 292 | model. 293 | */ 294 | 295 | SELECT p1.ProductModelID 296 | FROM Production.Product AS p1 297 | GROUP BY p1.ProductModelID 298 | HAVING MAX(p1.ListPrice) >= ALL 299 | (SELECT AVG(p2.ListPrice) 300 | FROM Production.Product AS p2 301 | WHERE p1.ProductModelID = p2.ProductModelID); 302 | GO 303 | 304 | /* 305 | This example uses two correlated subqueries to find the names 306 | of employees who have sold a particular product. 307 | */ 308 | 309 | SELECT DISTINCT pp.LastName, pp.FirstName 310 | FROM Person.Person pp JOIN HumanResources.Employee e 311 | ON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN 312 | (SELECT SalesPersonID 313 | FROM Sales.SalesOrderHeader 314 | WHERE SalesOrderID IN 315 | (SELECT SalesOrderID 316 | FROM Sales.SalesOrderDetail 317 | WHERE ProductID IN 318 | (SELECT ProductID 319 | FROM Production.Product p 320 | WHERE ProductNumber = 'BK-M68B-42'))); 321 | GO 322 | 323 | ----Query---- 324 | 325 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 326 | F. Using GROUP BY 327 | The following example finds the total of each sales order in 328 | the database. 329 | */ 330 | 331 | SELECT SalesOrderID, SUM(LineTotal) AS SubTotal 332 | FROM Sales.SalesOrderDetail 333 | GROUP BY SalesOrderID 334 | ORDER BY SalesOrderID; 335 | GO 336 | 337 | ----Query---- 338 | 339 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 340 | Because of the GROUP BY clause, only one row containing the sum of all 341 | sales is returned for each sales order. 342 | 343 | G. Using GROUP BY with multiple groups 344 | The following example finds the average price and the sum of 345 | year-to-date sales, grouped by product ID and special offer ID. 346 | */ 347 | 348 | SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS 'Average Price', 349 | SUM(LineTotal) AS SubTotal 350 | FROM Sales.SalesOrderDetail 351 | GROUP BY ProductID, SpecialOfferID 352 | ORDER BY ProductID; 353 | GO 354 | 355 | ----Query---- 356 | 357 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 358 | H. Using GROUP BY and WHERE 359 | The following example puts the results into groups after retrieving 360 | only the rows with list prices greater than $1000. 361 | */ 362 | 363 | SELECT ProductModelID, AVG(ListPrice) AS 'Average List Price' 364 | FROM Production.Product 365 | WHERE ListPrice > $1000 366 | GROUP BY ProductModelID 367 | ORDER BY ProductModelID; 368 | GO 369 | 370 | ----Query---- 371 | 372 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 373 | I. Using GROUP BY with an expression 374 | The following example groups by an expression. You can group 375 | by an expression if the expression does not include aggregate 376 | functions. 377 | */ 378 | 379 | SELECT AVG(OrderQty) AS 'Average Quantity', 380 | NonDiscountSales = (OrderQty * UnitPrice) 381 | FROM Sales.SalesOrderDetail 382 | GROUP BY (OrderQty * UnitPrice) 383 | ORDER BY (OrderQty * UnitPrice) DESC; 384 | GO 385 | 386 | ----Query---- 387 | 388 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 389 | J. Using GROUP BY with ORDER BY 390 | The following example finds the average price of each type of 391 | product and orders the results by average price. 392 | */ 393 | 394 | SELECT ProductID, AVG(UnitPrice) AS 'Average Price' 395 | FROM Sales.SalesOrderDetail 396 | WHERE OrderQty > 10 397 | GROUP BY ProductID 398 | ORDER BY AVG(UnitPrice); 399 | GO 400 | 401 | ----Query---- 402 | 403 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 404 | K. Using the HAVING clause 405 | The first example that follows shows a HAVING clause with an 406 | aggregate function. It groups the rows in the SalesOrderDetail 407 | table by product ID and eliminates products whose average order 408 | quantities are five or less. The second example shows a HAVING 409 | clause without aggregate functions. 410 | */ 411 | 412 | SELECT ProductID 413 | FROM Sales.SalesOrderDetail 414 | GROUP BY ProductID 415 | HAVING AVG(OrderQty) > 5 416 | ORDER BY ProductID; 417 | GO 418 | 419 | /* 420 | This query uses the LIKE clause in the HAVING clause. 421 | */ 422 | 423 | SELECT SalesOrderID, CarrierTrackingNumber 424 | FROM Sales.SalesOrderDetail 425 | GROUP BY SalesOrderID, CarrierTrackingNumber 426 | HAVING CarrierTrackingNumber LIKE '4BD%' 427 | ORDER BY SalesOrderID ; 428 | GO 429 | 430 | ----Query---- 431 | 432 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 433 | L. Using HAVING and GROUP BY 434 | The following example shows using GROUP BY, HAVING, WHERE, and 435 | ORDER BY clauses in one SELECT statement. It produces groups and 436 | summary values but does so after eliminating the products with 437 | prices over $25 and average order quantities under 5. It also 438 | organizes the results by ProductID. 439 | */ 440 | 441 | SELECT ProductID 442 | FROM Sales.SalesOrderDetail 443 | WHERE UnitPrice < 25.00 444 | GROUP BY ProductID 445 | HAVING AVG(OrderQty) > 5 446 | ORDER BY ProductID; 447 | GO 448 | 449 | ----Query---- 450 | 451 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 452 | M. Using HAVING with SUM and AVG 453 | The following example groups the SalesOrderDetail table by product 454 | ID and includes only those groups of products that have orders 455 | totaling more than $1000000.00 and whose average order quantities 456 | are less than 3. 457 | */ 458 | 459 | SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total 460 | FROM Sales.SalesOrderDetail 461 | GROUP BY ProductID 462 | HAVING SUM(LineTotal) > $1000000.00 463 | AND AVG(OrderQty) < 3; 464 | GO 465 | 466 | /* 467 | To see the products that have had total sales greater than 468 | $2000000.00, use this query: 469 | */ 470 | 471 | SELECT ProductID, Total = SUM(LineTotal) 472 | FROM Sales.SalesOrderDetail 473 | GROUP BY ProductID 474 | HAVING SUM(LineTotal) > $2000000.00; 475 | GO 476 | 477 | /* 478 | If you want to make sure there are at least one thousand five 479 | hundred items involved in the calculations for each product, use 480 | HAVING COUNT(*) > 1500 to eliminate the products that return totals 481 | for fewer than 1500 items sold. The query looks like this: 482 | */ 483 | 484 | SELECT ProductID, SUM(LineTotal) AS Total 485 | FROM Sales.SalesOrderDetail 486 | GROUP BY ProductID 487 | HAVING COUNT(*) > 1500; 488 | GO 489 | 490 | ----Query---- 491 | 492 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 493 | N. Calculating group totals by using COMPUTE BY 494 | The following example uses two code examples to show the use 495 | of COMPUTE BY. The first code example uses one COMPUTE BY with 496 | one aggregate function, and the second code example uses one 497 | COMPUTE BY item and two aggregate functions. 498 | 499 | This query calculates the sum of the orders, for products with 500 | prices less than $5.00, for each type of product. 501 | */ 502 | 503 | SELECT ProductID, LineTotal 504 | FROM Sales.SalesOrderDetail 505 | WHERE UnitPrice < $5.00 506 | ORDER BY ProductID, LineTotal 507 | COMPUTE SUM(LineTotal) BY ProductID; 508 | GO 509 | 510 | /* 511 | This query retrieves the product type and order total for 512 | products with unit prices under $5.00. The COMPUTE BY 513 | clause uses two different aggregate functions. 514 | */ 515 | 516 | SELECT ProductID, LineTotal 517 | FROM Sales.SalesOrderDetail 518 | WHERE UnitPrice < $5.00 519 | ORDER BY ProductID, LineTotal 520 | COMPUTE SUM(LineTotal), MAX(LineTotal) BY ProductID; 521 | GO 522 | 523 | ----Query---- 524 | 525 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 526 | O. Calculating grand values by using COMPUTE without BY 527 | The COMPUTE keyword can be used without BY to generate grand 528 | totals, grand counts, and so on. 529 | 530 | The following example finds the grand total of the prices and 531 | advances for all types of products les than $2.00. 532 | */ 533 | 534 | SELECT ProductID, OrderQty, UnitPrice, LineTotal 535 | FROM Sales.SalesOrderDetail 536 | WHERE UnitPrice < $2.00 537 | COMPUTE SUM(OrderQty), SUM(LineTotal); 538 | GO 539 | 540 | /* 541 | You can use COMPUTE BY and COMPUTE without BY in the same query. 542 | The following query finds the sum of order quantities and line 543 | totals by product type, and then computes the grand total of 544 | order quantities and line totals. 545 | */ 546 | 547 | SELECT ProductID, OrderQty, UnitPrice, LineTotal 548 | FROM Sales.SalesOrderDetail 549 | WHERE UnitPrice < $5.00 550 | ORDER BY ProductID 551 | COMPUTE SUM(OrderQty), SUM(LineTotal) BY ProductID 552 | COMPUTE SUM(OrderQty), SUM(LineTotal); 553 | GO 554 | 555 | ----Query---- 556 | 557 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 558 | P. Calculating computed sums on all rows 559 | The following example shows only three columns in the select 560 | list and gives totals based on all order quantities and all line 561 | totals at the end of the results. 562 | */ 563 | 564 | SELECT ProductID, OrderQty, LineTotal 565 | FROM Sales.SalesOrderDetail 566 | COMPUTE SUM(OrderQty), SUM(LineTotal); 567 | GO 568 | 569 | ----Query---- 570 | 571 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 572 | Q. Using more than one COMPUTE clause 573 | The following example finds the sum of the prices of all orders 574 | whose unit price is less than $5 organized by product ID and order 575 | quantity, as well as the sum of the prices of all orders less than 576 | $5 organized by product ID only. You can use different aggregate 577 | functions in the same statement by including more than one COMPUTE 578 | BY clause. 579 | */ 580 | 581 | SELECT ProductID, OrderQty, UnitPrice, LineTotal 582 | FROM Sales.SalesOrderDetail 583 | WHERE UnitPrice < $5.00 584 | ORDER BY ProductID, OrderQty, LineTotal 585 | COMPUTE SUM(LineTotal) BY ProductID, OrderQty 586 | COMPUTE SUM(LineTotal) BY ProductID; 587 | GO 588 | 589 | ----Query---- 590 | 591 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 592 | R. Comparing GROUP BY with COMPUTE 593 | The first example that follows uses the COMPUTE clause to 594 | calculate the sum of all orders whose product's unit price 595 | is less than $5.00, by type of product. The second example 596 | produces the same summary information by using only GROUP BY. 597 | */ 598 | 599 | SELECT ProductID, LineTotal 600 | FROM Sales.SalesOrderDetail 601 | WHERE UnitPrice < $5.00 602 | ORDER BY ProductID 603 | COMPUTE SUM(LineTotal) BY ProductID; 604 | GO 605 | 606 | /* 607 | This is the second query that uses GROUP BY. 608 | */ 609 | 610 | SELECT ProductID, SUM(LineTotal) AS Total 611 | FROM Sales.SalesOrderDetail 612 | WHERE UnitPrice < $5.00 613 | GROUP BY ProductID 614 | ORDER BY ProductID; 615 | GO 616 | 617 | ----Query---- 618 | 619 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 620 | S. Using SELECT with GROUP BY, COMPUTE, and ORDER BY clauses 621 | The following example returns only those orders whose unit 622 | price is less than $5, and then computes the line total sum 623 | by product and the grand total. All computed columns appear 624 | within the select list. 625 | */ 626 | 627 | SELECT ProductID, OrderQty, SUM(LineTotal) AS Total 628 | FROM Sales.SalesOrderDetail 629 | WHERE UnitPrice < $5.00 630 | GROUP BY ProductID, OrderQty 631 | ORDER BY ProductID, OrderQty 632 | COMPUTE SUM(SUM(LineTotal)) BY ProductID, OrderQty 633 | COMPUTE SUM(SUM(LineTotal)); 634 | GO 635 | 636 | ----Query---- 637 | 638 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 639 | T. Using the INDEX optimizer hint 640 | The following example shows two ways to use the INDEX 641 | optimizer hint. The first example shows how to force the 642 | optimizer to use a nonclustered index to retrieve rows from 643 | a table, and the second example forces a table scan by using 644 | an index of 0. 645 | */ 646 | 647 | SELECT pp.FirstName, pp.LastName, e.NationalIDNumber 648 | FROM HumanResources.Employee AS e WITH (INDEX(AK_Employee_NationalIDNumber)) 649 | JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityID 650 | WHERE LastName = 'Johnson'; 651 | GO 652 | 653 | -- Force a table scan by using INDEX = 0. 654 | SELECT pp.LastName, pp.FirstName, e.JobTitle 655 | FROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS pp 656 | ON e.BusinessEntityID = pp.BusinessEntityID 657 | WHERE LastName = 'Johnson'; 658 | GO 659 | 660 | ----Query---- 661 | 662 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 663 | U. Using OPTION and the GROUP hints 664 | The following example shows how the OPTION (GROUP) clause 665 | is used with a GROUP BY clause. 666 | */ 667 | 668 | SELECT ProductID, OrderQty, SUM(LineTotal) AS Total 669 | FROM Sales.SalesOrderDetail 670 | WHERE UnitPrice < $5.00 671 | GROUP BY ProductID, OrderQty 672 | ORDER BY ProductID, OrderQty 673 | OPTION (HASH GROUP, FAST 10); 674 | GO 675 | 676 | ----Query---- 677 | 678 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 679 | V. Using the UNION query hint 680 | The following example uses the MERGE UNION query hint. 681 | */ 682 | 683 | SELECT * 684 | FROM HumanResources.Employee AS e1 685 | UNION 686 | SELECT * 687 | FROM HumanResources.Employee AS e2 688 | OPTION (MERGE UNION); 689 | GO 690 | 691 | ----Query---- 692 | 693 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 694 | W. Using a simple UNION 695 | In the following example, the result set includes the contents 696 | of the ProductModelID and Name columns of both the ProductModel 697 | and Gloves tables. 698 | */ 699 | 700 | -- Here is the simple union. 701 | SELECT ProductModelID, Name 702 | FROM Production.ProductModel 703 | WHERE ProductModelID NOT IN (3, 4) 704 | UNION 705 | SELECT ProductModelID, Name 706 | FROM dbo.Gloves 707 | ORDER BY Name; 708 | GO 709 | 710 | ----Query---- 711 | 712 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 713 | X. Using SELECT INTO with UNION 714 | In the following example, the INTO clause in the second SELECT 715 | statement specifies that the table named ProductResults holds 716 | the final result set of the union of the designated columns 717 | of the ProductModel and Gloves tables. Note that the Gloves 718 | table is created in the first SELECT statement. 719 | */ 720 | 721 | IF OBJECT_ID ('dbo.ProductResults', 'U') IS NOT NULL 722 | DROP TABLE dbo.ProductResults; 723 | GO 724 | 725 | SELECT ProductModelID, Name 726 | INTO dbo.ProductResults 727 | FROM Production.ProductModel 728 | WHERE ProductModelID NOT IN (3, 4) 729 | UNION 730 | SELECT ProductModelID, Name 731 | FROM dbo.Gloves; 732 | GO 733 | 734 | SELECT * 735 | FROM dbo.ProductResults; 736 | 737 | ----Query---- 738 | 739 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 740 | Y. Using UNION of two SELECT statements with ORDER BY 741 | The order of certain parameters used with the UNION clause 742 | is important. The following example shows the incorrect and 743 | correct use of UNION in two SELECT statements in which a 744 | column is to be renamed in the output. 745 | */ 746 | 747 | SELECT ProductModelID, Name 748 | FROM Production.ProductModel 749 | WHERE ProductModelID NOT IN (3, 4) 750 | UNION 751 | SELECT ProductModelID, Name 752 | FROM dbo.Gloves 753 | ORDER BY Name; 754 | GO 755 | 756 | 757 | ----Query---- 758 | 759 | 760 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 761 | Z. Using UNION of three SELECT statements to show the 762 | effects of ALL and parentheses 763 | The following examples use UNION to combine the results 764 | of three tables that all have the same 5 rows of data. 765 | The first example uses UNION ALL to show the duplicated 766 | records, and returns all 15 rows. The second example uses 767 | UNION without ALL to eliminate the duplicate rows from the 768 | combined results of the three SELECT statements, and 769 | returns 5 rows. The third example uses ALL with the first 770 | UNION and parentheses enclose the second UNION that is not 771 | using ALL. The second UNION is processed first because it 772 | is in parentheses, and returns 5 rows because the ALL option 773 | is not used and the duplicates are removed. These 5 rows are 774 | combined with the results of the first SELECT by using the 775 | UNION ALL keywords. This does not remove the duplicates 776 | between the two sets of 5 rows. The final result has 10 rows. 777 | */ 778 | 779 | 780 | -- Union ALL 781 | SELECT LastName, FirstName, JobTitle 782 | FROM dbo.EmployeeOne 783 | UNION ALL 784 | SELECT LastName, FirstName ,JobTitle 785 | FROM dbo.EmployeeTwo 786 | UNION ALL 787 | SELECT LastName, FirstName,JobTitle 788 | FROM dbo.EmployeeThree; 789 | GO 790 | 791 | SELECT LastName, FirstName,JobTitle 792 | FROM dbo.EmployeeOne 793 | UNION 794 | SELECT LastName, FirstName, JobTitle 795 | FROM dbo.EmployeeTwo 796 | UNION 797 | SELECT LastName, FirstName, JobTitle 798 | FROM dbo.EmployeeThree; 799 | GO 800 | 801 | SELECT LastName, FirstName,JobTitle 802 | FROM dbo.EmployeeOne 803 | UNION ALL 804 | ( 805 | SELECT LastName, FirstName, JobTitle 806 | FROM dbo.EmployeeTwo 807 | UNION 808 | SELECT LastName, FirstName, JobTitle 809 | FROM dbo.EmployeeThree 810 | ); 811 | GO 812 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorks2008R2BOLWorkload_Setup.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Setup 3 | *******************************************************************************/ 4 | 5 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 6 | W. Using a simple UNION 7 | In the following example, the result set includes the contents 8 | of the ProductModelID and Name columns of both the ProductModel 9 | and Gloves tables. 10 | */ 11 | 12 | USE AdventureWorks2008R2; 13 | GO 14 | IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL 15 | DROP TABLE dbo.Gloves; 16 | GO 17 | -- Create Gloves table. 18 | SELECT ProductModelID, Name 19 | INTO dbo.Gloves 20 | FROM Production.ProductModel 21 | WHERE ProductModelID IN (3, 4); 22 | GO 23 | 24 | /* http://msdn.microsoft.com/en-us/library/ms187731.aspx 25 | Z. Using UNION of three SELECT statements to show the 26 | effects of ALL and parentheses 27 | The following examples use UNION to combine the results 28 | of three tables that all have the same 5 rows of data. 29 | The first example uses UNION ALL to show the duplicated 30 | records, and returns all 15 rows. The second example uses 31 | UNION without ALL to eliminate the duplicate rows from the 32 | combined results of the three SELECT statements, and 33 | returns 5 rows. The third example uses ALL with the first 34 | UNION and parentheses enclose the second UNION that is not 35 | using ALL. The second UNION is processed first because it 36 | is in parentheses, and returns 5 rows because the ALL option 37 | is not used and the duplicates are removed. These 5 rows are 38 | combined with the results of the first SELECT by using the 39 | UNION ALL keywords. This does not remove the duplicates 40 | between the two sets of 5 rows. The final result has 10 rows. 41 | */ 42 | 43 | USE AdventureWorks2008R2; 44 | GO 45 | IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULL 46 | DROP TABLE dbo.EmployeeOne; 47 | GO 48 | IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULL 49 | DROP TABLE dbo.EmployeeTwo; 50 | GO 51 | IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULL 52 | DROP TABLE dbo.EmployeeThree; 53 | GO 54 | 55 | SELECT pp.LastName, pp.FirstName, e.JobTitle 56 | INTO dbo.EmployeeOne 57 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 58 | ON e.BusinessEntityID = pp.BusinessEntityID 59 | WHERE LastName = 'Johnson'; 60 | GO 61 | SELECT pp.LastName, pp.FirstName, e.JobTitle 62 | INTO dbo.EmployeeTwo 63 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 64 | ON e.BusinessEntityID = pp.BusinessEntityID 65 | WHERE LastName = 'Johnson'; 66 | GO 67 | SELECT pp.LastName, pp.FirstName, e.JobTitle 68 | INTO dbo.EmployeeThree 69 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 70 | ON e.BusinessEntityID = pp.BusinessEntityID 71 | WHERE LastName = 'Johnson'; 72 | GO 73 | 74 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorks2012BOLWorkload.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Scripts from http://msdn.microsoft.com/en-us/library/ms187731%28v=sql.110%29.aspx 3 | *******************************************************************************/ 4 | 5 | ----Query---- 6 | SELECT * 7 | FROM Production.Product 8 | ORDER BY Name ASC; 9 | 10 | ----Query---- 11 | SELECT p.* 12 | FROM Production.Product AS p 13 | ORDER BY Name ASC; 14 | 15 | ----Query---- 16 | SELECT Name, ProductNumber, ListPrice AS Price 17 | FROM Production.Product 18 | ORDER BY Name ASC; 19 | 20 | ----Query---- 21 | SELECT Name, ProductNumber, ListPrice AS Price 22 | FROM Production.Product 23 | WHERE ProductLine = 'R' 24 | AND DaysToManufacture < 4 25 | ORDER BY Name ASC; 26 | 27 | ----Query---- 28 | SELECT p.Name AS ProductName, 29 | NonDiscountSales = (OrderQty * UnitPrice), 30 | Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount) 31 | FROM Production.Product AS p 32 | INNER JOIN Sales.SalesOrderDetail AS sod 33 | ON p.ProductID = sod.ProductID 34 | ORDER BY ProductName DESC; 35 | 36 | ----Query---- 37 | SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ', 38 | p.Name AS ProductName 39 | FROM Production.Product AS p 40 | INNER JOIN Sales.SalesOrderDetail AS sod 41 | ON p.ProductID = sod.ProductID 42 | ORDER BY ProductName ASC; 43 | 44 | ----Query---- 45 | SELECT DISTINCT JobTitle 46 | FROM HumanResources.Employee 47 | ORDER BY JobTitle; 48 | 49 | ----Query---- 50 | USE tempdb; 51 | GO 52 | IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL 53 | DROP TABLE #Bicycles; 54 | GO 55 | SELECT * 56 | INTO #Bicycles 57 | FROM Production.Product 58 | WHERE ProductNumber LIKE 'BK%'; 59 | 60 | ----Query---- 61 | SELECT DISTINCT Name 62 | FROM Production.Product AS p 63 | WHERE EXISTS 64 | (SELECT * 65 | FROM Production.ProductModel AS pm 66 | WHERE p.ProductModelID = pm.ProductModelID 67 | AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'); 68 | 69 | ----Query---- 70 | 71 | SELECT DISTINCT Name 72 | FROM Production.Product 73 | WHERE ProductModelID IN 74 | (SELECT ProductModelID 75 | FROM Production.ProductModel 76 | WHERE Name LIKE 'Long-Sleeve Logo Jersey%'); 77 | 78 | ----Query---- 79 | SELECT DISTINCT p.LastName, p.FirstName 80 | FROM Person.Person AS p 81 | JOIN HumanResources.Employee AS e 82 | ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN 83 | (SELECT Bonus 84 | FROM Sales.SalesPerson AS sp 85 | WHERE e.BusinessEntityID = sp.BusinessEntityID); 86 | 87 | ----Query---- 88 | SELECT p1.ProductModelID 89 | FROM Production.Product AS p1 90 | GROUP BY p1.ProductModelID 91 | HAVING MAX(p1.ListPrice) >= ALL 92 | (SELECT AVG(p2.ListPrice) 93 | FROM Production.Product AS p2 94 | WHERE p1.ProductModelID = p2.ProductModelID); 95 | 96 | ----Query---- 97 | SELECT DISTINCT pp.LastName, pp.FirstName 98 | FROM Person.Person pp JOIN HumanResources.Employee e 99 | ON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN 100 | (SELECT SalesPersonID 101 | FROM Sales.SalesOrderHeader 102 | WHERE SalesOrderID IN 103 | (SELECT SalesOrderID 104 | FROM Sales.SalesOrderDetail 105 | WHERE ProductID IN 106 | (SELECT ProductID 107 | FROM Production.Product p 108 | WHERE ProductNumber = 'BK-M68B-42'))); 109 | 110 | ----Query---- 111 | SELECT SalesOrderID, SUM(LineTotal) AS SubTotal 112 | FROM Sales.SalesOrderDetail 113 | GROUP BY SalesOrderID 114 | ORDER BY SalesOrderID; 115 | 116 | ----Query---- 117 | SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price], 118 | SUM(LineTotal) AS SubTotal 119 | FROM Sales.SalesOrderDetail 120 | GROUP BY ProductID, SpecialOfferID 121 | ORDER BY ProductID; 122 | 123 | ----Query---- 124 | SELECT ProductModelID, AVG(ListPrice) AS [Average List Price] 125 | FROM Production.Product 126 | WHERE ListPrice > $1000 127 | GROUP BY ProductModelID 128 | ORDER BY ProductModelID; 129 | 130 | ----Query---- 131 | SELECT AVG(OrderQty) AS [Average Quantity], 132 | NonDiscountSales = (OrderQty * UnitPrice) 133 | FROM Sales.SalesOrderDetail 134 | GROUP BY (OrderQty * UnitPrice) 135 | ORDER BY (OrderQty * UnitPrice) DESC; 136 | 137 | ----Query---- 138 | SELECT ProductID, AVG(UnitPrice) AS [Average Price] 139 | FROM Sales.SalesOrderDetail 140 | WHERE OrderQty > 10 141 | GROUP BY ProductID 142 | ORDER BY AVG(UnitPrice); 143 | 144 | ----Query---- 145 | SELECT ProductID 146 | FROM Sales.SalesOrderDetail 147 | GROUP BY ProductID 148 | HAVING AVG(OrderQty) > 5 149 | ORDER BY ProductID; 150 | 151 | ----Query---- 152 | SELECT SalesOrderID, CarrierTrackingNumber 153 | FROM Sales.SalesOrderDetail 154 | GROUP BY SalesOrderID, CarrierTrackingNumber 155 | HAVING CarrierTrackingNumber LIKE '4BD%' 156 | ORDER BY SalesOrderID ; 157 | 158 | ----Query---- 159 | SELECT ProductID 160 | FROM Sales.SalesOrderDetail 161 | WHERE UnitPrice < 25.00 162 | GROUP BY ProductID 163 | HAVING AVG(OrderQty) > 5 164 | ORDER BY ProductID; 165 | 166 | ----Query---- 167 | SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total 168 | FROM Sales.SalesOrderDetail 169 | GROUP BY ProductID 170 | HAVING SUM(LineTotal) > $1000000.00 171 | AND AVG(OrderQty) < 3; 172 | 173 | ----Query---- 174 | SELECT ProductID, Total = SUM(LineTotal) 175 | FROM Sales.SalesOrderDetail 176 | GROUP BY ProductID 177 | HAVING SUM(LineTotal) > $2000000.00; 178 | 179 | ----Query---- 180 | SELECT ProductID, SUM(LineTotal) AS Total 181 | FROM Sales.SalesOrderDetail 182 | GROUP BY ProductID 183 | HAVING COUNT(*) > 1500; 184 | 185 | ----Query---- 186 | SELECT pp.FirstName, pp.LastName, e.NationalIDNumber 187 | FROM HumanResources.Employee AS e WITH (INDEX(AK_Employee_NationalIDNumber)) 188 | JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityID 189 | WHERE LastName = 'Johnson'; 190 | 191 | ----Query---- 192 | -- Force a table scan by using INDEX = 0. 193 | SELECT pp.LastName, pp.FirstName, e.JobTitle 194 | FROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS pp 195 | ON e.BusinessEntityID = pp.BusinessEntityID 196 | WHERE LastName = 'Johnson'; 197 | 198 | ----Query---- 199 | SELECT ProductID, OrderQty, SUM(LineTotal) AS Total 200 | FROM Sales.SalesOrderDetail 201 | WHERE UnitPrice < $5.00 202 | GROUP BY ProductID, OrderQty 203 | ORDER BY ProductID, OrderQty 204 | OPTION (HASH GROUP, FAST 10); 205 | 206 | ----Query---- 207 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 208 | FROM HumanResources.Employee AS e1 209 | UNION 210 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 211 | FROM HumanResources.Employee AS e2 212 | OPTION (MERGE UNION); 213 | 214 | ----Query---- 215 | -- Here is the simple union. 216 | SELECT ProductModelID, Name 217 | FROM Production.ProductModel 218 | WHERE ProductModelID NOT IN (3, 4) 219 | UNION 220 | SELECT ProductModelID, Name 221 | FROM dbo.Gloves 222 | ORDER BY Name; 223 | 224 | ----Query---- 225 | SELECT ProductModelID, Name 226 | FROM dbo.ProductResults; 227 | 228 | ----Query---- 229 | /* Union */ 230 | SELECT ProductModelID, Name 231 | FROM Production.ProductModel 232 | WHERE ProductModelID NOT IN (3, 4) 233 | UNION 234 | SELECT ProductModelID, Name 235 | FROM dbo.Gloves 236 | ORDER BY Name; 237 | 238 | ----Query---- 239 | -- Union ALL 240 | SELECT LastName, FirstName, JobTitle 241 | FROM dbo.EmployeeOne 242 | UNION ALL 243 | SELECT LastName, FirstName ,JobTitle 244 | FROM dbo.EmployeeTwo 245 | UNION ALL 246 | SELECT LastName, FirstName,JobTitle 247 | FROM dbo.EmployeeThree; 248 | 249 | ----Query---- 250 | -- Union ALL 2 251 | SELECT LastName, FirstName,JobTitle 252 | FROM dbo.EmployeeOne 253 | UNION 254 | SELECT LastName, FirstName, JobTitle 255 | FROM dbo.EmployeeTwo 256 | UNION 257 | SELECT LastName, FirstName, JobTitle 258 | FROM dbo.EmployeeThree; 259 | 260 | ----Query---- 261 | -- Union ALL 3 262 | SELECT LastName, FirstName,JobTitle 263 | FROM dbo.EmployeeOne 264 | UNION ALL 265 | ( 266 | SELECT LastName, FirstName, JobTitle 267 | FROM dbo.EmployeeTwo 268 | UNION 269 | SELECT LastName, FirstName, JobTitle 270 | FROM dbo.EmployeeThree 271 | ); 272 | 273 | 274 | ----Query---- 275 | /******************************************************************************* 276 | Scripts from http://msdn.microsoft.com/en-us/library/bb510625.aspx 277 | *******************************************************************************/ 278 | 279 | ----Query---- 280 | -- Test the procedure 281 | EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'New Test Value'; 282 | EXEC InsertUnitMeasure @UnitMeasureCode = 'XYZ', @Name = 'Test Value'; 283 | EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Another Test Value'; 284 | 285 | -- Cleanup 286 | DELETE FROM Production.UnitMeasure WHERE UnitMeasureCode IN ('ABC','XYZ'); 287 | 288 | 289 | ----Query---- 290 | EXECUTE Production.usp_UpdateInventory '20030501' 291 | 292 | ----Query---- 293 | -- Create a temporary table variable to hold the output actions. 294 | DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20)); 295 | 296 | MERGE INTO Sales.SalesReason AS Target 297 | USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion')) 298 | AS Source (NewName, NewReasonType) 299 | ON Target.Name = Source.NewName 300 | WHEN MATCHED THEN 301 | UPDATE SET ReasonType = Source.NewReasonType 302 | WHEN NOT MATCHED BY TARGET THEN 303 | INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) 304 | OUTPUT $action INTO @SummaryOfChanges; 305 | 306 | -- Query the results of the table variable. 307 | SELECT Change, COUNT(*) AS CountPerChange 308 | FROM @SummaryOfChanges 309 | GROUP BY Change; 310 | 311 | ----Query---- 312 | INSERT INTO Production.UpdatedInventory 313 | SELECT ProductID, LocationID, NewQty, PreviousQty 314 | FROM 315 | ( MERGE Production.ProductInventory AS pi 316 | USING (SELECT ProductID, SUM(OrderQty) 317 | FROM Sales.SalesOrderDetail AS sod 318 | JOIN Sales.SalesOrderHeader AS soh 319 | ON sod.SalesOrderID = soh.SalesOrderID 320 | AND soh.OrderDate BETWEEN '20030701' AND '20030731' 321 | GROUP BY ProductID) AS src (ProductID, OrderQty) 322 | ON pi.ProductID = src.ProductID 323 | WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0 324 | THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty 325 | WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0 326 | THEN DELETE 327 | OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty) 328 | AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'UPDATE'; 329 | 330 | 331 | 332 | 333 | 334 | /******************************************************************************* 335 | Scripts from http://msdn.microsoft.com/en-us/library/ms174335.aspx 336 | *******************************************************************************/ 337 | 338 | ----Query---- 339 | INSERT INTO Production.UnitMeasure 340 | VALUES (N'FT', N'Feet', '20080414'); 341 | 342 | ----Query---- 343 | INSERT INTO Production.UnitMeasure 344 | VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'), (N'Y3', N'Cubic Yards', '20080923'); 345 | 346 | ----Query---- 347 | INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, 348 | ModifiedDate) 349 | VALUES (N'Square Yards', N'Y2', GETDATE()); 350 | 351 | ----Query---- 352 | INSERT INTO dbo.T1 (column_4) 353 | VALUES ('Explicit value'); 354 | INSERT INTO dbo.T1 (column_2, column_4) 355 | VALUES ('Explicit value', 'Explicit value'); 356 | INSERT INTO dbo.T1 (column_2) 357 | VALUES ('Explicit value'); 358 | INSERT INTO T1 DEFAULT VALUES; 359 | SELECT column_1, column_2, column_3, column_4 360 | FROM dbo.T1; 361 | 362 | ----Query---- 363 | INSERT T1 VALUES ('Row #1'); 364 | INSERT T1 (column_2) VALUES ('Row #2'); 365 | SET IDENTITY_INSERT T1 ON; 366 | INSERT INTO T1 (column_1,column_2) 367 | VALUES (-99, 'Explicit identity value'); 368 | SELECT column_1, column_2 369 | FROM T1; 370 | 371 | ----Query---- 372 | INSERT INTO dbo.T1 (column_2) 373 | VALUES (NEWID()); 374 | INSERT INTO T1 DEFAULT VALUES; 375 | SELECT column_1, column_2 376 | FROM dbo.T1; 377 | 378 | ----Query---- 379 | --INSERT...SELECT example 380 | INSERT INTO dbo.EmployeeSales 381 | SELECT 'SELECT', sp.BusinessEntityID, c.LastName, sp.SalesYTD 382 | FROM Sales.SalesPerson AS sp 383 | INNER JOIN Person.Person AS c 384 | ON sp.BusinessEntityID = c.BusinessEntityID 385 | WHERE sp.BusinessEntityID LIKE '2%' 386 | ORDER BY sp.BusinessEntityID, c.LastName; 387 | --INSERT...EXECUTE procedure example 388 | INSERT INTO dbo.EmployeeSales 389 | EXECUTE dbo.uspGetEmployeeSales; 390 | --INSERT...EXECUTE('string') example 391 | INSERT INTO dbo.EmployeeSales 392 | EXECUTE 393 | (' 394 | SELECT ''EXEC STRING'', sp.BusinessEntityID, c.LastName, 395 | sp.SalesYTD 396 | FROM Sales.SalesPerson AS sp 397 | INNER JOIN Person.Person AS c 398 | ON sp.BusinessEntityID = c.BusinessEntityID 399 | WHERE sp.BusinessEntityID LIKE ''2%'' 400 | ORDER BY sp.BusinessEntityID, c.LastName 401 | '); 402 | --Show results. 403 | SELECT DataSource,BusinessEntityID,LastName,SalesDollars 404 | FROM dbo.EmployeeSales; 405 | 406 | ----Query---- 407 | WITH EmployeeTemp (EmpID, LastName, FirstName, Phone, 408 | Address, City, StateProvince, 409 | PostalCode, CurrentFlag) 410 | AS (SELECT 411 | e.BusinessEntityID, c.LastName, c.FirstName, pp.PhoneNumber, 412 | a.AddressLine1, a.City, sp.StateProvinceCode, 413 | a.PostalCode, e.CurrentFlag 414 | FROM HumanResources.Employee e 415 | INNER JOIN Person.BusinessEntityAddress AS bea 416 | ON e.BusinessEntityID = bea.BusinessEntityID 417 | INNER JOIN Person.Address AS a 418 | ON bea.AddressID = a.AddressID 419 | INNER JOIN Person.PersonPhone AS pp 420 | ON e.BusinessEntityID = pp.BusinessEntityID 421 | INNER JOIN Person.StateProvince AS sp 422 | ON a.StateProvinceID = sp.StateProvinceID 423 | INNER JOIN Person.Person as c 424 | ON e.BusinessEntityID = c.BusinessEntityID 425 | ) 426 | INSERT INTO HumanResources.NewEmployee 427 | SELECT EmpID, LastName, FirstName, Phone, 428 | Address, City, StateProvince, PostalCode, CurrentFlag 429 | FROM EmployeeTemp; 430 | 431 | ----Query---- 432 | INSERT TOP(5)INTO dbo.EmployeeSales 433 | OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales 434 | SELECT sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 435 | FROM Sales.SalesPerson AS sp 436 | INNER JOIN Person.Person AS c 437 | ON sp.BusinessEntityID = c.BusinessEntityID 438 | WHERE sp.SalesYTD > 250000.00 439 | ORDER BY sp.SalesYTD DESC; 440 | 441 | ----Query---- 442 | INSERT INTO dbo.EmployeeSales 443 | OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales 444 | SELECT TOP (5) sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 445 | FROM Sales.SalesPerson AS sp 446 | INNER JOIN Person.Person AS c 447 | ON sp.BusinessEntityID = c.BusinessEntityID 448 | WHERE sp.SalesYTD > 250000.00 449 | ORDER BY sp.SalesYTD DESC; 450 | 451 | ----Query---- 452 | INSERT INTO V1 453 | VALUES ('Row 1',1); 454 | SELECT column_1, column_2 455 | FROM T1; 456 | SELECT column_1, column_2 457 | FROM V1; 458 | 459 | ----Query---- 460 | -- Create the table variable. 461 | DECLARE @MyTableVar table( 462 | LocationID int NOT NULL, 463 | CostRate smallmoney NOT NULL, 464 | NewCostRate AS CostRate * 1.5, 465 | ModifiedDate datetime); 466 | 467 | -- Insert values into the table variable. 468 | INSERT INTO @MyTableVar (LocationID, CostRate, ModifiedDate) 469 | SELECT LocationID, CostRate, GETDATE() FROM Production.Location 470 | WHERE CostRate > 0; 471 | 472 | -- View the table variable result set. 473 | SELECT * FROM @MyTableVar; 474 | 475 | 476 | 477 | 478 | /******************************************************************************* 479 | Scripts from http://msdn.microsoft.com/en-us/library/ms177523.aspx 480 | *******************************************************************************/ 481 | 482 | ----Query---- 483 | UPDATE Person.Address 484 | SET ModifiedDate = GETDATE(); 485 | 486 | ----Query---- 487 | UPDATE Sales.SalesPerson 488 | SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL; 489 | 490 | ----Query---- 491 | UPDATE Production.Product 492 | SET Color = N'Metallic Red' 493 | WHERE Name LIKE N'Road-250%' AND Color = N'Red'; 494 | 495 | ----Query---- 496 | UPDATE TOP (10) HumanResources.Employee 497 | SET VacationHours = VacationHours * 1.25 ; 498 | 499 | ----Query---- 500 | UPDATE HumanResources.Employee 501 | SET VacationHours = VacationHours + 8 502 | FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee 503 | ORDER BY HireDate ASC) AS th 504 | WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID; 505 | 506 | ----Query---- 507 | WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS 508 | ( 509 | SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty, 510 | b.EndDate, 0 AS ComponentLevel 511 | FROM Production.BillOfMaterials AS b 512 | WHERE b.ProductAssemblyID = 800 513 | AND b.EndDate IS NULL 514 | UNION ALL 515 | SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty, 516 | bom.EndDate, ComponentLevel + 1 517 | FROM Production.BillOfMaterials AS bom 518 | INNER JOIN Parts AS p 519 | ON bom.ProductAssemblyID = p.ComponentID 520 | AND bom.EndDate IS NULL 521 | ) 522 | UPDATE Production.BillOfMaterials 523 | SET PerAssemblyQty = c.PerAssemblyQty * 2 524 | FROM Production.BillOfMaterials AS c 525 | JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID 526 | WHERE d.ComponentLevel = 0; 527 | 528 | ----Query---- 529 | DECLARE complex_cursor CURSOR FOR 530 | SELECT a.BusinessEntityID 531 | FROM HumanResources.EmployeePayHistory AS a 532 | WHERE RateChangeDate <> 533 | (SELECT MAX(RateChangeDate) 534 | FROM HumanResources.EmployeePayHistory AS b 535 | WHERE a.BusinessEntityID = b.BusinessEntityID) ; 536 | OPEN complex_cursor; 537 | FETCH FROM complex_cursor; 538 | UPDATE HumanResources.EmployeePayHistory 539 | SET PayFrequency = 2 540 | WHERE CURRENT OF complex_cursor; 541 | CLOSE complex_cursor; 542 | DEALLOCATE complex_cursor; 543 | 544 | ----Query---- 545 | UPDATE Production.Product 546 | SET ListPrice = ListPrice * 2; 547 | 548 | ----Query---- 549 | DECLARE @NewPrice int = 10; 550 | UPDATE Production.Product 551 | SET ListPrice += @NewPrice 552 | WHERE Color = N'Red'; 553 | 554 | ----Query---- 555 | UPDATE Production.ScrapReason 556 | SET Name += ' - tool malfunction' 557 | WHERE ScrapReasonID BETWEEN 10 and 12; 558 | 559 | ----Query---- 560 | UPDATE Sales.SalesPerson 561 | SET SalesYTD = SalesYTD + 562 | (SELECT SUM(so.SubTotal) 563 | FROM Sales.SalesOrderHeader AS so 564 | WHERE so.OrderDate = (SELECT MAX(OrderDate) 565 | FROM Sales.SalesOrderHeader AS so2 566 | WHERE so2.SalesPersonID = so.SalesPersonID) 567 | AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID 568 | GROUP BY so.SalesPersonID); 569 | 570 | ----Query---- 571 | UPDATE Production.Location 572 | SET CostRate = DEFAULT 573 | WHERE CostRate > 20.00; 574 | 575 | ----Query---- 576 | UPDATE Person.vStateProvinceCountryRegion 577 | SET CountryRegionName = 'United States of America' 578 | WHERE CountryRegionName = 'United States'; 579 | 580 | 581 | ----Query---- 582 | UPDATE sr 583 | SET sr.Name += ' - tool malfunction' 584 | FROM Production.ScrapReason AS sr 585 | JOIN Production.WorkOrder AS wo 586 | ON sr.ScrapReasonID = wo.ScrapReasonID 587 | AND wo.ScrappedQty > 300; 588 | 589 | ----Query---- 590 | -- Create the table variable. 591 | DECLARE @MyTableVar table( 592 | EmpID int NOT NULL, 593 | NewVacationHours int, 594 | ModifiedDate datetime); 595 | 596 | -- Populate the table variable with employee ID values from HumanResources.Employee. 597 | INSERT INTO @MyTableVar (EmpID) 598 | SELECT BusinessEntityID FROM HumanResources.Employee; 599 | 600 | -- Update columns in the table variable. 601 | UPDATE @MyTableVar 602 | SET NewVacationHours = e.VacationHours + 20, 603 | ModifiedDate = GETDATE() 604 | FROM HumanResources.Employee AS e 605 | WHERE e.BusinessEntityID = EmpID; 606 | 607 | -- Display the results of the UPDATE statement. 608 | SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar 609 | ORDER BY EmpID; 610 | 611 | ----Query---- 612 | UPDATE Sales.SalesPerson 613 | SET SalesYTD = SalesYTD + SubTotal 614 | FROM Sales.SalesPerson AS sp 615 | JOIN Sales.SalesOrderHeader AS so 616 | ON sp.BusinessEntityID = so.SalesPersonID 617 | AND so.OrderDate = (SELECT MAX(OrderDate) 618 | FROM Sales.SalesOrderHeader 619 | WHERE SalesPersonID = sp.BusinessEntityID); 620 | 621 | ----Query---- 622 | UPDATE Sales.SalesPerson 623 | SET SalesYTD = SalesYTD + 624 | (SELECT SUM(so.SubTotal) 625 | FROM Sales.SalesOrderHeader AS so 626 | WHERE so.OrderDate = (SELECT MAX(OrderDate) 627 | FROM Sales.SalesOrderHeader AS so2 628 | WHERE so2.SalesPersonID = so.SalesPersonID) 629 | AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID 630 | GROUP BY so.SalesPersonID); 631 | 632 | ----Query---- 633 | DECLARE @MyTableVar table ( 634 | SummaryBefore nvarchar(max), 635 | SummaryAfter nvarchar(max)); 636 | UPDATE Production.Document 637 | SET DocumentSummary .WRITE (N'features',28,10) 638 | OUTPUT deleted.DocumentSummary, 639 | inserted.DocumentSummary 640 | INTO @MyTableVar 641 | WHERE Title = N'Front Reflector Bracket Installation'; 642 | SELECT SummaryBefore, SummaryAfter 643 | FROM @MyTableVar; 644 | 645 | ----Query---- 646 | UPDATE Production.Product 647 | WITH (TABLOCK) 648 | SET ListPrice = ListPrice * 1.10 649 | WHERE ProductNumber LIKE 'BK-%'; 650 | 651 | ----Query---- 652 | /*CREATE PROCEDURE Production.uspProductUpdate 653 | @Product nvarchar(25) 654 | AS 655 | SET NOCOUNT ON; 656 | UPDATE Production.Product 657 | SET ListPrice = ListPrice * 1.10 658 | WHERE ProductNumber LIKE @Product 659 | OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); 660 | GO*/ 661 | -- Execute the stored procedure 662 | EXEC Production.uspProductUpdate 'BK-%'; 663 | 664 | ----Query---- 665 | DECLARE @MyTableVar table( 666 | EmpID int NOT NULL, 667 | OldVacationHours int, 668 | NewVacationHours int, 669 | ModifiedDate datetime); 670 | UPDATE TOP (10) HumanResources.Employee 671 | SET VacationHours = VacationHours * 1.25, 672 | ModifiedDate = GETDATE() 673 | OUTPUT inserted.BusinessEntityID, 674 | deleted.VacationHours, 675 | inserted.VacationHours, 676 | inserted.ModifiedDate 677 | INTO @MyTableVar; 678 | --Display the result set of the table variable. 679 | SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate 680 | FROM @MyTableVar; 681 | --Display the result set of the table. 682 | SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate 683 | FROM HumanResources.Employee; 684 | 685 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorks2012BOLWorkload_Setup.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Setup 3 | *******************************************************************************/ 4 | --USE AdventureWorks2012; 5 | --GO 6 | 7 | IF OBJECT_ID ('dbo.Gloves', 'U') IS NULL 8 | BEGIN 9 | -- Create Gloves table. 10 | SELECT ProductModelID, Name 11 | INTO dbo.Gloves 12 | FROM Production.ProductModel 13 | WHERE ProductModelID IN (3, 4); 14 | --DROP TABLE dbo.Gloves; 15 | --GO 16 | END 17 | IF OBJECT_ID ('dbo.ProductResults', 'U') IS NULL 18 | BEGIN 19 | --DROP TABLE dbo.ProductResults; 20 | --GO 21 | SELECT ProductModelID, Name 22 | INTO dbo.ProductResults 23 | FROM Production.ProductModel 24 | WHERE ProductModelID NOT IN (3, 4) 25 | UNION 26 | SELECT ProductModelID, Name 27 | FROM dbo.Gloves; 28 | END 29 | 30 | IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NULL 31 | BEGIN 32 | --DROP TABLE dbo.EmployeeSales; 33 | --GO 34 | CREATE TABLE dbo.EmployeeSales 35 | ( DataSource varchar(20) NOT NULL, 36 | BusinessEntityID varchar(11) NOT NULL, 37 | LastName varchar(40) NOT NULL, 38 | SalesDollars money NOT NULL 39 | ); 40 | END 41 | 42 | 43 | IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NULL 44 | BEGIN 45 | --DROP TABLE dbo.EmployeeOne; 46 | --GO 47 | 48 | SELECT pp.LastName, pp.FirstName, e.JobTitle 49 | INTO dbo.EmployeeOne 50 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 51 | ON e.BusinessEntityID = pp.BusinessEntityID 52 | WHERE LastName = 'Johnson'; 53 | END 54 | IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NULL 55 | BEGIN 56 | --DROP TABLE dbo.EmployeeTwo; 57 | --GO 58 | SELECT pp.LastName, pp.FirstName, e.JobTitle 59 | INTO dbo.EmployeeTwo 60 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 61 | ON e.BusinessEntityID = pp.BusinessEntityID 62 | WHERE LastName = 'Johnson'; 63 | END 64 | IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NULL 65 | BEGIN 66 | --DROP TABLE dbo.EmployeeThree; 67 | --GO 68 | SELECT pp.LastName, pp.FirstName, e.JobTitle 69 | INTO dbo.EmployeeThree 70 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 71 | ON e.BusinessEntityID = pp.BusinessEntityID 72 | WHERE LastName = 'Johnson'; 73 | END 74 | 75 | 76 | 77 | IF OBJECT_ID ('dbo.uspGetEmployeeSales', 'P') IS NOT NULL 78 | DROP PROCEDURE uspGetEmployeeSales; 79 | GO 80 | CREATE PROCEDURE dbo.uspGetEmployeeSales 81 | AS 82 | SET NOCOUNT ON; 83 | SELECT 'PROCEDURE', sp.BusinessEntityID, c.LastName, 84 | sp.SalesYTD 85 | FROM Sales.SalesPerson AS sp 86 | INNER JOIN Person.Person AS c 87 | ON sp.BusinessEntityID = c.BusinessEntityID 88 | WHERE sp.BusinessEntityID LIKE '2%' 89 | ORDER BY sp.BusinessEntityID, c.LastName; 90 | GO 91 | 92 | IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL 93 | DROP TABLE HumanResources.NewEmployee; 94 | GO 95 | CREATE TABLE HumanResources.NewEmployee 96 | ( 97 | EmployeeID int NOT NULL, 98 | LastName nvarchar(50) NOT NULL, 99 | FirstName nvarchar(50) NOT NULL, 100 | PhoneNumber Phone NULL, 101 | AddressLine1 nvarchar(60) NOT NULL, 102 | City nvarchar(30) NOT NULL, 103 | State nchar(3) NOT NULL, 104 | PostalCode nvarchar(15) NOT NULL, 105 | CurrentFlag Flag 106 | ); 107 | GO 108 | 109 | IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL 110 | DROP TABLE dbo.EmployeeSales; 111 | GO 112 | CREATE TABLE dbo.EmployeeSales 113 | ( EmployeeID nvarchar(11) NOT NULL, 114 | LastName nvarchar(20) NOT NULL, 115 | FirstName nvarchar(20) NOT NULL, 116 | YearlySales money NOT NULL 117 | ); 118 | GO 119 | 120 | 121 | IF OBJECT_ID ('dbo.T1', 'U') IS NULL 122 | BEGIN 123 | --DROP TABLE dbo.T1; 124 | --GO 125 | CREATE TABLE dbo.T1 126 | ( 127 | column_1 int IDENTITY, 128 | column_2 uniqueidentifier, 129 | ); 130 | END 131 | 132 | IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL 133 | DROP TABLE dbo.T1; 134 | GO 135 | IF OBJECT_ID ('dbo.V1', 'V') IS NOT NULL 136 | DROP VIEW dbo.V1; 137 | GO 138 | CREATE TABLE T1 ( column_1 int, column_2 varchar(30)); 139 | GO 140 | CREATE VIEW V1 AS 141 | SELECT column_2, column_1 142 | FROM T1; 143 | GO 144 | 145 | IF OBJECT_ID ('Production.uspProductUpdate', 'P') IS NOT NULL 146 | DROP PROCEDURE Production.uspProductUpdate; 147 | GO 148 | CREATE PROCEDURE Production.uspProductUpdate 149 | @Product nvarchar(25) 150 | AS 151 | SET NOCOUNT ON; 152 | UPDATE Production.Product 153 | SET ListPrice = ListPrice * 1.10 154 | WHERE ProductNumber LIKE @Product 155 | OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); 156 | 157 | 158 | -- Rewrite the procedure to perform the same operations using the MERGE statement. 159 | -- Create a temporary table to hold the updated or inserted values from the OUTPUT clause. 160 | IF OBJECT_ID ('dbo.InsertUnitMeasure', 'P') IS NOT NULL 161 | BEGIN 162 | DROP PROCEDURE dbo.InsertUnitMeasure; 163 | END 164 | GO 165 | CREATE PROCEDURE dbo.InsertUnitMeasure 166 | @UnitMeasureCode nchar(3), 167 | @Name nvarchar(25) 168 | AS 169 | BEGIN 170 | SET NOCOUNT ON; 171 | 172 | CREATE TABLE #MyTempTable 173 | (ExistingCode nchar(3), 174 | ExistingName nvarchar(50), 175 | ExistingDate datetime, 176 | ActionTaken nvarchar(10), 177 | NewCode nchar(3), 178 | NewName nvarchar(50), 179 | NewDate datetime 180 | ); 181 | 182 | MERGE Production.UnitMeasure AS target 183 | USING (SELECT @UnitMeasureCode, @Name) AS source (UnitMeasureCode, Name) 184 | ON (target.UnitMeasureCode = source.UnitMeasureCode) 185 | WHEN MATCHED THEN 186 | UPDATE SET Name = source.Name 187 | WHEN NOT MATCHED THEN 188 | INSERT (UnitMeasureCode, Name) 189 | VALUES (source.UnitMeasureCode, source.Name) 190 | OUTPUT deleted.*, $action, inserted.* INTO #MyTempTable; 191 | 192 | SELECT * FROM #MyTempTable; 193 | 194 | DROP TABLE #MyTempTable; 195 | 196 | END; 197 | GO 198 | 199 | 200 | IF OBJECT_ID (N'Production.usp_UpdateInventory', N'P') IS NOT NULL DROP PROCEDURE Production.usp_UpdateInventory; 201 | GO 202 | CREATE PROCEDURE Production.usp_UpdateInventory 203 | @OrderDate datetime 204 | AS 205 | MERGE Production.ProductInventory AS target 206 | USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod 207 | JOIN Sales.SalesOrderHeader AS soh 208 | ON sod.SalesOrderID = soh.SalesOrderID 209 | AND soh.OrderDate = @OrderDate 210 | GROUP BY ProductID) AS source (ProductID, OrderQty) 211 | ON (target.ProductID = source.ProductID) 212 | WHEN MATCHED AND target.Quantity - source.OrderQty <= 0 213 | THEN DELETE 214 | WHEN MATCHED 215 | THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty, 216 | target.ModifiedDate = GETDATE() 217 | OUTPUT $action, Inserted.ProductID, Inserted.Quantity, Inserted.ModifiedDate, Deleted.ProductID, 218 | Deleted.Quantity, Deleted.ModifiedDate; 219 | GO 220 | 221 | IF OBJECT_ID ('Production.UpdatedInventory', 'U') IS NULL 222 | BEGIN 223 | --DROP TABLE Production.UpdatedInventory; 224 | --GO 225 | CREATE TABLE Production.UpdatedInventory 226 | (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int, 227 | CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID)); 228 | END 229 | 230 | IF OBJECT_ID ('dbo.T1', 'U') IS NULL 231 | BEGIN 232 | --DROP TABLE dbo.T1; 233 | --GO 234 | CREATE TABLE dbo.T1 235 | ( 236 | column_1 AS 'Computed column ' + column_2, 237 | column_2 varchar(30) 238 | CONSTRAINT default_name DEFAULT ('my column default'), 239 | column_3 rowversion, 240 | column_4 varchar(40) NULL 241 | ); 242 | END 243 | 244 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorksAzureBOLWorkload.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Scripts adapted from http://msdn.microsoft.com/en-us/library/ms187731%28v=sql.110%29.aspx 3 | *******************************************************************************/ 4 | 5 | ----Query---- 6 | SELECT * 7 | FROM SalesLT.Product 8 | ORDER BY Name ASC; 9 | 10 | ----Query---- 11 | SELECT p.* 12 | FROM SalesLT.Product AS p 13 | ORDER BY Name ASC; 14 | 15 | ----Query---- 16 | SELECT Name, ProductNumber, ListPrice AS Price 17 | FROM SalesLT.Product 18 | ORDER BY Name ASC; 19 | 20 | ----Query---- 21 | SELECT Name, ProductNumber, ListPrice AS Price 22 | FROM SalesLT.Product 23 | WHERE ProductLine = 'R' 24 | AND DaysToManufacture < 4 25 | ORDER BY Name ASC; 26 | 27 | ----Query---- 28 | SELECT p.Name AS ProductName, 29 | NonDiscountSales = (OrderQty * UnitPrice), 30 | Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount) 31 | FROM SalesLT.Product AS p 32 | INNER JOIN SalesLT.SalesOrderDetail AS sod 33 | ON p.ProductID = sod.ProductID 34 | ORDER BY ProductName DESC; 35 | 36 | ----Query---- 37 | SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ', 38 | p.Name AS ProductName 39 | FROM SalesLT.Product AS p 40 | INNER JOIN SalesLT.SalesOrderDetail AS sod 41 | ON p.ProductID = sod.ProductID 42 | ORDER BY ProductName ASC; 43 | 44 | ----Query---- 45 | SELECT DISTINCT FirstName, LastName 46 | FROM SalesLT.Customer 47 | ORDER BY LastName, FirstName; 48 | 49 | ----Query---- 50 | SELECT C.CustomerID, C.NameStyle, C.Title, C.FirstName, C.LastName, C.Suffix, C.CompanyName, C.SalesPerson, C.EmailAddress 51 | , C.Phone, CA.AddressType, A.AddressLine1, A.AddressLine2, A.City, A.StateProvince, A.CountryRegion, A.PostalCode 52 | FROM SalesLT.Customer C 53 | INNER JOIN SalesLT.CustomerAddress CA ON CA.CustomerID = C.CustomerID 54 | INNER JOIN SalesLT.Address A ON A.AddressID = CA.AddressID 55 | ORDER BY C.LastName, C.FirstName; 56 | 57 | ----Query---- 58 | SELECT DISTINCT FirstName, LastName 59 | FROM SalesLT.Customer 60 | ORDER BY LastName, FirstName; 61 | 62 | 63 | ----Query---- 64 | IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL 65 | DROP TABLE #Bicycles; 66 | GO 67 | SELECT * 68 | INTO #Bicycles 69 | FROM SalesLT.Product 70 | WHERE ProductNumber LIKE 'BK%'; 71 | 72 | ----Query---- 73 | SELECT DISTINCT Name 74 | FROM SalesLT.Product AS p 75 | WHERE EXISTS 76 | (SELECT * 77 | FROM SalesLT.ProductModel AS pm 78 | WHERE p.ProductModelID = pm.ProductModelID 79 | AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'); 80 | 81 | ----Query---- 82 | 83 | SELECT DISTINCT Name 84 | FROM SalesLT.Product 85 | WHERE ProductModelID IN 86 | (SELECT ProductModelID 87 | FROM SalesLT.ProductModel 88 | WHERE Name LIKE 'Long-Sleeve Logo Jersey%'); 89 | 90 | ----Query---- 91 | SELECT p1.ProductModelID 92 | FROM SalesLT.Product AS p1 93 | GROUP BY p1.ProductModelID 94 | HAVING MAX(p1.ListPrice) >= ALL 95 | (SELECT AVG(p2.ListPrice) 96 | FROM SalesLT.Product AS p2 97 | WHERE p1.ProductModelID = p2.ProductModelID); 98 | 99 | 100 | 101 | ----Query---- 102 | SELECT SalesOrderID, SUM(LineTotal) AS SubTotal 103 | FROM SalesLT.SalesOrderDetail 104 | GROUP BY SalesOrderID 105 | ORDER BY SalesOrderID; 106 | 107 | ----Query---- 108 | SELECT ProductID, OrderQty, AVG(UnitPrice) AS [Average Price], 109 | SUM(LineTotal) AS SubTotal 110 | FROM SalesLT.SalesOrderDetail 111 | GROUP BY ProductID, OrderQty 112 | ORDER BY ProductID; 113 | 114 | ----Query---- 115 | SELECT ProductModelID, AVG(ListPrice) AS [Average List Price] 116 | FROM SalesLT.Product 117 | WHERE ListPrice > $1000 118 | GROUP BY ProductModelID 119 | ORDER BY ProductModelID; 120 | 121 | ----Query---- 122 | SELECT AVG(OrderQty) AS [Average Quantity], 123 | NonDiscountSales = (OrderQty * UnitPrice) 124 | FROM SalesLT.SalesOrderDetail 125 | GROUP BY (OrderQty * UnitPrice) 126 | ORDER BY (OrderQty * UnitPrice) DESC; 127 | 128 | ----Query---- 129 | SELECT ProductID, AVG(UnitPrice) AS [Average Price] 130 | FROM SalesLT.SalesOrderDetail 131 | WHERE OrderQty > 10 132 | GROUP BY ProductID 133 | ORDER BY AVG(UnitPrice); 134 | 135 | ----Query---- 136 | SELECT ProductID 137 | FROM SalesLT.SalesOrderDetail 138 | GROUP BY ProductID 139 | HAVING AVG(OrderQty) > 5 140 | ORDER BY ProductID; 141 | 142 | ----Query---- 143 | SELECT SalesOrderID, CarrierTrackingNumber 144 | FROM SalesLT.SalesOrderDetail 145 | GROUP BY SalesOrderID, CarrierTrackingNumber 146 | HAVING CarrierTrackingNumber LIKE '4BD%' 147 | ORDER BY SalesOrderID; 148 | 149 | ----Query---- 150 | SELECT ProductID 151 | FROM SalesLT.SalesOrderDetail 152 | WHERE UnitPrice < 25.00 153 | GROUP BY ProductID 154 | HAVING AVG(OrderQty) > 5 155 | ORDER BY ProductID; 156 | 157 | ----Query---- 158 | SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total 159 | FROM SalesLT.SalesOrderDetail 160 | GROUP BY ProductID 161 | HAVING SUM(LineTotal) > $1000000.00 162 | AND AVG(OrderQty) < 3; 163 | 164 | ----Query---- 165 | SELECT ProductID, Total = SUM(LineTotal) 166 | FROM SalesLT.SalesOrderDetail 167 | GROUP BY ProductID 168 | HAVING SUM(LineTotal) > $2000000.00; 169 | 170 | ----Query---- 171 | SELECT ProductID, SUM(LineTotal) AS Total 172 | FROM SalesLT.SalesOrderDetail 173 | GROUP BY ProductID 174 | HAVING COUNT(*) > 1500; 175 | 176 | 177 | ----Query---- 178 | -- Performs an index seek 179 | SELECT C.CustomerID, C.NameStyle, C.Title, C.FirstName, C.LastName, C.Suffix, C.CompanyName, C.SalesPerson, C.EmailAddress 180 | , C.Phone, CA.AddressType, A.AddressLine1, A.AddressLine2, A.City, A.StateProvince, A.CountryRegion, A.PostalCode 181 | FROM SalesLT.Customer C 182 | INNER JOIN SalesLT.CustomerAddress CA ON CA.CustomerID = C.CustomerID 183 | INNER JOIN SalesLT.Address A ON A.AddressID = CA.AddressID 184 | WHERE C.EmailAddress = 'martha0@adventure-works.com' 185 | ORDER BY C.LastName, C.FirstName; 186 | 187 | ----Query---- 188 | -- Force a table scan by using INDEX = 0. 189 | SELECT C.CustomerID, C.NameStyle, C.Title, C.FirstName, C.LastName, C.Suffix, C.CompanyName, C.SalesPerson, C.EmailAddress 190 | , C.Phone, CA.AddressType, A.AddressLine1, A.AddressLine2, A.City, A.StateProvince, A.CountryRegion, A.PostalCode 191 | FROM SalesLT.Customer C WITH (INDEX = 0) 192 | INNER JOIN SalesLT.CustomerAddress CA ON CA.CustomerID = C.CustomerID 193 | INNER JOIN SalesLT.Address A ON A.AddressID = CA.AddressID 194 | WHERE C.EmailAddress = 'martha0@adventure-works.com' 195 | ORDER BY C.LastName, C.FirstName; 196 | 197 | 198 | ----Query---- 199 | SELECT ProductID, OrderQty, SUM(LineTotal) AS Total 200 | FROM SalesLT.SalesOrderDetail 201 | WHERE UnitPrice < $5.00 202 | GROUP BY ProductID, OrderQty 203 | ORDER BY ProductID, OrderQty 204 | OPTION (HASH GROUP, FAST 10); 205 | 206 | ----Query---- 207 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 208 | FROM HumanResources.Employee AS e1 209 | UNION 210 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 211 | FROM HumanResources.Employee AS e2 212 | OPTION (MERGE UNION); 213 | 214 | ----Query---- 215 | -- Here is the simple union. 216 | SELECT ProductModelID, Name 217 | FROM SalesLT.ProductModel AS pm1 218 | WHERE ProductModelID NOT IN (3, 4) 219 | UNION 220 | SELECT ProductModelID, Name 221 | FROM SalesLT.ProductModel AS pm2 222 | WHERE ProductModelID IN (3, 4) 223 | ORDER BY Name; 224 | 225 | ----Query---- 226 | -- Union ALL 1 227 | SELECT LastName, FirstName, EmailAddress 228 | FROM SalesLT.Customer as C1 229 | UNION ALL 230 | SELECT LastName, FirstName, EmailAddress 231 | FROM SalesLT.Customer as C2 232 | UNION ALL 233 | SELECT LastName, FirstName, EmailAddress 234 | FROM SalesLT.Customer as C3 235 | 236 | ----Query---- 237 | -- Union ALL 2 238 | SELECT LastName, FirstName, EmailAddress 239 | FROM SalesLT.Customer as C1 240 | UNION 241 | SELECT LastName, FirstName, EmailAddress 242 | FROM SalesLT.Customer as C2 243 | UNION 244 | SELECT LastName, FirstName, EmailAddress 245 | FROM SalesLT.Customer as C3 246 | 247 | ----Query---- 248 | -- Union ALL 3 249 | SELECT LastName, FirstName, EmailAddress 250 | FROM SalesLT.Customer as C1 251 | UNION ALL 252 | ( 253 | SELECT LastName, FirstName, EmailAddress 254 | FROM SalesLT.Customer as C2 255 | UNION 256 | SELECT LastName, FirstName, EmailAddress 257 | FROM SalesLT.Customer as C3 258 | ); 259 | 260 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorksWorkload.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Scripts from https://docs.microsoft.com/en-us/sql/t-sql/queries/select-examples-transact-sql 3 | *******************************************************************************/ 4 | 5 | ----Query---- 6 | SELECT * 7 | FROM Production.Product 8 | ORDER BY Name ASC; 9 | 10 | ----Query---- 11 | SELECT p.* 12 | FROM Production.Product AS p 13 | ORDER BY Name ASC; 14 | 15 | ----Query---- 16 | SELECT Name, ProductNumber, ListPrice AS Price 17 | FROM Production.Product 18 | ORDER BY Name ASC; 19 | 20 | ----Query---- 21 | SELECT Name, ProductNumber, ListPrice AS Price 22 | FROM Production.Product 23 | WHERE ProductLine = 'R' 24 | AND DaysToManufacture < 4 25 | ORDER BY Name ASC; 26 | 27 | ----Query---- 28 | SELECT p.Name AS ProductName, 29 | NonDiscountSales = (OrderQty * UnitPrice), 30 | Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount) 31 | FROM Production.Product AS p 32 | INNER JOIN Sales.SalesOrderDetail AS sod 33 | ON p.ProductID = sod.ProductID 34 | ORDER BY ProductName DESC; 35 | 36 | ----Query---- 37 | SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ', 38 | p.Name AS ProductName 39 | FROM Production.Product AS p 40 | INNER JOIN Sales.SalesOrderDetail AS sod 41 | ON p.ProductID = sod.ProductID 42 | ORDER BY ProductName ASC; 43 | 44 | ----Query---- 45 | SELECT DISTINCT JobTitle 46 | FROM HumanResources.Employee 47 | ORDER BY JobTitle; 48 | 49 | ----Query---- 50 | USE tempdb; 51 | GO 52 | IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL 53 | DROP TABLE #Bicycles; 54 | GO 55 | SELECT * 56 | INTO #Bicycles 57 | FROM Production.Product 58 | WHERE ProductNumber LIKE 'BK%'; 59 | 60 | ----Query---- 61 | SELECT DISTINCT Name 62 | FROM Production.Product AS p 63 | WHERE EXISTS 64 | (SELECT * 65 | FROM Production.ProductModel AS pm 66 | WHERE p.ProductModelID = pm.ProductModelID 67 | AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'); 68 | 69 | ----Query---- 70 | 71 | SELECT DISTINCT Name 72 | FROM Production.Product 73 | WHERE ProductModelID IN 74 | (SELECT ProductModelID 75 | FROM Production.ProductModel 76 | WHERE Name LIKE 'Long-Sleeve Logo Jersey%'); 77 | 78 | ----Query---- 79 | SELECT DISTINCT p.LastName, p.FirstName 80 | FROM Person.Person AS p 81 | JOIN HumanResources.Employee AS e 82 | ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN 83 | (SELECT Bonus 84 | FROM Sales.SalesPerson AS sp 85 | WHERE e.BusinessEntityID = sp.BusinessEntityID); 86 | 87 | ----Query---- 88 | SELECT p1.ProductModelID 89 | FROM Production.Product AS p1 90 | GROUP BY p1.ProductModelID 91 | HAVING MAX(p1.ListPrice) >= ALL 92 | (SELECT AVG(p2.ListPrice) 93 | FROM Production.Product AS p2 94 | WHERE p1.ProductModelID = p2.ProductModelID); 95 | 96 | ----Query---- 97 | SELECT DISTINCT pp.LastName, pp.FirstName 98 | FROM Person.Person pp JOIN HumanResources.Employee e 99 | ON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN 100 | (SELECT SalesPersonID 101 | FROM Sales.SalesOrderHeader 102 | WHERE SalesOrderID IN 103 | (SELECT SalesOrderID 104 | FROM Sales.SalesOrderDetail 105 | WHERE ProductID IN 106 | (SELECT ProductID 107 | FROM Production.Product p 108 | WHERE ProductNumber = 'BK-M68B-42'))); 109 | 110 | ----Query---- 111 | SELECT SalesOrderID, SUM(LineTotal) AS SubTotal 112 | FROM Sales.SalesOrderDetail 113 | GROUP BY SalesOrderID 114 | ORDER BY SalesOrderID; 115 | 116 | ----Query---- 117 | SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price], 118 | SUM(LineTotal) AS SubTotal 119 | FROM Sales.SalesOrderDetail 120 | GROUP BY ProductID, SpecialOfferID 121 | ORDER BY ProductID; 122 | 123 | ----Query---- 124 | SELECT ProductModelID, AVG(ListPrice) AS [Average List Price] 125 | FROM Production.Product 126 | WHERE ListPrice > $1000 127 | GROUP BY ProductModelID 128 | ORDER BY ProductModelID; 129 | 130 | ----Query---- 131 | SELECT AVG(OrderQty) AS [Average Quantity], 132 | NonDiscountSales = (OrderQty * UnitPrice) 133 | FROM Sales.SalesOrderDetail 134 | GROUP BY (OrderQty * UnitPrice) 135 | ORDER BY (OrderQty * UnitPrice) DESC; 136 | 137 | ----Query---- 138 | SELECT ProductID, AVG(UnitPrice) AS [Average Price] 139 | FROM Sales.SalesOrderDetail 140 | WHERE OrderQty > 10 141 | GROUP BY ProductID 142 | ORDER BY AVG(UnitPrice); 143 | 144 | ----Query---- 145 | SELECT ProductID 146 | FROM Sales.SalesOrderDetail 147 | GROUP BY ProductID 148 | HAVING AVG(OrderQty) > 5 149 | ORDER BY ProductID; 150 | 151 | ----Query---- 152 | SELECT SalesOrderID, CarrierTrackingNumber 153 | FROM Sales.SalesOrderDetail 154 | GROUP BY SalesOrderID, CarrierTrackingNumber 155 | HAVING CarrierTrackingNumber LIKE '4BD%' 156 | ORDER BY SalesOrderID ; 157 | 158 | ----Query---- 159 | SELECT ProductID 160 | FROM Sales.SalesOrderDetail 161 | WHERE UnitPrice < 25.00 162 | GROUP BY ProductID 163 | HAVING AVG(OrderQty) > 5 164 | ORDER BY ProductID; 165 | 166 | ----Query---- 167 | SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total 168 | FROM Sales.SalesOrderDetail 169 | GROUP BY ProductID 170 | HAVING SUM(LineTotal) > $1000000.00 171 | AND AVG(OrderQty) < 3; 172 | 173 | ----Query---- 174 | SELECT ProductID, Total = SUM(LineTotal) 175 | FROM Sales.SalesOrderDetail 176 | GROUP BY ProductID 177 | HAVING SUM(LineTotal) > $2000000.00; 178 | 179 | ----Query---- 180 | SELECT ProductID, SUM(LineTotal) AS Total 181 | FROM Sales.SalesOrderDetail 182 | GROUP BY ProductID 183 | HAVING COUNT(*) > 1500; 184 | 185 | ----Query---- 186 | SELECT pp.FirstName, pp.LastName, e.NationalIDNumber 187 | FROM HumanResources.Employee AS e WITH (INDEX(AK_Employee_NationalIDNumber)) 188 | JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityID 189 | WHERE LastName = 'Johnson'; 190 | 191 | ----Query---- 192 | -- Force a table scan by using INDEX = 0. 193 | SELECT pp.LastName, pp.FirstName, e.JobTitle 194 | FROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS pp 195 | ON e.BusinessEntityID = pp.BusinessEntityID 196 | WHERE LastName = 'Johnson'; 197 | 198 | ----Query---- 199 | SELECT ProductID, OrderQty, SUM(LineTotal) AS Total 200 | FROM Sales.SalesOrderDetail 201 | WHERE UnitPrice < $5.00 202 | GROUP BY ProductID, OrderQty 203 | ORDER BY ProductID, OrderQty 204 | OPTION (HASH GROUP, FAST 10); 205 | 206 | ----Query---- 207 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 208 | FROM HumanResources.Employee AS e1 209 | UNION 210 | SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours 211 | FROM HumanResources.Employee AS e2 212 | OPTION (MERGE UNION); 213 | 214 | ----Query---- 215 | -- Here is the simple union. 216 | SELECT ProductModelID, Name 217 | FROM Production.ProductModel 218 | WHERE ProductModelID NOT IN (3, 4) 219 | UNION 220 | SELECT ProductModelID, Name 221 | FROM dbo.Gloves 222 | ORDER BY Name; 223 | 224 | ----Query---- 225 | SELECT ProductModelID, Name 226 | FROM dbo.ProductResults; 227 | 228 | ----Query---- 229 | /* Union */ 230 | SELECT ProductModelID, Name 231 | FROM Production.ProductModel 232 | WHERE ProductModelID NOT IN (3, 4) 233 | UNION 234 | SELECT ProductModelID, Name 235 | FROM dbo.Gloves 236 | ORDER BY Name; 237 | 238 | ----Query---- 239 | -- Union ALL 240 | SELECT LastName, FirstName, JobTitle 241 | FROM dbo.EmployeeOne 242 | UNION ALL 243 | SELECT LastName, FirstName ,JobTitle 244 | FROM dbo.EmployeeTwo 245 | UNION ALL 246 | SELECT LastName, FirstName,JobTitle 247 | FROM dbo.EmployeeThree; 248 | 249 | ----Query---- 250 | -- Union ALL 2 251 | SELECT LastName, FirstName,JobTitle 252 | FROM dbo.EmployeeOne 253 | UNION 254 | SELECT LastName, FirstName, JobTitle 255 | FROM dbo.EmployeeTwo 256 | UNION 257 | SELECT LastName, FirstName, JobTitle 258 | FROM dbo.EmployeeThree; 259 | 260 | ----Query---- 261 | -- Union ALL 3 262 | SELECT LastName, FirstName,JobTitle 263 | FROM dbo.EmployeeOne 264 | UNION ALL 265 | ( 266 | SELECT LastName, FirstName, JobTitle 267 | FROM dbo.EmployeeTwo 268 | UNION 269 | SELECT LastName, FirstName, JobTitle 270 | FROM dbo.EmployeeThree 271 | ); 272 | 273 | 274 | ----Query---- 275 | /******************************************************************************* 276 | Scripts from http://msdn.microsoft.com/en-us/library/bb510625.aspx 277 | *******************************************************************************/ 278 | 279 | ----Query---- 280 | -- Test the procedure 281 | EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'New Test Value'; 282 | EXEC InsertUnitMeasure @UnitMeasureCode = 'XYZ', @Name = 'Test Value'; 283 | EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Another Test Value'; 284 | 285 | -- Cleanup 286 | DELETE FROM Production.UnitMeasure WHERE UnitMeasureCode IN ('ABC','XYZ'); 287 | 288 | 289 | ----Query---- 290 | EXECUTE Production.usp_UpdateInventory '20030501' 291 | 292 | ----Query---- 293 | -- Create a temporary table variable to hold the output actions. 294 | DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20)); 295 | 296 | MERGE INTO Sales.SalesReason AS Target 297 | USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion')) 298 | AS Source (NewName, NewReasonType) 299 | ON Target.Name = Source.NewName 300 | WHEN MATCHED THEN 301 | UPDATE SET ReasonType = Source.NewReasonType 302 | WHEN NOT MATCHED BY TARGET THEN 303 | INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) 304 | OUTPUT $action INTO @SummaryOfChanges; 305 | 306 | -- Query the results of the table variable. 307 | SELECT Change, COUNT(*) AS CountPerChange 308 | FROM @SummaryOfChanges 309 | GROUP BY Change; 310 | 311 | ----Query---- 312 | INSERT INTO Production.UpdatedInventory 313 | SELECT ProductID, LocationID, NewQty, PreviousQty 314 | FROM 315 | ( MERGE Production.ProductInventory AS pi 316 | USING (SELECT ProductID, SUM(OrderQty) 317 | FROM Sales.SalesOrderDetail AS sod 318 | JOIN Sales.SalesOrderHeader AS soh 319 | ON sod.SalesOrderID = soh.SalesOrderID 320 | AND soh.OrderDate BETWEEN '20030701' AND '20030731' 321 | GROUP BY ProductID) AS src (ProductID, OrderQty) 322 | ON pi.ProductID = src.ProductID 323 | WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0 324 | THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty 325 | WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0 326 | THEN DELETE 327 | OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty) 328 | AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'UPDATE'; 329 | 330 | 331 | 332 | 333 | 334 | /******************************************************************************* 335 | Scripts from http://msdn.microsoft.com/en-us/library/ms174335.aspx 336 | *******************************************************************************/ 337 | 338 | ----Query---- 339 | INSERT INTO Production.UnitMeasure 340 | VALUES (N'FT', N'Feet', '20080414'); 341 | 342 | ----Query---- 343 | INSERT INTO Production.UnitMeasure 344 | VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'), (N'Y3', N'Cubic Yards', '20080923'); 345 | 346 | ----Query---- 347 | INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, 348 | ModifiedDate) 349 | VALUES (N'Square Yards', N'Y2', GETDATE()); 350 | 351 | ----Query---- 352 | INSERT INTO dbo.T1 (column_4) 353 | VALUES ('Explicit value'); 354 | INSERT INTO dbo.T1 (column_2, column_4) 355 | VALUES ('Explicit value', 'Explicit value'); 356 | INSERT INTO dbo.T1 (column_2) 357 | VALUES ('Explicit value'); 358 | INSERT INTO T1 DEFAULT VALUES; 359 | SELECT column_1, column_2, column_3, column_4 360 | FROM dbo.T1; 361 | 362 | ----Query---- 363 | INSERT T1 VALUES ('Row #1'); 364 | INSERT T1 (column_2) VALUES ('Row #2'); 365 | SET IDENTITY_INSERT T1 ON; 366 | INSERT INTO T1 (column_1,column_2) 367 | VALUES (-99, 'Explicit identity value'); 368 | SELECT column_1, column_2 369 | FROM T1; 370 | 371 | ----Query---- 372 | INSERT INTO dbo.T1 (column_2) 373 | VALUES (NEWID()); 374 | INSERT INTO T1 DEFAULT VALUES; 375 | SELECT column_1, column_2 376 | FROM dbo.T1; 377 | 378 | ----Query---- 379 | --INSERT...SELECT example 380 | INSERT INTO dbo.EmployeeSales 381 | SELECT 'SELECT', sp.BusinessEntityID, c.LastName, sp.SalesYTD 382 | FROM Sales.SalesPerson AS sp 383 | INNER JOIN Person.Person AS c 384 | ON sp.BusinessEntityID = c.BusinessEntityID 385 | WHERE sp.BusinessEntityID LIKE '2%' 386 | ORDER BY sp.BusinessEntityID, c.LastName; 387 | --INSERT...EXECUTE procedure example 388 | INSERT INTO dbo.EmployeeSales 389 | EXECUTE dbo.uspGetEmployeeSales; 390 | --INSERT...EXECUTE('string') example 391 | INSERT INTO dbo.EmployeeSales 392 | EXECUTE 393 | (' 394 | SELECT ''EXEC STRING'', sp.BusinessEntityID, c.LastName, 395 | sp.SalesYTD 396 | FROM Sales.SalesPerson AS sp 397 | INNER JOIN Person.Person AS c 398 | ON sp.BusinessEntityID = c.BusinessEntityID 399 | WHERE sp.BusinessEntityID LIKE ''2%'' 400 | ORDER BY sp.BusinessEntityID, c.LastName 401 | '); 402 | --Show results. 403 | SELECT DataSource,BusinessEntityID,LastName,SalesDollars 404 | FROM dbo.EmployeeSales; 405 | 406 | ----Query---- 407 | WITH EmployeeTemp (EmpID, LastName, FirstName, Phone, 408 | Address, City, StateProvince, 409 | PostalCode, CurrentFlag) 410 | AS (SELECT 411 | e.BusinessEntityID, c.LastName, c.FirstName, pp.PhoneNumber, 412 | a.AddressLine1, a.City, sp.StateProvinceCode, 413 | a.PostalCode, e.CurrentFlag 414 | FROM HumanResources.Employee e 415 | INNER JOIN Person.BusinessEntityAddress AS bea 416 | ON e.BusinessEntityID = bea.BusinessEntityID 417 | INNER JOIN Person.Address AS a 418 | ON bea.AddressID = a.AddressID 419 | INNER JOIN Person.PersonPhone AS pp 420 | ON e.BusinessEntityID = pp.BusinessEntityID 421 | INNER JOIN Person.StateProvince AS sp 422 | ON a.StateProvinceID = sp.StateProvinceID 423 | INNER JOIN Person.Person as c 424 | ON e.BusinessEntityID = c.BusinessEntityID 425 | ) 426 | INSERT INTO HumanResources.NewEmployee 427 | SELECT EmpID, LastName, FirstName, Phone, 428 | Address, City, StateProvince, PostalCode, CurrentFlag 429 | FROM EmployeeTemp; 430 | 431 | ----Query---- 432 | INSERT TOP(5)INTO dbo.EmployeeSales 433 | OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales 434 | SELECT sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 435 | FROM Sales.SalesPerson AS sp 436 | INNER JOIN Person.Person AS c 437 | ON sp.BusinessEntityID = c.BusinessEntityID 438 | WHERE sp.SalesYTD > 250000.00 439 | ORDER BY sp.SalesYTD DESC; 440 | 441 | ----Query---- 442 | INSERT INTO dbo.EmployeeSales 443 | OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales 444 | SELECT TOP (5) sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD 445 | FROM Sales.SalesPerson AS sp 446 | INNER JOIN Person.Person AS c 447 | ON sp.BusinessEntityID = c.BusinessEntityID 448 | WHERE sp.SalesYTD > 250000.00 449 | ORDER BY sp.SalesYTD DESC; 450 | 451 | ----Query---- 452 | INSERT INTO V1 453 | VALUES ('Row 1',1); 454 | SELECT column_1, column_2 455 | FROM T1; 456 | SELECT column_1, column_2 457 | FROM V1; 458 | 459 | ----Query---- 460 | -- Create the table variable. 461 | DECLARE @MyTableVar table( 462 | LocationID int NOT NULL, 463 | CostRate smallmoney NOT NULL, 464 | NewCostRate AS CostRate * 1.5, 465 | ModifiedDate datetime); 466 | 467 | -- Insert values into the table variable. 468 | INSERT INTO @MyTableVar (LocationID, CostRate, ModifiedDate) 469 | SELECT LocationID, CostRate, GETDATE() FROM Production.Location 470 | WHERE CostRate > 0; 471 | 472 | -- View the table variable result set. 473 | SELECT * FROM @MyTableVar; 474 | 475 | 476 | 477 | 478 | /******************************************************************************* 479 | Scripts from http://msdn.microsoft.com/en-us/library/ms177523.aspx 480 | *******************************************************************************/ 481 | 482 | ----Query---- 483 | UPDATE Person.Address 484 | SET ModifiedDate = GETDATE(); 485 | 486 | ----Query---- 487 | UPDATE Sales.SalesPerson 488 | SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL; 489 | 490 | ----Query---- 491 | UPDATE Production.Product 492 | SET Color = N'Metallic Red' 493 | WHERE Name LIKE N'Road-250%' AND Color = N'Red'; 494 | 495 | ----Query---- 496 | UPDATE TOP (10) HumanResources.Employee 497 | SET VacationHours = VacationHours * 1.25 ; 498 | 499 | ----Query---- 500 | UPDATE HumanResources.Employee 501 | SET VacationHours = VacationHours + 8 502 | FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee 503 | ORDER BY HireDate ASC) AS th 504 | WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID; 505 | 506 | ----Query---- 507 | WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS 508 | ( 509 | SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty, 510 | b.EndDate, 0 AS ComponentLevel 511 | FROM Production.BillOfMaterials AS b 512 | WHERE b.ProductAssemblyID = 800 513 | AND b.EndDate IS NULL 514 | UNION ALL 515 | SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty, 516 | bom.EndDate, ComponentLevel + 1 517 | FROM Production.BillOfMaterials AS bom 518 | INNER JOIN Parts AS p 519 | ON bom.ProductAssemblyID = p.ComponentID 520 | AND bom.EndDate IS NULL 521 | ) 522 | UPDATE Production.BillOfMaterials 523 | SET PerAssemblyQty = c.PerAssemblyQty * 2 524 | FROM Production.BillOfMaterials AS c 525 | JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID 526 | WHERE d.ComponentLevel = 0; 527 | 528 | ----Query---- 529 | DECLARE complex_cursor CURSOR FOR 530 | SELECT a.BusinessEntityID 531 | FROM HumanResources.EmployeePayHistory AS a 532 | WHERE RateChangeDate <> 533 | (SELECT MAX(RateChangeDate) 534 | FROM HumanResources.EmployeePayHistory AS b 535 | WHERE a.BusinessEntityID = b.BusinessEntityID) ; 536 | OPEN complex_cursor; 537 | FETCH FROM complex_cursor; 538 | UPDATE HumanResources.EmployeePayHistory 539 | SET PayFrequency = 2 540 | WHERE CURRENT OF complex_cursor; 541 | CLOSE complex_cursor; 542 | DEALLOCATE complex_cursor; 543 | 544 | ----Query---- 545 | UPDATE Production.Product 546 | SET ListPrice = ListPrice * 2; 547 | 548 | ----Query---- 549 | DECLARE @NewPrice int = 10; 550 | UPDATE Production.Product 551 | SET ListPrice += @NewPrice 552 | WHERE Color = N'Red'; 553 | 554 | ----Query---- 555 | UPDATE Production.ScrapReason 556 | SET Name += ' - tool malfunction' 557 | WHERE ScrapReasonID BETWEEN 10 and 12; 558 | 559 | ----Query---- 560 | UPDATE Sales.SalesPerson 561 | SET SalesYTD = SalesYTD + 562 | (SELECT SUM(so.SubTotal) 563 | FROM Sales.SalesOrderHeader AS so 564 | WHERE so.OrderDate = (SELECT MAX(OrderDate) 565 | FROM Sales.SalesOrderHeader AS so2 566 | WHERE so2.SalesPersonID = so.SalesPersonID) 567 | AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID 568 | GROUP BY so.SalesPersonID); 569 | 570 | ----Query---- 571 | UPDATE Production.Location 572 | SET CostRate = DEFAULT 573 | WHERE CostRate > 20.00; 574 | 575 | ----Query---- 576 | UPDATE Person.vStateProvinceCountryRegion 577 | SET CountryRegionName = 'United States of America' 578 | WHERE CountryRegionName = 'United States'; 579 | 580 | 581 | ----Query---- 582 | UPDATE sr 583 | SET sr.Name += ' - tool malfunction' 584 | FROM Production.ScrapReason AS sr 585 | JOIN Production.WorkOrder AS wo 586 | ON sr.ScrapReasonID = wo.ScrapReasonID 587 | AND wo.ScrappedQty > 300; 588 | 589 | ----Query---- 590 | -- Create the table variable. 591 | DECLARE @MyTableVar table( 592 | EmpID int NOT NULL, 593 | NewVacationHours int, 594 | ModifiedDate datetime); 595 | 596 | -- Populate the table variable with employee ID values from HumanResources.Employee. 597 | INSERT INTO @MyTableVar (EmpID) 598 | SELECT BusinessEntityID FROM HumanResources.Employee; 599 | 600 | -- Update columns in the table variable. 601 | UPDATE @MyTableVar 602 | SET NewVacationHours = e.VacationHours + 20, 603 | ModifiedDate = GETDATE() 604 | FROM HumanResources.Employee AS e 605 | WHERE e.BusinessEntityID = EmpID; 606 | 607 | -- Display the results of the UPDATE statement. 608 | SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar 609 | ORDER BY EmpID; 610 | 611 | ----Query---- 612 | UPDATE Sales.SalesPerson 613 | SET SalesYTD = SalesYTD + SubTotal 614 | FROM Sales.SalesPerson AS sp 615 | JOIN Sales.SalesOrderHeader AS so 616 | ON sp.BusinessEntityID = so.SalesPersonID 617 | AND so.OrderDate = (SELECT MAX(OrderDate) 618 | FROM Sales.SalesOrderHeader 619 | WHERE SalesPersonID = sp.BusinessEntityID); 620 | 621 | ----Query---- 622 | UPDATE Sales.SalesPerson 623 | SET SalesYTD = SalesYTD + 624 | (SELECT SUM(so.SubTotal) 625 | FROM Sales.SalesOrderHeader AS so 626 | WHERE so.OrderDate = (SELECT MAX(OrderDate) 627 | FROM Sales.SalesOrderHeader AS so2 628 | WHERE so2.SalesPersonID = so.SalesPersonID) 629 | AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID 630 | GROUP BY so.SalesPersonID); 631 | 632 | ----Query---- 633 | DECLARE @MyTableVar table ( 634 | SummaryBefore nvarchar(max), 635 | SummaryAfter nvarchar(max)); 636 | UPDATE Production.Document 637 | SET DocumentSummary .WRITE (N'features',28,10) 638 | OUTPUT deleted.DocumentSummary, 639 | inserted.DocumentSummary 640 | INTO @MyTableVar 641 | WHERE Title = N'Front Reflector Bracket Installation'; 642 | SELECT SummaryBefore, SummaryAfter 643 | FROM @MyTableVar; 644 | 645 | ----Query---- 646 | UPDATE Production.Product 647 | WITH (TABLOCK) 648 | SET ListPrice = ListPrice * 1.10 649 | WHERE ProductNumber LIKE 'BK-%'; 650 | 651 | ----Query---- 652 | /*CREATE PROCEDURE Production.uspProductUpdate 653 | @Product nvarchar(25) 654 | AS 655 | SET NOCOUNT ON; 656 | UPDATE Production.Product 657 | SET ListPrice = ListPrice * 1.10 658 | WHERE ProductNumber LIKE @Product 659 | OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); 660 | GO*/ 661 | -- Execute the stored procedure 662 | EXEC Production.uspProductUpdate 'BK-%'; 663 | 664 | ----Query---- 665 | DECLARE @MyTableVar table( 666 | EmpID int NOT NULL, 667 | OldVacationHours int, 668 | NewVacationHours int, 669 | ModifiedDate datetime); 670 | UPDATE TOP (10) HumanResources.Employee 671 | SET VacationHours = VacationHours * 1.25, 672 | ModifiedDate = GETDATE() 673 | OUTPUT inserted.BusinessEntityID, 674 | deleted.VacationHours, 675 | inserted.VacationHours, 676 | inserted.ModifiedDate 677 | INTO @MyTableVar; 678 | --Display the result set of the table variable. 679 | SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate 680 | FROM @MyTableVar; 681 | --Display the result set of the table. 682 | SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate 683 | FROM HumanResources.Employee; 684 | 685 | -------------------------------------------------------------------------------- /SqlScripts/AdventureWorksWorkload_Setup.sql: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Setup 3 | WARNING: There is no clean up of objects in this file. The AdventureWorks database used 4 | should be refreshed following any tests 5 | *******************************************************************************/ 6 | IF OBJECT_ID ('dbo.Gloves', 'U') IS NULL 7 | BEGIN 8 | -- Create Gloves table. 9 | SELECT ProductModelID, Name 10 | INTO dbo.Gloves 11 | FROM Production.ProductModel 12 | WHERE ProductModelID IN (3, 4); 13 | --DROP TABLE dbo.Gloves; 14 | --GO 15 | END 16 | IF OBJECT_ID ('dbo.ProductResults', 'U') IS NULL 17 | BEGIN 18 | --DROP TABLE dbo.ProductResults; 19 | --GO 20 | SELECT ProductModelID, Name 21 | INTO dbo.ProductResults 22 | FROM Production.ProductModel 23 | WHERE ProductModelID NOT IN (3, 4) 24 | UNION 25 | SELECT ProductModelID, Name 26 | FROM dbo.Gloves; 27 | END 28 | 29 | IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NULL 30 | BEGIN 31 | --DROP TABLE dbo.EmployeeSales; 32 | --GO 33 | CREATE TABLE dbo.EmployeeSales 34 | ( DataSource varchar(20) NOT NULL, 35 | BusinessEntityID varchar(11) NOT NULL, 36 | LastName varchar(40) NOT NULL, 37 | SalesDollars money NOT NULL 38 | ); 39 | END 40 | 41 | 42 | IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NULL 43 | BEGIN 44 | --DROP TABLE dbo.EmployeeOne; 45 | --GO 46 | 47 | SELECT pp.LastName, pp.FirstName, e.JobTitle 48 | INTO dbo.EmployeeOne 49 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 50 | ON e.BusinessEntityID = pp.BusinessEntityID 51 | WHERE LastName = 'Johnson'; 52 | END 53 | IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NULL 54 | BEGIN 55 | --DROP TABLE dbo.EmployeeTwo; 56 | --GO 57 | SELECT pp.LastName, pp.FirstName, e.JobTitle 58 | INTO dbo.EmployeeTwo 59 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 60 | ON e.BusinessEntityID = pp.BusinessEntityID 61 | WHERE LastName = 'Johnson'; 62 | END 63 | IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NULL 64 | BEGIN 65 | --DROP TABLE dbo.EmployeeThree; 66 | --GO 67 | SELECT pp.LastName, pp.FirstName, e.JobTitle 68 | INTO dbo.EmployeeThree 69 | FROM Person.Person AS pp JOIN HumanResources.Employee AS e 70 | ON e.BusinessEntityID = pp.BusinessEntityID 71 | WHERE LastName = 'Johnson'; 72 | END 73 | 74 | 75 | 76 | IF OBJECT_ID ('dbo.uspGetEmployeeSales', 'P') IS NOT NULL 77 | DROP PROCEDURE uspGetEmployeeSales; 78 | GO 79 | CREATE PROCEDURE dbo.uspGetEmployeeSales 80 | AS 81 | SET NOCOUNT ON; 82 | SELECT 'PROCEDURE', sp.BusinessEntityID, c.LastName, 83 | sp.SalesYTD 84 | FROM Sales.SalesPerson AS sp 85 | INNER JOIN Person.Person AS c 86 | ON sp.BusinessEntityID = c.BusinessEntityID 87 | WHERE sp.BusinessEntityID LIKE '2%' 88 | ORDER BY sp.BusinessEntityID, c.LastName; 89 | GO 90 | 91 | IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL 92 | DROP TABLE HumanResources.NewEmployee; 93 | GO 94 | CREATE TABLE HumanResources.NewEmployee 95 | ( 96 | EmployeeID int NOT NULL, 97 | LastName nvarchar(50) NOT NULL, 98 | FirstName nvarchar(50) NOT NULL, 99 | PhoneNumber Phone NULL, 100 | AddressLine1 nvarchar(60) NOT NULL, 101 | City nvarchar(30) NOT NULL, 102 | State nchar(3) NOT NULL, 103 | PostalCode nvarchar(15) NOT NULL, 104 | CurrentFlag Flag 105 | ); 106 | GO 107 | 108 | IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL 109 | DROP TABLE dbo.EmployeeSales; 110 | GO 111 | CREATE TABLE dbo.EmployeeSales 112 | ( EmployeeID nvarchar(11) NOT NULL, 113 | LastName nvarchar(20) NOT NULL, 114 | FirstName nvarchar(20) NOT NULL, 115 | YearlySales money NOT NULL 116 | ); 117 | GO 118 | 119 | 120 | IF OBJECT_ID ('dbo.T1', 'U') IS NULL 121 | BEGIN 122 | --DROP TABLE dbo.T1; 123 | --GO 124 | CREATE TABLE dbo.T1 125 | ( 126 | column_1 int IDENTITY, 127 | column_2 uniqueidentifier, 128 | ); 129 | END 130 | 131 | IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL 132 | DROP TABLE dbo.T1; 133 | GO 134 | IF OBJECT_ID ('dbo.V1', 'V') IS NOT NULL 135 | DROP VIEW dbo.V1; 136 | GO 137 | CREATE TABLE T1 ( column_1 int, column_2 varchar(30)); 138 | GO 139 | CREATE VIEW V1 AS 140 | SELECT column_2, column_1 141 | FROM T1; 142 | GO 143 | 144 | IF OBJECT_ID ('Production.uspProductUpdate', 'P') IS NOT NULL 145 | DROP PROCEDURE Production.uspProductUpdate; 146 | GO 147 | CREATE PROCEDURE Production.uspProductUpdate 148 | @Product nvarchar(25) 149 | AS 150 | SET NOCOUNT ON; 151 | UPDATE Production.Product 152 | SET ListPrice = ListPrice * 1.10 153 | WHERE ProductNumber LIKE @Product 154 | OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); 155 | 156 | 157 | -- Rewrite the procedure to perform the same operations using the MERGE statement. 158 | -- Create a temporary table to hold the updated or inserted values from the OUTPUT clause. 159 | IF OBJECT_ID ('dbo.InsertUnitMeasure', 'P') IS NOT NULL 160 | BEGIN 161 | DROP PROCEDURE dbo.InsertUnitMeasure; 162 | END 163 | GO 164 | CREATE PROCEDURE dbo.InsertUnitMeasure 165 | @UnitMeasureCode nchar(3), 166 | @Name nvarchar(25) 167 | AS 168 | BEGIN 169 | SET NOCOUNT ON; 170 | 171 | CREATE TABLE #MyTempTable 172 | (ExistingCode nchar(3), 173 | ExistingName nvarchar(50), 174 | ExistingDate datetime, 175 | ActionTaken nvarchar(10), 176 | NewCode nchar(3), 177 | NewName nvarchar(50), 178 | NewDate datetime 179 | ); 180 | 181 | MERGE Production.UnitMeasure AS target 182 | USING (SELECT @UnitMeasureCode, @Name) AS source (UnitMeasureCode, Name) 183 | ON (target.UnitMeasureCode = source.UnitMeasureCode) 184 | WHEN MATCHED THEN 185 | UPDATE SET Name = source.Name 186 | WHEN NOT MATCHED THEN 187 | INSERT (UnitMeasureCode, Name) 188 | VALUES (source.UnitMeasureCode, source.Name) 189 | OUTPUT deleted.*, $action, inserted.* INTO #MyTempTable; 190 | 191 | SELECT * FROM #MyTempTable; 192 | 193 | DROP TABLE #MyTempTable; 194 | 195 | END; 196 | GO 197 | 198 | 199 | IF OBJECT_ID (N'Production.usp_UpdateInventory', N'P') IS NOT NULL DROP PROCEDURE Production.usp_UpdateInventory; 200 | GO 201 | CREATE PROCEDURE Production.usp_UpdateInventory 202 | @OrderDate datetime 203 | AS 204 | MERGE Production.ProductInventory AS target 205 | USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod 206 | JOIN Sales.SalesOrderHeader AS soh 207 | ON sod.SalesOrderID = soh.SalesOrderID 208 | AND soh.OrderDate = @OrderDate 209 | GROUP BY ProductID) AS source (ProductID, OrderQty) 210 | ON (target.ProductID = source.ProductID) 211 | WHEN MATCHED AND target.Quantity - source.OrderQty <= 0 212 | THEN DELETE 213 | WHEN MATCHED 214 | THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty, 215 | target.ModifiedDate = GETDATE() 216 | OUTPUT $action, Inserted.ProductID, Inserted.Quantity, Inserted.ModifiedDate, Deleted.ProductID, 217 | Deleted.Quantity, Deleted.ModifiedDate; 218 | GO 219 | 220 | IF OBJECT_ID ('Production.UpdatedInventory', 'U') IS NULL 221 | BEGIN 222 | --DROP TABLE Production.UpdatedInventory; 223 | --GO 224 | CREATE TABLE Production.UpdatedInventory 225 | (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int, 226 | CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID)); 227 | END 228 | 229 | IF OBJECT_ID ('dbo.T1', 'U') IS NULL 230 | BEGIN 231 | --DROP TABLE dbo.T1; 232 | --GO 233 | CREATE TABLE dbo.T1 234 | ( 235 | column_1 AS 'Computed column ' + column_2, 236 | column_2 varchar(30) 237 | CONSTRAINT default_name DEFAULT ('my column default'), 238 | column_3 rowversion, 239 | column_4 varchar(40) NULL 240 | ); 241 | END 242 | 243 | -------------------------------------------------------------------------------- /Tests/RunWorkload.Tests.ps1: -------------------------------------------------------------------------------- 1 | Import-Module "$PSScriptRoot\..\RunWorkload" -Force -Verbose; 2 | 3 | $Error.Clear(); 4 | 5 | Describe 'Invoke-SqlWorkload'{ 6 | Mock -ModuleName RunWorkload -CommandName Get-Content -MockWith { 7 | Write-Output 'SELECT * FROM Test.TestData' 8 | } 9 | Mock -ModuleName RunWorkload -CommandName Invoke-SqlWorkloadSetup -MockWith { 10 | Write-Output 'Setup script executed' 11 | } 12 | Mock -ModuleName RunWorkload -CommandName Invoke-SqlWorkloadQuery -MockWith { 13 | Write-Output 'Query executed' 14 | } 15 | 16 | Invoke-SqlWorkload -SqlServer 'localhost' -Database 'AdventureWorks' -TSQLFile 'C:\SqlQueries.sql' -TSQLSetupFile '' -Frequency 'Normal' -Duration 15 -Verbose; 17 | 18 | It 'Should not have any errors'{ 19 | $? | Should Be $true 20 | } 21 | 22 | It 'Should not have any exceptions'{ 23 | $Error.Count -eq 0 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | #---------------------------------# 2 | # environment configuration # 3 | #---------------------------------# 4 | version: 1.2.{build}.0 5 | install: 6 | - cinst -y pester 7 | - git clone https://github.com/PowerShell/DscResource.Tests 8 | - ps: Push-Location 9 | - cd DscResource.Tests 10 | - ps: Import-Module .\TestHelper.psm1 -force 11 | - ps: Pop-Location 12 | 13 | #---------------------------------# 14 | # build configuration # 15 | #---------------------------------# 16 | 17 | build: false 18 | 19 | #---------------------------------# 20 | # test configuration # 21 | #---------------------------------# 22 | 23 | test_script: 24 | - ps: | 25 | $testResultsFile = ".\TestsResults.xml" 26 | $res = Invoke-Pester -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru 27 | (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) 28 | if ($res.FailedCount -gt 0) { 29 | throw "$($res.FailedCount) tests failed." 30 | } 31 | 32 | #---------------------------------# 33 | # deployment configuration # 34 | #---------------------------------# 35 | 36 | # scripts to run before deployment 37 | deploy_script: 38 | - ps: | 39 | # None at this time 40 | 41 | 42 | 43 | 44 | 45 | --------------------------------------------------------------------------------