{"id":1393,"date":"2025-01-15T07:05:32","date_gmt":"2025-01-15T12:05:32","guid":{"rendered":"https:\/\/pressbooks.bccampus.ca\/nelson\/chapter\/chapter-13-programs-to-work-with-a-database\/"},"modified":"2025-01-16T05:42:21","modified_gmt":"2025-01-16T10:42:21","slug":"chapter13thirdedition","status":"publish","type":"chapter","link":"https:\/\/pressbooks.bccampus.ca\/nelson\/chapter\/chapter13thirdedition\/","title":{"raw":"Chapter 13 Programs to Work with a Database","rendered":"Chapter 13 Programs to Work with a Database"},"content":{"raw":"<div class=\"chapter-13-programs-to-work-with-a-database\">\r\n<p class=\"import-Standard\">Original Material to the textbook: Fred Strickland<\/p>\r\n\r\n<h2>Learning Outcomes<\/h2>\r\n<table style=\"width: 467.5pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>Computing Sub Discipline<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>Document Code, Reference Code, and Page Number<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>Text<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\r\n<td class=\"TableNormal-C\" style=\"border-top: solid #00000A 0.5pt;border-right: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\" rowspan=\"3\">\r\n<p class=\"import-Standard\">Computer Science<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CS2013<\/p>\r\n<p class=\"import-Standard\">IM\/Query Languages<\/p>\r\n<p class=\"import-Standard\">(Page 116)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">4. Create a non-procedural<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote1anc\" href=\"#sdfootnote1sym\">1<\/a><\/sup> query by filling in templates of relations to construct an example of the desired query result. [Usage]<\/p>\r\n<p class=\"import-Standard\">5. Embed object-oriented queries into a stand-alone language such as C++ or Java (e.g., SELECT Col.Method() FROM Object). [Usage]<\/p>\r\n<p class=\"import-Standard\">6. Write a stored procedure that deals with parameters and has some control flow<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote2anc\" href=\"#sdfootnote2sym\">2<\/a><\/sup> , to provide a given functionality. [Usage]<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CS2023<\/p>\r\n<p class=\"import-Standard\">DM-Querying: Query Construction<\/p>\r\n<p class=\"import-Standard\">(Page 118)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CS Core 1b. Programmatic execution of an SQL query<\/p>\r\n<p class=\"import-Standard\">Non-core 6. Different ways to invoke non-procedural queries in conventional languages.<\/p>\r\n<p class=\"import-Standard\">Non-core 8. Stored procedures<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CS2023<\/p>\r\n<p class=\"import-Standard\">DM-Security: Data Security and Privacy<\/p>\r\n<p class=\"import-Standard\">(Page 121)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CS Core 2. Protecting data and database systems from attacks, including injection attacks such as SQL injection<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\" rowspan=\"3\">\r\n<p class=\"import-Standard\">Data Science<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">DS2021<\/p>\r\n<p class=\"import-Standard\">Programming, Data Structures, and Algorithms (PDA) - Programming<\/p>\r\n<p class=\"import-Standard\">(Pages 112-113)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Manipulate data from selected sources (e.g., databases, ... utilizing appropriate techniques (e.g., database queries, API calls, regular expressions).<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 59.35pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">DS2021<\/p>\r\n<p class=\"import-Standard\">SDM-Software Design and Development<\/p>\r\n<p class=\"import-Standard\">(Page 119)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Students need to have T1 level of knowledge of<\/p>\r\n<p class=\"import-Standard\">\u2022Integration with Information Management\/Database systems<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 31.9pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Skills<\/p>\r\n<p class=\"import-Standard\">(Page 120)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Describe how to integrate or interact with Information Management\/Database Systems.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Information Systems<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">IS2020<\/p>\r\n<p class=\"import-Standard\">A3.2.1 Competency Area \u2013 Data \/ Information Management<\/p>\r\n<p class=\"import-Standard\">(Page 101)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">3. Programming database systems using functions and triggers. (Page 103)<\/p>\r\n<p class=\"import-Standard\">4. Secure a database. (Page 103)<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 60.25pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\" rowspan=\"2\">\r\n<p class=\"import-Standard\">Information Technology<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">IT2017<\/p>\r\n<p class=\"import-Standard\">ITE-IMA Domain: Information Management<\/p>\r\n<p class=\"import-Standard\">(Page 56)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">E. Perform major database administration tasks such as create and manage database users, roles and privileges, ... to ensure organizational efficiency, continuity, and information security. (Testing and performance)<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 60.25pt\">\r\n<td class=\"TableNormal-C\" style=\"border-right: solid #00000A 0.5pt;border-bottom: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\">\r\n<p class=\"import-Standard\">IT2017<\/p>\r\n<p class=\"import-Standard\">ITE-IMA-04 Database query languages [L3]<\/p>\r\n<p class=\"import-Standard\">(Page 92)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"border-right: solid #00000A 0.5pt;border-bottom: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\">\r\n<p class=\"import-Standard\">d. Use embedded SQL queries.<\/p>\r\n<p class=\"import-Standard\">f. Create updatable and non-updatable views.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<h2>Introduction to Chapter 13<\/h2>\r\n<p class=\"import-Standard\">We have been looking at relational DBMS from a hands-on or application viewpoint. And we have touched upon the different DBMSs. We have looked at the theory for any relational DBMS. We looked under the hood to see how the DBMS functions. In this chapter, we will begin to explore how to create a front end to a DBMS. We will be installing Microsoft\u2019s Visual Studio. We will be using the C# programming language. We will create some simple front-end programs for accessing a DBMS. In the process, we will touch upon secure coding concepts. We will look at tools that are stored in the DBMS such as stored procedures, functions, and triggers. We will wrap up this chapter by exploring how to create views.<\/p>\r\n\r\n<h2>The Third Edition Style Guide<\/h2>\r\n<p class=\"import-Standard\">This is the style guide that this book will follow for this chapter and for the other chapters.<\/p>\r\n\r\n<table style=\"width: 229.25pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Naming Convention:<\/p>\r\n\r\n<ul>\r\n \t<li>All English names<\/li>\r\n \t<li>Plural table names<\/li>\r\n \t<li>Singular column names<\/li>\r\n \t<li>Capitalized words<\/li>\r\n \t<li>Pascal Case for composite names<\/li>\r\n \t<li>No underscores or special characters<\/li>\r\n \t<li>No unique SQL commands<\/li>\r\n \t<li>No object prefixes<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">Using the IE\u2019s Notation with Crow\u2019s Foot Notation.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.1 The database style guide. Adapted from https:\/\/vertabelo.com\/blog\/database-schema-naming-conventions\/<\/p>\r\n<p class=\"import-Standard\">The examples will conform to the style guide.<\/p>\r\n\r\n<h2>Microsoft\u2019s Visual Studio<\/h2>\r\n<h3>Installing Microsoft\u2019s Visual Studio<\/h3>\r\n<p class=\"import-Standard\">Search for \u201cMicrosoft Visual Studio.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image1-8.png\" alt=\"image\" width=\"618.143937007874px\" height=\"537.071916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.2 Screenshot of a hit for the search phrase \u201cMicrosoft Visual Studio.\u201d<\/p>\r\n<p class=\"import-Standard\">This chapter will be working with Visual Studio instead of Visual Studio Code. In October 2024, the current edition is 2022<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote3anc\" href=\"#sdfootnote3sym\">3<\/a><\/sup>. There are three versions.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image2-8.png\" alt=\"image\" width=\"624px\" height=\"519.196745406824px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.3 The Visual Studio download screen with the three versions shown.<\/p>\r\n<p class=\"import-Standard\">The Community edition is free. By clicking on the Community button, the download starts immediately. At the same time, you are taken to an information web page. This is a rich resource that you can explore on your own.<\/p>\r\n<p class=\"import-Standard\">Install the software. At one point, you will see the \u201cWorkloads\u201d screen.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image3-10.png\" alt=\"image\" width=\"624px\" height=\"315.2543832021px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.4 The Workloads screen.<\/p>\r\n<p class=\"import-Standard\">Select the data storage option.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image4-9.png\" alt=\"image\" width=\"624px\" height=\"316.463937007874px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.5 Selecting the data storage option.<\/p>\r\n<p class=\"import-Standard\">You can come back later and add more pieces to your Visual Studio.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image5-10.png\" alt=\"image\" width=\"624px\" height=\"345.148766404199px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.6 Screenshot of the installed items in Visual Studio.<\/p>\r\n<p class=\"import-Standard\">Now sign into Visual Studio. Or you could skip doing this action for later on. Microsoft has an interesting approach. You can sign into Visual Studio or into Hotmail. These are related in some fashion.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image6-9.png\" alt=\"image\" width=\"624px\" height=\"314.006299212598px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.7 The Visual Studio sign-in screen.<\/p>\r\n\r\n<h3>Starting Up Visual Studio<\/h3>\r\n<p class=\"import-Standard\">On a Windows computer, the start button is in the \u201cV\u201d part of the listing.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image7-11.png\" alt=\"image\" width=\"259.996745406824px\" height=\"172.991916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.8 Location of the start button for Visual Studio.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image8-7.png\" alt=\"image\" width=\"624px\" height=\"385.40157480315px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.9 The splash screen during start up.<\/p>\r\n<p class=\"import-Standard\">The opening screen shows your previous work and provides some options.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image9-5.png\" alt=\"image\" width=\"543.983937007874px\" height=\"362.111916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.10 The Visual Studio opening screen.<\/p>\r\n\r\n<h3>Testing Our Connection to the SQL Server<\/h3>\r\n<p class=\"import-Standard\">I used the information provided by the Programmingempire.<\/p>\r\n<p class=\"import-Standard\">Create a new <em>console project<\/em> (a program that does not use a graphic interface (GUI)).<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image10-7.png\" alt=\"image\" width=\"624px\" height=\"46.5983202099738px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.11 Creating a new project.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image11-7.png\" alt=\"image\" width=\"429.129553805774px\" height=\"285.657532808399px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.12 Selecting a console project out of the list of possible project types.<\/p>\r\n<p class=\"import-Standard\">Select C#<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote4anc\" href=\"#sdfootnote4sym\">4<\/a><\/sup> as the desired programming language.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image12-7.png\" alt=\"image\" width=\"168.979107611549px\" height=\"220.991916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.13 The available programming languages.<\/p>\r\n<p class=\"import-Standard\">Fill out the floating dialog box. Figure 13.14 shows a screenshot from my personal computer:<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image13-7.png\" alt=\"image\" width=\"542.323149606299px\" height=\"349.68px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.14 Screenshot of the \u201cConfigure your new project\u201d floating dialog box on my personal computer.<\/p>\r\n<p class=\"import-Standard\">Note: The location line will be different for your computer. There is a checkbox toward the bottom. Do not use it.<\/p>\r\n<p class=\"import-Standard\">Most tutorial websites will recommend using \u201c.NET 7.0 (Standard Term Support) on the \u201cAdditional information\u201d floating dialog box.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image14-6.png\" alt=\"image\" width=\"569.087979002625px\" height=\"218.985511811024px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.15 Selecting the \u201c.NET 7.0 (Standard Term Support)\u201d Framework<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote5anc\" href=\"#sdfootnote5sym\">5<\/a><\/sup>.<\/p>\r\n<p class=\"import-Standard\">Check the \u201cDo not use the top-level statements<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote6anc\" href=\"#sdfootnote6sym\">6<\/a><\/sup>.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image15-7.png\" alt=\"image\" width=\"419.078320209974px\" height=\"190.070341207349px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13. 16 The updated \u201cAdditional information\u201d floating dialog box.<\/p>\r\n<p class=\"import-Standard\">The Visual Studio has enough information to create a starting file.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image16-6.png\" alt=\"image\" width=\"624px\" height=\"116.073595800525px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.17 Screenshot of the generated C# lines.<\/p>\r\n<p class=\"import-Standard\">Look for the \u201cServer Explorer.\u201d It is under the \u201cView\u201d menu tab.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image17-7.png\" alt=\"image\" width=\"257.087979002625px\" height=\"192.076745406824px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.18 Navigating to the \u201cServer Explorer.\u201d<\/p>\r\n<p class=\"import-Standard\">When the \u201cData Connection\u201d is present, then do a right mouse click and select \u201cAdd Connection.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image18-5.png\" alt=\"image\" width=\"407.059107611549px\" height=\"170.083149606299px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.19 Selecting the option for connecting to a current database.<\/p>\r\n<p class=\"import-Standard\">Select the \u201cMicrosoft SQL Server\u201d option from the \u201cChoose Data Source.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image19-5.png\" alt=\"image\" width=\"375.724724409449px\" height=\"288.451128608924px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.20 The opening screen of the \u201cChoose Data Source\u201d dialog box.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image20-5.png\" alt=\"image\" width=\"464.390341207349px\" height=\"364.271916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.21 Selecting the \u201cMicrosoft SQL Server\u201d option.<\/p>\r\n<p class=\"import-Standard\">Another floating dialog box will appear. This is the \u201cAdd Connection\u201d dialog box. It will look for SQL Servers and populate the drop-down menu.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image21-5.png\" alt=\"image\" width=\"624px\" height=\"438.911916010499px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.22 The \u201cAdd Connection\u201d floating dialog box.<\/p>\r\n<p class=\"import-Standard\">In additional, the floating dialog box will populate the names of the dialog box. The \u201cPlease Wait\u201d floating dialog box is blocking view of the \u201cConnect to a database\u201d section.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image22-5.png\" alt=\"image\" width=\"606.537532808399px\" height=\"185.615958005249px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.23 The list of discovered databases on the SQL Server.<\/p>\r\n<p class=\"import-Standard\">If you have installed the AdventureWorks database, then you can select it.<\/p>\r\n<p class=\"import-Standard\">At the bottom of the floating dialog box is a button for testing the connection.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image23-5.png\" alt=\"image\" width=\"362.083149606299px\" height=\"156.019107611549px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.24 The result of testing the connection.<\/p>\r\n<p class=\"import-Standard\">When you hit the \u201cOK\u201d button, the screen will update and display the details from the SQL Server.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image24-5.png\" alt=\"image\" width=\"344.0543832021px\" height=\"263.059107611549px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.25 The Server Explorer shows the connection to the AdventureWorks2022 database.<\/p>\r\n<p class=\"import-Standard\">From inside Visual Studio, you can do some of the basic SQL Server Management Studio tasks.<\/p>\r\n\r\n<h2>Using Microsoft\u2019s Visual Studio for Accessing a DBMS<\/h2>\r\n<p class=\"import-Standard\">It is beyond the scope of this chapter to provide a detailed description of C# coding with objects. And it is beyond the scope of this chapter to teach you how to use Microsoft\u2019s Visual Studio. You will be provided with enough information in order to create a successful program. You will not be writing raw lines. Instead you will be using an <em>Application Programming Interface<\/em> (API) approach whereby you provide input to built-in classes and methods.<\/p>\r\n<p class=\"import-Standard\">In the code template, you need to type the following line as the first executable line:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">using Microsoft.Data.sqlClient;<\/p>\r\n\r\n<h3>Adding the Microsoft.Data.sqlClient Package<\/h3>\r\n<p class=\"import-Standard\">If you receive an error message about this component not existing, then you will need to add the NuGet Package.<\/p>\r\n<p class=\"import-Standard\">Right mouse click on the project name and look for \u201cManage NuGet Packages.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image25-5.png\" alt=\"image\" width=\"395.711916010499px\" height=\"412.953595800525px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.26 First step for adding the missing Microsoft.Data.sqlClient package.<\/p>\r\n<p class=\"import-Standard\">Click on the \u201cBrowse\u201d button. Assuming your computer has an active Internet connection, the list will populate.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image26-5.png\" alt=\"image\" width=\"543.983937007874px\" height=\"338.457532808399px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.27 Opening screen for NuGet.<\/p>\r\n<p class=\"import-Standard\">Once the list has populated, page down until you find \u201cMicrosoft.Data.SqlClient.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image27-4.png\" alt=\"image\" width=\"593.193595800525px\" height=\"396.287979002625px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.28 The populated NuGet list.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image28-8.png\" alt=\"image\" width=\"443.711916010499px\" height=\"101.855958005249px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 1329 The \u201cMicrosoft.Data.SqlClient\u201d piece.<\/p>\r\n<p class=\"import-Standard\">Install the Microsoft.Data.SqlClient.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image29-5.png\" alt=\"image\" width=\"428.937532808399px\" height=\"461.068766404199px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.30 The installation screen for Microsoft.Data.SqlClient.<\/p>\r\n<p class=\"import-Standard\">Follow the prompts.<\/p>\r\n\r\n<h3>Working with the SqlConnection Object<\/h3>\r\n<p class=\"import-Standard\">From Figure 12.24, we can view the <em>connection string<\/em>, which is a series of value pairs that is needed by a program in order to access a database. We need to code this in our program. We need to work with the SqlConnection Object. Understand that the SqlConnection object is used to handle the actual communications between our C# program and the SQL Server database. The SqlConnection Object creates an <em>instance<\/em> (a running example or session) and it is populated with a Connection String. This instance is passed (or shared) with another part of the program. Figure 12.30A shows the connection string template. Figure 12.25B shows an example based on my personal computer.<\/p>\r\n\r\n<table style=\"width: 478.85pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>A<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>string<\/strong> connString = @\"Data Source=\" + datasource + \";Initial Catalog=\" + database + \";Persist Security Info=True;User ID=\" + username + \";Password=\" + password;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>B<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>string <\/strong>connString = \"Data Source=FRED-WINDOWS-10;Initial Catalog=AdventureWorks2022; Integrated Security=True; TrustServerCertificate=True\u201d<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.31 Connection string template and example.<\/p>\r\n<p class=\"import-Standard\">The connection string is passed to the SqlConnectionStringBuilder object:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlConnectionStringBuilder builder= new SqlConnectionStringBuilder(connString)<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote7anc\" href=\"#sdfootnote7sym\">7<\/a><\/sup>;<\/p>\r\n<p class=\"import-Standard\">Then the created builder object is passed to the SqlConnection object:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlConnection connection = new SqlConnection(builder);<\/p>\r\n<p class=\"import-Standard\">Now we can open the connection to the database.<\/p>\r\n<p class=\"import-Standard\">Connection.Open()<\/p>\r\n\r\n<h2>Four Ways for a Program to Work with a Database<\/h2>\r\n<p class=\"import-Standard\">There are four ways of working with a database:<\/p>\r\n\r\n<ul>\r\n \t<li>A concatenated string<\/li>\r\n \t<li>Prepared statements with parameters<\/li>\r\n \t<li>Stored procedures<\/li>\r\n \t<li>Allow-list input validation<\/li>\r\n<\/ul>\r\n<h3>Using a Concatenated String<\/h3>\r\n<p class=\"import-Standard\">Imagine that we wish to select name and collation_name from the sys.databases table. Imagine that we have created a front end that looks similar to Figure 12.31.<\/p>\r\n\r\n<table style=\"width: 478.85pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Type in the desired column names separated by a comma.<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Type in the desired table name.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.32 A fictitious front-end.<\/p>\r\n<p class=\"import-Standard\">Our user fills out the form as shown in Figure 12.32.<\/p>\r\n\r\n<table style=\"width: 478.85pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Type in the desired column names separated by a comma.<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Type in the desired table name.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">name, collation_name<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">sys.databases<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.33 Example entries in the fictitious front-end.<\/p>\r\n<p class=\"import-Standard\">Behind the front-end, the entries are <em>concatenated<\/em> or combined or added to a string:<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">\u201cSELECT<\/span> \u201d + &lt;words from the column name box&gt; + \u201c<span style=\"color: #3366ff\"> FROM<\/span> \u201d + &lt;words from the table name box&gt;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">\u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases\u201d<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">String sql = \u201c <span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases\u201d<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.34 The behind the front-end work.<\/p>\r\n<p class=\"import-Standard\">This string is added to the SqlCommand object and this is sent out to the database for processing:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlCommand command new SqlCommand(sql, connection)<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlDataReader reader = command.ExcuteReader();<\/p>\r\n<p class=\"import-Standard\">This will return a <em>result set <\/em>(the desired rows).<\/p>\r\n<p class=\"import-Standard\">This is bad coding, because a hacker could add another command at the end. Look at Figure 12.35.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">\u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources\u201d<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">String sql = \u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources\u201d<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.35 Example of how a hacker could obtain more data from a database.<\/p>\r\n<p class=\"import-Standard\">This is known as an <em>SQL injection attack<\/em>. There are three additional versions of this attack:<\/p>\r\n\r\n<ul>\r\n \t<li>Use the <span style=\"color: #3366ff\">UNION<\/span> keyword. This combines two SQL statements. This is similar to using a semicolon as shown in Figure 12.34.<\/li>\r\n \t<li>Malformed SQL statement. A SQL Server will return an error message with the desired data.<\/li>\r\n \t<li>Blind SQL attack. The hacker creates queries that return true or false. The hacker inspects the results. Then the hacker crafts a SQL query that will return the desired data.<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">A skillful hacker could access cookies<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote8anc\" href=\"#sdfootnote8sym\">8<\/a><\/sup> on a person\u2019s computer. The hacker could change the contents of the cookie file and cause the query to execute differently.<\/p>\r\n<p class=\"import-Standard\">Some websites will put pieces of a query in the URL. A hacker could change the URL to execute differently.<\/p>\r\n<p class=\"import-Standard\">And a hacker could execute commands that would change the data or add bogus data.<\/p>\r\n<p class=\"import-Standard\">Some database administrators have attempted to stop hackers by requiring the authorized users to add their userid and passwords to the fill-in boxes. The login credentials would be added to the <span style=\"color: #3366ff\">WHERE<\/span> clause. Hackers have defeated this by adding the <span style=\"color: #3366ff\">OR<\/span> connector with a Boolean statement that is always true.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">sql = \"<span style=\"color: #3366ff\">SELECT<\/span> id <span style=\"color: #3366ff\">FROM<\/span> users <span style=\"color: #3366ff\">WHERE<\/span> username='\" + user + \"' <span style=\"color: #3366ff\">AND<\/span> password='\" + pass + \"'\"<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">After the pass variable, add: <span style=\"color: #3366ff\">OR<\/span> 5 = 5<\/p>\r\n<p class=\"import-Standard\">The hacker can type anything for the login credentials and the query will still execute.<\/p>\r\n<p class=\"import-Standard\">These are just some of the ways that a hacker can attack a concatenated string front end. Admir Dizdar\u2019s article covered these examples in greater detail plus provided insights on other exploits.<\/p>\r\n\r\n<h3>Using Prepared Statements with Parameters<\/h3>\r\n<p class=\"import-Standard\">Instead of collecting the user\u2019s entries, we define a parameter or variable for each item.<\/p>\r\n<p class=\"import-Standard\">Instead of a very generic front-end, we will make it narrower.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">To access your account balance, enter your user name<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.36 Revised front-end for collecting a parameter.<\/p>\r\n<p class=\"import-Standard\">Our user fills out the form as in Figure 13.37.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">To access your account balance, enter your user name.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">IamAwonderfulUser<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.37 Example entry in the fictitious front-end.<\/p>\r\n<p class=\"import-Standard\">Behind the front-end, the entries are fed into the parameters and we create a <em>prepared statement<\/em>.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>Java Code<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">String customerName = request.getParameter(\u201cName\u201d)<\/p>\r\n<p class=\"import-Standard\">String sql \u201c<span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName = ?\u201d;<\/p>\r\n<p class=\"import-Standard\">PreparedStatement preparedStatement = connection.prepareStatement (sql);<\/p>\r\n<p class=\"import-Standard\">preparedStatement.setString (1, <span style=\"background-color: #ffff00\">customerName<\/span>);<\/p>\r\n<p class=\"import-Standard\">resultSet results = preparedStatement.executeQuery();<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>C# Code<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">String sql \u201c<span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName = @userName\u201d;<\/p>\r\n<p class=\"import-Standard\">using (SqlCommand command new SqlCommand(sql, connection);<\/p>\r\n<p class=\"import-Standard\">command.Parameters.AddWithValue(\u201d@userName\u201d,<span style=\"background-color: #ffff00\"> customerName<\/span>;<\/p>\r\n<p class=\"import-Standard\">using (SqlDataReader reader = command.ExecuteReader())<\/p>\r\n<p class=\"import-Standard\">while (reader.Read()<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">\/\/ retrieve the data.<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The value stored in sql is: <span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName \u201cIamAwonderfulUser\u201d;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.38 The behind the front-end work with the variable customerName<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote9anc\" href=\"#sdfootnote9sym\">9<\/a><\/sup> is connected to the front-end.<\/p>\r\n<p class=\"import-Standard\">Suppose the hacker adds something extra to the name box.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">IamAwonderfulUser; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources;<\/p>\r\n<p class=\"import-Standard\">The query would become:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName \u201cIamAwonderfulUser; SELECT * FROM HumanResources;\u201d<\/p>\r\n<p class=\"import-Standard\">The system would look for a person with the name of \u201cIamAwonderfulUser; SELECT * FROM HumanResources;\u201d The search fails since there is no person in the database with that name!<\/p>\r\n\r\n<h3>Using Stored Procedures<\/h3>\r\n<p class=\"import-Standard\">Prepared statements work with the actual SQL command inside the programming language. <em>Stored procedures<\/em> work with the actual SQL command inside the database environment. The approach is similar in that data parameters are collected and are sent to the database. The difference is that you need to define the name of each parameter.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>Java Code Example using a Single Parameter<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">\/\/ Separate definition of user inputs<\/p>\r\n<p class=\"import-Standard\">String custname = request.getParameter(\"customerName\");<\/p>\r\n<p class=\"import-Standard\">\/\/ Executing the stored procedure sp_getAccountBalancer<\/p>\r\n<p class=\"import-Standard\">try {<\/p>\r\n<p class=\"import-Standard\">CallableStatement cs = connection.prepareCall(\"{call sp_getAccountBalance(?)}\");<\/p>\r\n<p class=\"import-Standard\">cs.setString(1, custname);<\/p>\r\n<p class=\"import-Standard\">ResultSet results = cs.executeQuery();<\/p>\r\n<p class=\"import-Standard\">\/\/ result set handling<\/p>\r\n<p class=\"import-Standard\">} catch (SQLException se) {<\/p>\r\n<p class=\"import-Standard\">\/\/ logging and error handling<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>C# Code Example Using More Than One Parameter<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">command.CommandText = \"HumanResources.uspGetEmployeesTest2\";<\/p>\r\n<p class=\"import-Standard\">\/\/ This tells the environment that we are working with a stored procedure.<\/p>\r\n<p class=\"import-Standard\">command.CommandType = CommandType.StoredProcedure;<\/p>\r\n<p class=\"import-Standard\">\/\/ Add the input parameter and set its properties.<\/p>\r\n<p class=\"import-Standard\">SqlParameter parameter = new SqlParameter();<\/p>\r\n<p class=\"import-Standard\">parameter.ParameterName = \"@FirstName\";<\/p>\r\n<p class=\"import-Standard\">parameter.SqlDbType = SqlDbType.NVarChar;<\/p>\r\n<p class=\"import-Standard\">parameter.Direction = ParameterDirection.Input;<\/p>\r\n<p class=\"import-Standard\">parameter.Value = \"Pilar\"; \/\/ FirstName. The value is provided to the stored procedure.<\/p>\r\n<p class=\"import-Standard\">command.Parameters.Add(\"@FirstName\", SqlDbType.NVarChar).Value = \"Pilar\";<\/p>\r\n<p class=\"import-Standard\">parameter.ParameterName = \"@LastName\";<\/p>\r\n<p class=\"import-Standard\">parameter.SqlDbType = SqlDbType.NVarChar;<\/p>\r\n<p class=\"import-Standard\">parameter.Direction = ParameterDirection.Input;<\/p>\r\n<p class=\"import-Standard\">parameter.Value = \"Ackerman\"; \/\/ LastName. The value is provided to the stored procedure.<\/p>\r\n<p class=\"import-Standard\">command.Parameters.Add(\"@LastName\", SqlDbType.NVarChar).Value = \"Ackerman\";<\/p>\r\n<p class=\"import-Standard\">\/\/ Open the connection and execute the reader.<\/p>\r\n<p class=\"import-Standard\">connection.Open();<\/p>\r\n<p class=\"import-Standard\">try<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">using (SqlDataReader reader = command.ExecuteReader())<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">if (reader.HasRows)<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">while (reader.Read())<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">Console.WriteLine(\"{0}: {1:C}\", reader[0], reader[1]);<\/p>\r\n<p class=\"import-Standard\">Console.WriteLine(reader[\"FirstName\"] + \" \" + reader[\"LastName\"] + \" in \" + reader[\"Department\"]);<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\">else<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">Console.WriteLine(\"No rows found.\");<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\">reader.Close();<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\">catch (SqlException ex)<\/p>\r\n<p class=\"import-Standard\">{<\/p>\r\n<p class=\"import-Standard\">Console.WriteLine(\"Inside the catch block. \" + ex);<\/p>\r\n<p class=\"import-Standard\">}<\/p>\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.39 Java and C# examples using a stored procedure.<\/p>\r\n\r\n<h3>Using Allow-List Input Validation<a id=\"_Hlk180124495\"><\/a><\/h3>\r\n<p class=\"import-Standard\">The user inputs are validated in some fashion.<\/p>\r\n<p class=\"import-Standard\">One approach is to use drop down lists. This is done for postal information (such the two-letter codes used in North America), for dates, for gender, and for other known lists of values.<\/p>\r\n<p class=\"import-Standard\">A <em>regular expression<\/em> could be used. A regular expression does a pattern match against permitted or not permitted characters. For example, a regular expression could be used to handle all of the current forms of ten-digit telephone numbers as used in North America:<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]\\d{3}[\\s.-]\\d{4}$<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">123-456-7890<\/p>\r\n<p class=\"import-Standard\">(123) 456-7890<\/p>\r\n<p class=\"import-Standard\">123 456 7890<\/p>\r\n<p class=\"import-Standard\">123.456.7890<\/p>\r\n<p class=\"import-Standard\">+91 (123) 456-7890<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.40 A regular expression for finding valid ten-digit telephone numbers.<\/p>\r\n<p class=\"import-Standard\">Support for regular expressions is found in every programming language such as C++, C#, Java, and others. Many editing programs use regular expressions. There are many resources for learning more about this topic.<\/p>\r\n\r\n<ul>\r\n \t<li>\u201cRegex Tutorial \u2013 How to write Regular Expressions?\u201d Geeks for Geeks, April 12, 2024. (<a class=\"rId36\" href=\"https:\/\/www.geeksforgeeks.org\/write-regular-expressions\/\">https:\/\/www.geeksforgeeks.org\/write-regular-expressions\/<\/a>)<\/li>\r\n \t<li>Regular expressions 101 (<a class=\"rId37\" href=\"https:\/\/regex101.com\/\">https:\/\/regex101.com<\/a>)<\/li>\r\n \t<li>Regex (<a class=\"rId38\" href=\"https:\/\/regexr.com\">https:\/\/regexr.com<\/a>)<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">The various environments may have slightly different regular expression rules.<\/p>\r\n<p class=\"import-Standard\">Validating user input should be included for prepared statements and for stored procedures.<\/p>\r\n\r\n<h2>Templates<\/h2>\r\n<p class=\"import-Standard\">Templates exist in the SQL Server Management Studio. These are found inside the View tab.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image30-4.png\" alt=\"image\" width=\"624px\" height=\"471.686299212598px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.41 Screenshot of the path to the SQL Server Management Studio templates. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">Select a template and do a right mouse click to open it up.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image31-3.png\" alt=\"image\" width=\"324.739107611549px\" height=\"570.863937007874px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.42 Opening up the \u201cCreate Database\u201d template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">A query window will open with the T-SQL script present.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image32-4.png\" alt=\"image\" width=\"400.060787401575px\" height=\"237.052703412073px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.43 Test of the \u201cCreate Database\u201d template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">You can modify the template and then execute it.<\/p>\r\n<p class=\"import-Standard\">If you wish to make the changes permanent, then you can edit the selected template.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image33-3.png\" alt=\"image\" width=\"332.937532808399px\" height=\"462.652703412073px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.44 The editing option. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">After the changes are made, then select File Save.<\/p>\r\n<p class=\"import-Standard\">Reopening the template view will show the revised changes.<\/p>\r\n<p class=\"import-Standard\">Creating a new template involves using the New folder steps. Look for \u201cCustom Templates.\u201d<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image34-3.png\" alt=\"image\" width=\"624px\" height=\"341.52px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.45 The create new template option. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">Right mouse click on \u201cCustom Templates\u201d and select the New Template path. Enter a useful name.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image35-4.png\" alt=\"image\" width=\"624px\" height=\"415.74719160105px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.46 Continuing the steps for creating a new template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">Enter the T-SQL lines. When finished, hit File Save.<\/p>\r\n\r\n<h2>Functions<\/h2>\r\n<p class=\"import-Standard\">In the chapter on SQL commands, we worked with AVG (), with COUNT(), with MAX(), with MIN(), and with others. These were SQL <em>functions<\/em>. The W3 schools website has grouped the Microsoft SQL Server functions in this fashion:<\/p>\r\n\r\n<ul>\r\n \t<li>SQL Server String Functions<\/li>\r\n \t<li>SQL Server Math\/Numeric Functions<\/li>\r\n \t<li>SQL Server Date Functions<\/li>\r\n \t<li>SQL Server Advanced Functions<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">The SQL Server Advanced functions provide solutions to challenging problems. CAST() and CONVERT() will change a value from one data type to another data type. For example, you could change a decimal to a whole number. Or you could change a string representing a number to a numeric that could be manipulated with mathematical operators.<\/p>\r\n<p class=\"import-Standard\">When working with NULLs, the Math\/Numeric functions will have strange results. The COALESCE function will solve this issue. The W3 schools COALESCE function web page does not explain this function fully. The following will render NULLs as zeros:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> <span style=\"color: #3366ff\">COALESCE<\/span>(TotalAmount, 0) <span style=\"color: #3366ff\">FROM<\/span> Products;<\/p>\r\n<p class=\"import-Standard\">Microsoft recommends using the following approach:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> isnull(TotalAmount 0) <span style=\"color: #3366ff\">AS<\/span> TotalAmount <span style=\"color: #3366ff\">FROM<\/span> Products;<\/p>\r\n<p class=\"import-Standard\">As the Microsoft writer explained in the 2008 article, COALESCE is based on the ANSI SQL standard whereas the ISNULL is a Microsoft proprietary T-SQL function.<\/p>\r\n<p class=\"import-Standard\">Troels Arvin has put together a web page that compares the different SQL implementations against the SQL 2008 standard.<\/p>\r\n\r\n<h2>Triggers<\/h2>\r\n<p class=\"import-Standard\">Recall the Chapter 9 section about cascading updates and deletes (\u201cDDL: CREATE TABLE with the Cascading Update and Cascading Delete\u201d). These are examples of DML <em>triggers<\/em>. Again, these are invoked automatically in response to INSERT, UPDATE, and DELETE events against database tables.<\/p>\r\n<p class=\"import-Standard\">There are two more types of triggers:<\/p>\r\n\r\n<ul>\r\n \t<li>DDL triggers. These react to CREATE, ALTER, and DROP statements.<\/li>\r\n \t<li>Some system defined stored procedures would cause a DDL trigger to fire.<\/li>\r\n \t<li>Logon triggers<\/li>\r\n<\/ul>\r\n<h3>Creating DML Triggers<\/h3>\r\n<p class=\"import-Standard\">Figure 13.47 shows the syntax for a create trigger statement:<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">CREATE<\/span> <span class=\"import-hljs-keyword\">TRIGGER<\/span> <\/span>[schema_name.]trigger_name<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> table_name<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AFTER<\/span> {[<span class=\"import-hljs-keyword\">INSERT<\/span>],[<span class=\"import-hljs-keyword\">UPDATE<\/span>],[<span class=\"import-hljs-keyword\">DELETE<\/span>]}<\/p>\r\n<p class=\"import-Standard\">[<span class=\"import-hljs-keyword\">NOT<\/span> <span class=\"import-hljs-keyword\">FOR<\/span> <span class=\"import-hljs-keyword\">REPLICATION<\/span>]<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\">{sql_statements}<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.47 Create trigger syntax. (The text was not changed to conform with our style guide.) Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">SQL Server has two predefined tables that support triggers. One table is for insert events and the other table is for delete events. These are used to capture the data before and after an action. Figure 13.48 explains how these work.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>DML event<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>INSERTED table holds<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><strong>DELETED table holds<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">INSERT<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">rows to be inserted<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">empty<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">UPDATE<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">new rows modified by the update<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">existing rows modified by the update<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">DELETE<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">empty<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">rows to be deleted<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.48 INSERTED and DELETED tables Source of table notes: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">SQLServer Tutorial.net has a nice example. The following is that example with changes to follow our style guide.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Production.Products<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">ID<\/p>\r\n<p class=\"import-Standard\">Name<\/p>\r\n<p class=\"import-Standard\">BrandID<\/p>\r\n<p class=\"import-Standard\">CategoryID<\/p>\r\n<p class=\"import-Standard\">ModelYear<\/p>\r\n<p class=\"import-Standard\">ListPrice<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.49 SQLServer Tutorial.net example table that has been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">We need a table for logging the changes to the Production.Products table. We are naming this table as Production.ProductAudits<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE TABLE<\/span> Production.ProductAudits(<\/p>\r\n<p class=\"import-Standard\">Id INT IDENTITY PRIMARY KEY,<\/p>\r\n<p class=\"import-Standard\">ProductId INT NOT NULL,<\/p>\r\n<p class=\"import-Standard\">ProductName VARCHAR(255) NOT NULL,<\/p>\r\n<p class=\"import-Standard\">BrandId INT NOT NULL,<\/p>\r\n<p class=\"import-Standard\">CategoryId INT NOT NULL,<\/p>\r\n<p class=\"import-Standard\">ModelYear SMALLINT NOT NULL,<\/p>\r\n<p class=\"import-Standard\">ListPrice DEC(10,2) NOT NULL,<\/p>\r\n<p class=\"import-Standard\">UpdatedAt DATETIME NOT NULL,<\/p>\r\n<p class=\"import-Standard\">Operation CHAR(3) NOT NULL,<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CHECK<\/span><sup class=\"import-FootnoteReference\"><a id=\"sdfootnote10anc\" href=\"#sdfootnote10sym\">10<\/a><\/sup>(Operation = 'INS' or Operation='DEL')<\/p>\r\n<p class=\"import-Standard\">);<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.50 SQLServer Tutorial.net example changes tracking table that has been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">Now, we need to create a trigger. Figure 12.51 has the trigger code with explanations.<\/p>\r\n\r\n<table style=\"width: 478.85pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE TRIGGER<\/span> Production.TriggerProductAudit<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">\u201cProduction\u201d is the schema name and it is optional.<\/p>\r\n<p class=\"import-Standard\">The trigger name is defined by the author.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">ON<\/span> Production.Products<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The keyword<span style=\"color: #3366ff\"> ON<\/span> precedes the name of the table that we wish to define a trigger for.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AFTER<\/span> INSERT, DELETE<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The keyword <span style=\"color: #3366ff\">AFTER<\/span> states that the trigger will fire after an event (INSERT, UPDATE, or DELETE). Here we are stating that we want this trigger to fire for all inserts and for all deletes.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The \u201cNOT FOR REPLICATION\u201d option instructs the SQL Server not to fire the trigger when data modification is made as part of a replication process<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote11anc\" href=\"#sdfootnote11sym\">11<\/a><\/sup>.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\" style=\"height: 31pt\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">BEGIN<\/span><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Ends the instructions and marks the beginning of the actual SQL lines.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">SET NOCOUNT ON;<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">We do not want a row report to be sent to the calling agent.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">INSERT INTO<\/span><\/p>\r\n<p class=\"import-Standard\">Production.ProductAudits<\/p>\r\n<p class=\"import-Standard\">(<\/p>\r\n<p class=\"import-Standard\">ProductId,<\/p>\r\n<p class=\"import-Standard\">ProductName,<\/p>\r\n<p class=\"import-Standard\">BrandId,<\/p>\r\n<p class=\"import-Standard\">CategoryId,<\/p>\r\n<p class=\"import-Standard\">ModelYear,<\/p>\r\n<p class=\"import-Standard\">ListPrice,<\/p>\r\n<p class=\"import-Standard\">UpdatedAt,<\/p>\r\n<p class=\"import-Standard\">Operation<\/p>\r\n<p class=\"import-Standard\">)<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span><\/p>\r\n<p class=\"import-Standard\">i.ProductId,<\/p>\r\n<p class=\"import-Standard\">ProductName,<\/p>\r\n<p class=\"import-Standard\">BrandId,<\/p>\r\n<p class=\"import-Standard\">CategoryId,<\/p>\r\n<p class=\"import-Standard\">ModelYear,<\/p>\r\n<p class=\"import-Standard\">i.ListPrice,<\/p>\r\n<p class=\"import-Standard\">GETDATE(),<\/p>\r\n<p class=\"import-Standard\">'INS'<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span><\/p>\r\n<p class=\"import-Standard\">Inserted <span style=\"color: #3366ff\">AS<\/span> i<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">UNION ALL<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span><\/p>\r\n<p class=\"import-Standard\">d.ProductId,<\/p>\r\n<p class=\"import-Standard\">ProductName,<\/p>\r\n<p class=\"import-Standard\">BrandId,<\/p>\r\n<p class=\"import-Standard\">CategoryId,<\/p>\r\n<p class=\"import-Standard\">ModelYear,<\/p>\r\n<p class=\"import-Standard\">d.ListPrice,<\/p>\r\n<p class=\"import-Standard\">GETDATE(),<\/p>\r\n<p class=\"import-Standard\">'DEL'<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span><\/p>\r\n<p class=\"import-Standard\">Deleted <span style=\"color: #3366ff\">AS<\/span> d;<\/p>\r\n<p class=\"import-Standard\">END<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">We are listing the target columns.<\/p>\r\n<p class=\"import-Standard\">When the values are coming from a database table, then the keyword VALUES is not used<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote12anc\" href=\"#sdfootnote12sym\">12<\/a><\/sup>. We are drawing from the Inserted system table and from the Deleted system table.<\/p>\r\n<p class=\"import-Standard\">SQLServer Tutorial.net writer aliased these two tables and used these for the product ID and for the list price<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote13anc\" href=\"#sdfootnote13sym\">13<\/a><\/sup>.<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">UNION ALL<\/span> retains duplicated actions.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.51 SQLServer Tutorial.net example trigger creation lines that have been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">You must execute the code. Then it will be added to the list of triggers. Figure 12.52 shows the location of this new trigger.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image36-2.jpeg\" alt=\"image\" width=\"375.80157480315px\" height=\"357.465511811024px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.52 SQLServer Tutorial.net example showing where it would be stored in a database.. Source of image: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n<p class=\"import-Standard\">If something is added to this table, the trigger would fire. If something is deleted from this table, the trigger would fire. Here is the output from the ProductAudits table:<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image37-3.jpeg\" alt=\"image\" width=\"624px\" height=\"55.8623622047244px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.53 SQLServer Tutorial.net example showing the output for two actions.. Source of image: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\r\n\r\n<h3>Creating DDL Triggers<\/h3>\r\n<p class=\"import-Standard\">SQL Server DDL triggers can react to database events such as <span style=\"color: #3366ff\">CREATE, ALTER, DROP, GRANT, DENY, REVOKE<\/span>, and <span style=\"color: #3366ff\">UPDATE<\/span> <span style=\"color: #3366ff\">STATISTICS<\/span>. DDL triggers are useful for recording changes to the database scheme. Instead of pulling from the Inserted system table or from the Deleted system table, you would execute the EVENTDATA() function and capture the output into the user created event tracking table. For a detailed example, see the reference for the URL.<\/p>\r\n\r\n<h3>Creating Logon Triggers<\/h3>\r\n<p class=\"import-Standard\">A logon trigger can be used for five purposes:<\/p>\r\n\r\n<ul>\r\n \t<li>Restrict users to only login at certain times.<\/li>\r\n \t<li>Restrict number of concurrent sessions for a specific login.<\/li>\r\n \t<li>Restrict total number of connections.<\/li>\r\n \t<li>Restrict login by host name or IP Address.<\/li>\r\n \t<li>Use a logon trigger for auditing.<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">The syntax is similar to the DML trigger.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE OR ALTER TRIGGER<\/span> [Name of Trigger]<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">ON<\/span> ALL SERVER<\/p>\r\n<p class=\"import-Standard\">FOR LOGON<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\">BEGIN<\/p>\r\n<p class=\"import-Standard\">-------------<\/p>\r\n<p class=\"import-Standard\">END<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.54 MSSQL Tips showing the basic syntax for working with a logon trigger.. Source of T-SQL: https:\/\/www.mssqltips.com\/sqlservertip\/6103\/sql-server-logon-trigger-examples\/<\/p>\r\n<p class=\"import-Standard\">If the logon trigger is built incorrectly, you could find yourself locked out of your own database. Bhavesh Patel has an example for each of the five use cases.<\/p>\r\n<p class=\"import-Standard\">We did not address the fact that SQL Server has triggers in the Template Explorer. See Figure 13.41 for the location of the Database Trigger folder. See Figure 13.45 for the location of the general Trigger folder.<\/p>\r\n\r\n<h2>Stored Procedures<\/h2>\r\n<p class=\"import-Standard\">Stored procedures were mentioned earlier in the chapter as one of four ways for a program to work with a database. We did not explore the benefits and drawbacks of using a stored procedure. Nor did we explore how to create a stored procedure. We will address these points in this section.<\/p>\r\n\r\n<h3>The Big Debate<\/h3>\r\n<p class=\"import-Standard\">There are forums that have debated the question of which is better. There are well-written articles that attempt to show both sides. Some individuals point out that the advance of technology has rendered some reasons as moot. Do not expect this section to be the be-all-and-end-all on this topic. The following lists are some of the points made by individuals on different sides of this debate.<\/p>\r\n\r\n<h4>The Pros of using stored procedures.<\/h4>\r\n<ul>\r\n \t<li>These support modular programming.<\/li>\r\n \t<li>These allow faster execution.<\/li>\r\n \t<li>These reduce the volume of network traffic.<\/li>\r\n \t<li>These add another layer of security.<\/li>\r\n \t<li>The application developer can concentrate on the code while the database programmer can create the stored procedures.<\/li>\r\n \t<li>Changes made to the stored procedures do not require the source code to be recompiled. This is assuming that the stored procedures have the same parameter list.<\/li>\r\n \t<li>Older versions of SQL Server could not optimize SQL statements from a program, but could do it for stored procedures.\r\n<ul>\r\n \t<li>New versions of SQL Server support statement-level optimization.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Stored procedures can be invoked by numerous applications and programs.<\/li>\r\n \t<li>Query statements can be inspected without the need for the program to be executing.<\/li>\r\n<\/ul>\r\n<h4>The Cons of using stored procedures.<\/h4>\r\n<ul>\r\n \t<li>Stored procedures tend to bloat. New stored procedures are added, but old ones rarely are deleted.<\/li>\r\n \t<li>There is no documentation that states who might use a specific stored procedure. There is the fear that removing a stored procedure might break something.<\/li>\r\n \t<li>If the stored procedure is using dynamic SQL, then parameterized queries can be used to launch an SQL injection attack.\r\n<ul>\r\n \t<li>A well-designed program block would support the generation of SQL code on the fly.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Writers may not encapsulate pieces. This makes working with and debugging the stored procedures difficult.<\/li>\r\n \t<li>Fake data cannot be used in a stored procedure.\r\n<ul>\r\n \t<li>Testing out a stored procedure requires against some database tables. So a testing database is needed.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>A database administrator would need to conduct performance tuning.<\/li>\r\n \t<li>Stored procedures tend to be based on a specific DBMS. Changing to a different DBMS would require rewriting the stored procedures.<\/li>\r\n \t<li>If a function is <em>deprecated<\/em> (planned removal), then any stored procedures using that function will not work.<\/li>\r\n \t<li>Source control is difficult to do for stored procedures. (Some individuals disagree with this statement.)<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">There have been efforts to add an object relational model support (Entity Framework). This gets into Code-First and Database-First mappings of a database to programming classes. The Language Integrated Query (LINQ) that works with LAMBDA expressions generates lines that resemble SQL syntax. For a time, it looked like Microsoft was dropping LINQ. Then they changed and now it is being improved in every release of .NET. In a blog, there was a paragraph about a situation when LINQ could greatly increase the generated code size.<\/p>\r\n<p class=\"import-Standard\">For this edition, we will not explore LINQ. When LINQ is more stable and more mainstream, then we will consider adding more information about LINQ.<\/p>\r\n\r\n<h3>Creating Stored Procedures<\/h3>\r\n<p class=\"import-Standard\">Microsoft has developed two ways of creating a stored procedure within the SQL Server Management Studio.<\/p>\r\n<p class=\"import-Standard\">The first way is using the GUI support. Recall that the Template Explorer was at a high level above the individual databases. For creating a stored procedure, it is more linked to the current working database.<\/p>\r\n<p class=\"import-Standard\">You would work down to the Programmability folder. Figure 13.55 is a screenshot of a database using VisualBasic. Our C# example would be similar.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image38-1.jpeg\" alt=\"image\" width=\"624px\" height=\"351.08157480315px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.55 A screenshot of the \u201cObject Explorer\u201d tree with the \u201cProgrammability\u201d folder visible. Source of image: https:\/\/i.ytimg.com\/vi\/7ZwcfvUYkTg\/maxresdefault.jpg<\/p>\r\n<p class=\"import-Standard\">Expanding the Programmability folder will reveal the Stored Procedure folder. The first folder has the System Stored Procedures. See Figure 13.56.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image39-3.png\" alt=\"image\" width=\"516.739107611549px\" height=\"544.329553805774px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.56 Screenshot of part of the items in the Programmability folder. Source of image: https:\/\/i.sstatic.net\/7piek.png<\/p>\r\n<p class=\"import-Standard\">You would do a right mouse click on the Stored Procedures folder. You would select New Stored Procedure. A new query window would appear with boilerplate lines for the new stored procedure.<\/p>\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image40-3.png\" alt=\"image\" width=\"624px\" height=\"307.353595800525px\" \/><\/p>\r\n<p class=\"import-Standard\">Figure 13.57 Screenshot of the boilerplate stored procedure text. Source of image: https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/<\/p>\r\n<p class=\"import-Standard\">On the Query menu, select Specify Values for Template Parameters. Figure 12.58 shows the example entries.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Author<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">Name<\/span>\u00a0with your name.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Create Date<\/strong>: Enter today's date.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Description<\/strong>: Briefly describe what the procedure does.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Procedure_Name<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">ProcedureName<\/span>\u00a0with the new stored procedure name.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Param1<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">@p1<\/span>\u00a0with your first parameter name, such as\u00a0<em class=\"import-Emphasis\">@ColumnName1<\/em>.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Datatype_For_Param1<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">int<\/span>\u00a0with your first parameter's datatype, such as\u00a0<em class=\"import-Emphasis\">nvarchar<\/em><em class=\"import-Emphasis\">(<\/em><em class=\"import-Emphasis\">50)<\/em>.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Default_Value_For_Param1<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">0<\/span>\u00a0with your first parameter's default value, or\u00a0<em class=\"import-Emphasis\">NULL<\/em>.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Param2<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">@p2<\/span>\u00a0with your second parameter name, such as\u00a0<em class=\"import-Emphasis\">@ColumnName2<\/em>.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Datatype_For_Param2<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">int<\/span>\u00a0with your second parameter's datatype, such as\u00a0<em class=\"import-Emphasis\">nvarchar<\/em><em class=\"import-Emphasis\">(<\/em><em class=\"import-Emphasis\">50)<\/em>.<\/p>\r\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Default_Value_For_Param2<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">0<\/span>\u00a0with your second parameter's default value, or\u00a0<em class=\"import-Emphasis\">NULL<\/em>.<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image41-3.png\" alt=\"image\" width=\"372.92157480315px\" height=\"252.287979002625px\" \/><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">A. Suggested Example Text<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">B. Screenshot of the completed floating dialog box.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.58 The Specify Values for Template Parameters dialog box. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16<\/p>\r\n<p class=\"import-Standard\">When finished, hit \u201cOK.\u201d<\/p>\r\n<p class=\"import-Standard\">You would be doing the actual editing inside the Query Editor. Figure 13.59 shows the example stored procedure.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- =======================================================<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Create Stored Procedure Template for Azure SQL Database<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- =======================================================<\/span><\/p>\r\n<p class=\"import-Standard\">SET ANSI_NULLS ON<\/p>\r\n<p class=\"import-Standard\">GO<\/p>\r\n<p class=\"import-Standard\">SET QUOTED_IDENTIFIER ON<\/p>\r\n<p class=\"import-Standard\">GO<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- =============================================<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Author: My Name<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Create Date: 01\/23\/2024<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Description: Returns the customer's company name.<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- =============================================<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> SalesLT.uspGetCustomerCompany<\/p>\r\n<p class=\"import-Standard\">(<\/p>\r\n<p class=\"import-Standard\">-- Add the parameters for the stored procedure here<\/p>\r\n<p class=\"import-Standard\">@LastName nvarchar(50) = NULL,<\/p>\r\n<p class=\"import-Standard\">@FirstName nvarchar(50) = NULL<\/p>\r\n<p class=\"import-Standard\">)<\/p>\r\n<p class=\"import-Standard\">AS<\/p>\r\n<p class=\"import-Standard\">BEGIN<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- SET NOCOUNT ON added to prevent extra result sets from<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- interfering with SELECT statements.<\/span><\/p>\r\n<p class=\"import-Standard\">SET NOCOUNT ON<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Insert statements for procedure here<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> SalesLT.Customer<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName AND LastName = @LastName;<\/p>\r\n<p class=\"import-Standard\">END<\/p>\r\n<p class=\"import-Standard\">GO<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.59 The final version of the running example.<\/p>\r\n<p class=\"import-Standard\">The Query menu has a Parse button that will check for syntax errors.<\/p>\r\n<p class=\"import-Standard\">Executing these lines will create the actual stored procedure and will store it as an object in the database. Revisit the Stored Procedure and select Refresh.<\/p>\r\n<p class=\"import-Standard\">To execute the new stored procedure, do a right mouse click on the stored procedure name and select Execute Stored Procedure. In the Execute Procedure window, you will need to enter some values for the blank parameters. Then hit the OK button.<\/p>\r\n<p class=\"import-Standard\">If you were using the Microsoft\u2019s AdventureWorksLT2022 database, then entering \u201cCannon\u201d for the @LastName parameter and \u201cChris\u201d for the @FirstName parameter would yield the following output:<\/p>\r\n<p class=\"import-Standard\">Chris Cannon Outdoor Sporting Goods<\/p>\r\n<p class=\"import-Standard\">The second way is using only the Transact-SQL lines. You would have the same text as Figure 13.59 without the comment lines. You would enter these lines manually.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> SalesLT.uspGetCustomerCompany1<\/p>\r\n<p class=\"import-Standard\">@LastName nvarchar(50),<\/p>\r\n<p class=\"import-Standard\">@FirstName nvarchar(50)<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\">SET NOCOUNT ON;<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM S<\/span>alesLT.Customer<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName <span style=\"color: #3366ff\">AND<\/span> LastName = @LastName;<\/p>\r\n<p class=\"import-Standard\">GO<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.60 The raw Transact-SQL lines.<\/p>\r\n<p class=\"import-Standard\">Rajendra Gupta\u2019s article is based on an older version of the SQL Server Management Studio.<\/p>\r\n<p class=\"import-Standard\">The sources used for this section did not explain the actual lines. Also, the sources did not explain that the text of the created stored procedure is different from the creation command lines.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\" style=\"text-align: center\"><strong>Extracted lines from the Microsoft Stored Procedure Example<\/strong><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\" style=\"text-align: center\"><strong>An Explanation<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- ======================================<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Create Stored Procedure Template for Azure SQL Database<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- ======================================<\/span><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Most programming languages use a pair of right leaning slant bars to start a comment. In SQL, it is a pair of hyphens (U+0045).<\/p>\r\n<p class=\"import-Standard\">SQL Server Management Studio uses green font to show that a line is not an executable line.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">SET ANSI_NULLS ON<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">When ANSI_NULLS is ON, a <span style=\"color: #3366ff\">SELECT<\/span> statement that uses <span style=\"color: #3366ff\">WHERE<\/span> column_name = NULL returns zero rows even if there are NULL values in <em>column_name<\/em>. A <span style=\"color: #3366ff\">SELECT<\/span> statement that uses WHERE column_name &lt;&gt; NULL returns zero rows even if there are non-NULL values in <em>column_name<\/em>.<\/p>\r\n<p class=\"import-Standard\">Prior to SQL Server 2017, the OFF option would have returned rows with NULL values.<\/p>\r\n<p class=\"import-Standard\">Beginning with SQL Server 2017, the OFF option has been deprecated.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">GO<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">Recall that Microsoft SQL came from the Sybase database environment. Over time, new features were added, but the GO statement was retained<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote14anc\" href=\"#sdfootnote14sym\">14<\/a><\/sup>.<\/p>\r\n<p class=\"import-Standard\">The GO command is used inside the Transit-SQL code when batches are being processed. It is not a true SQL command. It is recognized by the SQL Server Management Studio and by other SQL Server tools.<\/p>\r\n<p class=\"import-Standard\">Attempting to create two stored procedures would require placing the word GO between the two.<\/p>\r\n<p class=\"import-Standard\">Changing to a different database would require the word GO.<\/p>\r\n<p class=\"import-Standard\">Locally declared variables exist only between the GO words.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">SET QUOTED_IDENTIFIER ON<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">This is the default setting.<\/p>\r\n<p class=\"import-Standard\">OFF would treat single quotes and double quote strings the same.<\/p>\r\n<p class=\"import-Standard\">ON would instruct the SQL Server to treat values inside a pair of double quotes an identifier<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote15anc\" href=\"#sdfootnote15sym\">15<\/a><\/sup>.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">GO<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">This follows the end of a batch.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- ======================================<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Author: My Name<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Create Date: 01\/23\/2024<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Description: Returns the customer's company name.<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- ======================================<\/span><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The generated stored procedure template has a spot for adding your name and a short description of the purpose for the stored procedure.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">CREATE PROCEDURE SalesLT.uspGetCustomerCompany<\/p>\r\n<p class=\"import-Standard\">(<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Add the parameters for the stored procedure here<\/span><\/p>\r\n<p class=\"import-Standard\">@LastName nvarchar(50) = NULL,<\/p>\r\n<p class=\"import-Standard\">@FirstName nvarchar(50) = NULL<\/p>\r\n<p class=\"import-Standard\">)<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">This is the header for the created block. It contains the name of the table and the name of the stored procedure. The \u201cusp\u201d is a convention that is used to identify a <strong>u<\/strong>ser defined <strong>s<\/strong>tored <strong>p<\/strong>rocedure.<\/p>\r\n<p class=\"import-Standard\">The at symbol (@) identifies the name of a variable.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">This is not explained, but based on the use of this word as a key word for changing the name of an output, it appears this is stating that the parameters will be used in the following block.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">BEGIN<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- SET NOCOUNT ON added to prevent extra result sets from<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- interfering with SELECT statements.<\/span><\/p>\r\n<p class=\"import-Standard\">SET NOCOUNT ON<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">-- Insert statements for procedure here<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> SalesLT.Customer<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName <span style=\"color: #3366ff\">AND<\/span> LastName = @LastName;<\/p>\r\n<p class=\"import-Standard\">END<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">The actual lines are inside a BEGIN-END block. These two key words are optional. Many programming languages use curved braces. Wirth based languages such as Algo, Pascal, and Modula family do use the BEGIN-END markers<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote16anc\" href=\"#sdfootnote16sym\">16<\/a><\/sup>.<\/p>\r\n<p class=\"import-Standard\">When the SQL query is executed, it may report on how many lines are in the result set. The SET NOCOUNT ON will prevent this message from being generated.<\/p>\r\n<p class=\"import-Standard\">The last few lines are the actual SQL lines.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">GO<\/p>\r\n<\/td>\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.61 The raw Transact-SQL lines with explanations.<\/p>\r\n<p class=\"import-Standard\">Another way of executing a stored procedure is with the EXEC command:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">EXEC SalesLT.uspGetCustomerCompany @FirstName = \u201cChris\u201d @LastName = \u201cCannon\u201d<\/p>\r\n<p class=\"import-Standard\">The EXEC is optional. You could execute the stored procedure by simply typing the name of the stored procedure:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SalesLT.uspGetCustomerCompany @FirstName = \u201cChris\u201d @LastName = \u201cCannon\u201d<\/p>\r\n<p class=\"import-Standard\">Just like you can drop tables, you can drop stored procedures:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">DROP PROCEDURE<\/span> SalesLT.uspGetCustomerCompany<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">GO<\/p>\r\n<p class=\"import-Standard\">If you need an output to be used elsewhere, then you would need to declare an <em>OUT parameter<\/em>. Figure 12.62 shows how to declare the OUT parameter and how to use it.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> dbo.uspGetAddressCount @City nvarchar(30), @AddressCount int <span style=\"color: #3366ff\">OUT<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> @AddressCount = count(*)<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> AdventureWorks.Person.Address<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> City = @City<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">DECLARE @AddressCount int<\/p>\r\n<p class=\"import-Standard\">EXEC dbo.uspGetAddressCount @City = 'Calgary', @AddressCount = @AddressCount OUT<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> @AddressCount<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.62 Creating a stored procedure that has an OUT parameter and showing an example execution. Source of example: https:\/\/www.mssqltips.com\/sqlservertutorial\/163\/returning-sql-server-stored-procedure-parameter-values-to-a-calling-stored-procedure\/<\/p>\r\n<p class=\"import-Standard\">The OUT parameter could be passed to a calling program. This is how this would be done:<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">cmd.Parameters.Add(\"@ClientName\", SqlDbType.VarChar, 100);<\/p>\r\n<p class=\"import-Standard\">cmd.Parameters[\"@ClientName\"].Direction = ParameterDirection.Output;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\">clientName = Convert.ToString(cmd.Parameters[\"@ClientName\"].Value);<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.63 Extract for declaring and receiving output values from a SQL stored procedure. Source of extract: https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp<\/p>\r\n<p class=\"import-Standard\">This has been a simple, high-level coverage of stored procedures. The body of a stored procedure could have been deleted and drop lines. There could be calls to other stored procedures. And stored procedures can have many lines. We have avoided covering dynamic SQL commands, because this approach could result in an SQL injection attack.<\/p>\r\n\r\n<h2>Creating Views<\/h2>\r\n<p class=\"import-Standard\">A <em>view <\/em>is a virtual table that is the result of a query. There are three reasons for creating a view:<\/p>\r\n\r\n<ul>\r\n \t<li>To focus, simplify, and customize the perception each user has of the database.<\/li>\r\n \t<li>As a security mechanism by allowing users to access data through the view, without granting the users permissions to directly access the underlying base tables.<\/li>\r\n \t<li>To provide a backward compatible interface to emulate a table whose schema has changed.<\/li>\r\n<\/ul>\r\n<p class=\"import-Standard\">The syntax has a column list in the header and a select statement in the body.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">CREATE<\/span> <span class=\"import-hljs-keyword\">VIEW<\/span><\/span> [<span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">OR<\/span> <span class=\"import-hljs-keyword\">ALTER<\/span><\/span>] schema_name.view_name [(column_list)]<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AS<\/span><\/p>\r\n<p class=\"import-Standard\">The select lines;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.64 Simple syntax of a create view command. Source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\r\n<p class=\"import-Standard\">If the column list is not used in the header, then column names would come from the SELECT statement.<\/p>\r\n<p class=\"import-Standard\">Imagine that your database has a Products table, a Sales.OrderItems table, and a Sales.Orders table. And imagine that upper management is interested in the total sales by date and by product. Upper management has no interest in the number of sold items. We could e-mail the SQL lines (Figure 13.65) and let them execute this query.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">SELECT<\/span><\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">year<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> y,<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">month<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> m,<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">day<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> d,<\/p>\r\n<p class=\"import-Standard\">p.product_id,<\/p>\r\n<p class=\"import-Standard\">product_name,<\/p>\r\n<p class=\"import-Standard\">quantity * i.list_price <span class=\"import-hljs-keyword\">AS<\/span> sales<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">FROM<\/span><\/p>\r\n<p class=\"import-Standard\">sales.orders <span class=\"import-hljs-keyword\">AS<\/span> o<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">INNER<\/span> <span class=\"import-hljs-keyword\">JOIN<\/span><\/span> sales.order_items <span class=\"import-hljs-keyword\">AS<\/span> i<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> o.order_id = i.order_id<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">INNER<\/span> <span class=\"import-hljs-keyword\">JOIN<\/span> <\/span>production.products <span class=\"import-hljs-keyword\">AS<\/span> p<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> p.product_id = i.product_id;<\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.65 Extracting data from a combination of three tables. Unchanged source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\r\n<p class=\"import-Standard\">The other option is to take the lines from Figure 13.65 and place in the body of the<span style=\"color: #3366ff\"> CREATE VIEW<\/span> and create a view with the name of Sales.DailySales. Then we could e-mail the lines from Figure 12.66 to upper management.<\/p>\r\n\r\n<table style=\"width: 478.8pt\">\r\n<tbody>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">SELECT<\/span> *<\/p>\r\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">FROM<\/span><\/p>\r\n<p class=\"import-Standard\">Sales.DailySales<\/p>\r\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">ORDER<\/span> <span class=\"import-hljs-keyword\">BY<\/span><\/span> y, m, d, product_name;<\/p>\r\n<p class=\"import-Standard\"><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr class=\"TableNormal-R\">\r\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\r\n<p class=\"import-Standard\"><img src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image42-3.png\" alt=\"image\" width=\"461.596745406824px\" height=\"245.135958005249px\" \/><\/p>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p class=\"import-Standard\">Figure 13.66 The View lines and example output. Source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\r\n<p class=\"import-Standard\">To make a change, the header line is \u201c<span style=\"color: #3366ff\">CREATE OR ALTER,<\/span>\u201d which is different from the syntax for changing a table. You would repeat the column names and add the new column name. The <span style=\"color: #3366ff\">SELECT<\/span> block would include the old lines plus the new line.<\/p>\r\n<p class=\"import-Standard\">The SQLSERVER Tutorial.net has additional examples.<\/p>\r\n\r\n<h2>A Word About Prefixes<\/h2>\r\n<p class=\"import-Standard\">You may have noticed that system defined stored procedures use \u201csp_\u201d at the beginning of the name. This is a standard naming convention and you must not use it for your own created stored procedures. If you do, then the SQL Server will search the master database for your stored procedure before visiting your user database.<\/p>\r\n<p class=\"import-Standard\">The user defined examples used prefixes in order to make the examples clearer. As noted elsewhere in this textbook, prefixes are not needed.<\/p>\r\n\r\n<h2>Key Terms<\/h2>\r\n<p class=\"import-Standard\"><strong>Application Programming Interface (API)<\/strong><strong>: <\/strong>A programming language will have objects and classes. Programmers will use these instead of creating their own block of code for a task. An example would be the SqlConnection object.<\/p>\r\n<p class=\"import-Standard\"><strong>concatenated<\/strong>: In programming, pieces are combined or added to form a string.<\/p>\r\n<p class=\"import-Standard\"><strong>connection string<\/strong>: This is a series of value pairs that is needed by a program in order to access a database.<\/p>\r\n<p class=\"import-Standard\"><strong>console project<\/strong>: This will return the rows that semi join had rejected.<\/p>\r\n<p class=\"import-Standard\"><strong>deprecated<\/strong><em>:<\/em> This means that the software feature is usable, but is obsolete. The practice is to state in a revision that a certain method or class or function will be removed in a future version. The word \u201cdeprecated\u201d is used in the warning.<\/p>\r\n<p class=\"import-Standard\"><strong>functions<\/strong>: These are built-in blocks of SQL lines for performing tasks such as obtaining the average of values in a column, counting the number of items in a column, and so on.<\/p>\r\n<p class=\"import-Standard\"><strong>graphic user interface (GUI)<\/strong>: The eye-pleasing front end to a program.<\/p>\r\n<p class=\"import-Standard\"><strong>instance<\/strong>: This is a running example or session.<\/p>\r\n<p class=\"import-Standard\"><strong>OUT parameter<\/strong>: This is used within the SQL Server environment for returning a value other than a result set. If this is being sent to the calling program, then that program would need to have an out variable declared.<\/p>\r\n<p class=\"import-Standard\"><strong>prepared statement<\/strong>: This is a programming approach whereby values are collected and added to a specially created statement for routing to a database.<\/p>\r\n<p class=\"import-Standard\"><strong>regular expression<\/strong><em>: <\/em>This does a pattern match against permitted or not permitted characters.<\/p>\r\n<p class=\"import-Standard\"><strong>result set<\/strong><strong>:<\/strong> What comes back from a SQL query.<\/p>\r\n<p class=\"import-Standard\"><strong>SQL injection attack<\/strong><strong>:<\/strong> This is a technique whereby a hacker can craft a SQL query that can obtain more data than wanted by the database managers.<\/p>\r\n<p class=\"import-Standard\"><strong>Stored procedures<\/strong>: These work with the actual SQL command inside the database environment.<\/p>\r\n<p class=\"import-Standard\"><strong>triggers<\/strong>: These are SQL lines that are invoked when an action takes place.<\/p>\r\n<p class=\"import-Standard\"><strong>view<\/strong>: This is a virtual table that is the result of a query.<\/p>\r\n\r\n<h2>Exercises<\/h2>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">1. Explain the following terms:<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">1. Application Programming Interface (API)<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">2 concatenated<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">3. connection string<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">4. console project<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">5. deprecated<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">6. function<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">7. graphic user interface<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">8. instance<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">9, OUT parameter<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">10. prepared statement<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">11. regular expression<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">12. result set<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">13. SQL Injection Attack<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">14. stored procedures<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">15. triggers<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">16. view<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">2. What are the four ways of working with a database?<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">3. Explain how a hacker could trick a concatenated string into providing more data. [IS2020 A3.2.14]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">4. Using an example from Java or from C# or from another programming language, show how you would embed a <span style=\"color: #3366ff\">SELECT<\/span> query. [CS2013 IM\/Query Languages 5 and IT2017 ITE-IMA-04d.]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">5. For the previous question, list and explain the API calls. [DS2021 PDA Programming]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">6. You are collecting address information from a person. Which fields could be handled without using a text box?<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">7. Explain how a regular expression could be used for validating a user\u2019s input.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">8. Using the references in this chapter, come up with a regular expression for something. Explain why you made this string as your answer.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">9. What is a SQL Server template? How is it used? [CS2013 IM\/Query Languages 4.]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">10. You know that a city uses a house numbering scheme whereby the house numbers differ by four. The database has all of the addresses stored in a database table. A dead-end street is being extended for a distance. You have been asked to add to the database the next 20 house numbers. Explain how this task could be completed by using functions.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">11. If the task in the previous question took place frequently, then a trigger action could be done. Explain how this might be achieved.<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">12. What are the benefits of using functions and triggers. [IS2020 A3.2.1 3]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">13. Write a stored procedure that uses at least two parameters. Explain how you could prevent unauthorized users from firing off your stored procedure. [CS2013 IM\/Query Languages 6.]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">14. What are some ways that a user could interact with a database. [DS2021 SDM-Software Design and Development Skills]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">15. Provide an example of a view. State who is the user. State why the view would be a good approach for this user. [IT2017 ITE-IMA-04f.]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">16. What are some ways of securing a database. I am looking for at least two ways of securing a database. [IS2020 A3.2.1 4]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">17. This was implied in this chapter, but never explained. Explain why we would want to write a program to access a database. [DS2021 SDM-Software Design and Development]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">18. Roles were mentioned in Chapter 11, but you were not asked to demonstrate an understanding of this topic. Describe how you might go about creating and managing database users. [IT2017 ITE-IMA Domain Information Management E.]<\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">19. Write about three ways of providing security to the database. This is an open-ended question. [IT2017 ITE-IMA Domain Information Management E.]<\/p>\r\n\r\n<h2>A Running Project<\/h2>\r\n<p class=\"import-Standard\">You should have your project in great shape.<\/p>\r\n<p class=\"import-Standard\">Some of the learning outcomes for this chapter are of an application nature. The following tasks will provide an opportunity to demonstrate your understanding.<\/p>\r\n<p class=\"import-Standard\">1. Using your project, create a query by filling in a template. [CS2013 IM\/Query Languages 4 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\r\n<p class=\"import-Standard\">2. Use the insights from this chapter to write a query that is requested from a programming language. This query should select at least one column from a table. [CS2013 IM\/Query Languages 5 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\r\n<p class=\"import-Standard\">3. Use the insights from this chapter to create a stored procedure. The stored procedure needs to work with at least two parameters. [CS2013 IM\/Query Languages 6 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\r\n<p class=\"import-Standard\">4. Use the insights from this chapter to create one trigger. [IS2020 A3.2.1 3.]<\/p>\r\n<p class=\"import-Standard\">5. Using any of the foregoing tools, create something that would use a function. [IS2020 A3.2.1 3.]<\/p>\r\n<p class=\"import-Standard\">6. Image the regular user of your project database. How would you limit what this person could see? [IT2017 ITE-IMA Domain Information Management E.]<\/p>\r\n<p class=\"import-Standard\">7. Create two views:<\/p>\r\n<p class=\"import-Standard\" style=\"padding-left: 40px\">A. A view that is fixed and will always produce the same result set.<\/p>\r\n<p class=\"import-Standard\" style=\"padding-left: 40px\">B. A view that permits the user to select different parameters and thus have a different result set.<\/p>\r\n<p class=\"import-Standard\">[IT2017 ITE-IMA-04 Database query languages f.]<\/p>\r\n\r\n<h2>Attribution<\/h2>\r\n<p class=\"import-Standard\">This chapter of <em>Database Design<\/em> is a brand-new addition.<\/p>\r\n<p class=\"import-Standard\">This chapter drew from many sources.<\/p>\r\n\r\n<h2>Image Attributions<\/h2>\r\n<p class=\"import-Standard\">No second edition images were used.<\/p>\r\n\r\n<h2>References<a id=\"_Hlk180124541\"><\/a><\/h2>\r\n<p class=\"import-Standard\">Troels Arvin. \u201cComparison of different SQSL implementations,\u201d Troels Arvin, December 29, 2018. <a class=\"rId52\" href=\"https:\/\/troels.arvin.dk\/db\/rdbms\/\">https:\/\/troels.arvin.dk\/db\/rdbms\/<\/a><\/p>\r\n<p class=\"import-Standard\">Daniel Calbimonte. \u201cSQL GO command in SQL Server,\u201d SQLShack, May 18, 2021. https:\/\/www.sqlshack.com\/sql-go-command-in-sql-server\/<\/p>\r\n<p class=\"import-Standard\">\u201cCreate a stored procedure,\u201d Learn Microsoft, January 30, 2024. <a class=\"rId53\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cCREATE VIEW (Transact-SQL),\u201d Learn Microsoft, May 23, 2023. <a class=\"rId54\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-view-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-view-transact-sql?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">Admir Dizdar. \u201cSQL Injection Payloads: How SQLi exploits work,\u201d Bright, September 16, 2021 (Updated on November 14, 2023). <a class=\"rId55\" href=\"https:\/\/brightsec.com\/blog\/sql-injection-payloads\/\">https:\/\/brightsec.com\/blog\/sql-injection-payloads\/<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cDifferences between ISNUL and COALESCE,\u201d Learn Microsoft, June 26, 2008. <a class=\"rId56\" href=\"https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/sqltips\/differences-between-isnull-and-coalesce\">https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/sqltips\/differences-between-isnull-and-coalesce<\/a><\/p>\r\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">The Stackoverflow forum discussed this topic. One writer cited the Microsoft article, but modified the example. I used the modified example, because it was clearer. See <a class=\"rId57\" href=\"https:\/\/stackoverflow.com\/questions\/19115040\/replace-null-with-blank-value-or-zero-in-sql-server\">https:\/\/stackoverflow.com\/questions\/19115040\/replace-null-with-blank-value-or-zero-in-sql-server<\/a><\/p>\r\n<p class=\"import-Standard\">Rajendra Gupta. \u201cSET QUOTED_IDENTIFIER settings in SQL Server,\u201d SQLShack, October 17, 2019. <a class=\"rId58\" href=\"https:\/\/www.sqlshack.com\/set-quoted_identifier-settings-in-sql-server\/\">https:\/\/www.sqlshack.com\/set-quoted_identifier-settings-in-sql-server\/<\/a><\/p>\r\n<p class=\"import-Standard\">Rajendra Gupta. \u201cScript templates in SQL Server Management Studio (SMS),\u201d SQLShack, April 27, 2020. <a class=\"rId59\" href=\"https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/\">https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/<\/a><\/p>\r\n<p class=\"import-Standard\">Bar Hofesh. \u201cSQL Injection Attack: how It Works, Examples and Prevention,\u201d Bright, April 8, 2022. <a class=\"rId60\" href=\"https:\/\/brightsec.com\/blog\/sql-injection-attack\/\">https:\/\/brightsec.com\/blog\/sql-injection-attack\/<\/a><\/p>\r\n<p class=\"import-Standard\" style=\"padding-left: 40px\">Bar Hofesh referenced a cheat sheet in his article. See https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/SQL_Injection_Prevention_Cheat_Sheet.html<\/p>\r\n<p class=\"import-Standard\">\u201cHow to Setup a Connection with SQL Serer Database in Visual Studio,\u201d Programmingempire, December 17, 2022 (updated on April 6, 2022). <a class=\"rId61\" href=\"https:\/\/www.programmingempire.com\/how-to-setup-a-connection-with-sql-server-database-in-visual-studio\/\">https:\/\/www.programmingempire.com\/how-to-setup-a-connection-with-sql-server-database-in-visual-studio\/<\/a><\/p>\r\n<p class=\"import-Standard\">Amit Mohanty. \u201cHow To Use Output Parameter In Stored Procedure In Stored Procedure In C#,\u201d C3 Corner, October 19, 2023. <a class=\"rId62\" href=\"https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp\">https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp<\/a><\/p>\r\n<p class=\"import-Standard\">Bhavesh Patel. \u201cSQL Server Logon Trigger Examples,\u201d MSSQL Tips, n.d. https:\/\/www.mssqltips.com\/sqlservertip\/6103\/sql-server-logon-trigger-examples\/<\/p>\r\n<p class=\"import-Standard\">\u201cSET ANSI_NULLS (Transact-SQL),\u201d Learn Microsoft, April 5, 2024. <a class=\"rId63\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-ansi-nulls-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-ansi-nulls-transact-sql?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSET NOCOUNT (Transact-SQL),\u201d Learn Microsoft, September 3, 2024. <a class=\"rId64\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-nocount-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-nocount-transact-sql?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSET QUOTED_IDENTIFIER (Transact-SQL),\u201d Learn Microsoft, August 9, 2024. <a class=\"rId65\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-quoted-identifier-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-quoted-identifier-transact-sql?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSQL Server CREATE TRIGGER,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId66\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/\">https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSQ; Server CREATE VIEW,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId67\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/\">https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSQL Server DDL Trigger,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId68\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-ddl-trigger\/\">https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-ddl-trigger\/<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cSQL Server Functions,\u201d W3 schools, n.d. <a class=\"rId69\" href=\"https:\/\/www.w3schools.com\/sqL\/sql_ref_sqlserver.asp\">https:\/\/www.w3schools.com\/sqL\/sql_ref_sqlserver.asp<\/a><\/p>\r\n<p class=\"import-Standard\">Stephen Toub. \u201cPerformance Improvements in .NET 9,\u201d Dev Blogs, September 12, 2024. <a class=\"rId70\" href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-9\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-9\/<\/a><\/p>\r\n<p class=\"import-Standard\">\u201cUse templates in SQL Server Management Studio,\u201d Learn Microsoft, March 3, 2023. <a class=\"rId71\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/a><\/p>\r\n<p class=\"import-Standard\">Ahmad Yaseen. \u201cINSERT INTO T-SQL Statement in SQL Server,\u201d SQLShack, March 27, 2020. <a class=\"rId72\" href=\"https:\/\/www.sqlshack.com\/insert-into-t-sql-statement-in-sql-server\/\">https:\/\/www.sqlshack.com\/insert-into-t-sql-statement-in-sql-server\/<\/a><\/p>\r\n&nbsp;\r\n<div id=\"sdfootnote1sym\"><a href=\"#sdfootnote1anc\">1<\/a>A procedural query spells out the steps for obtaining a result set. A non-procedural query states what is desired and leaves it to the system to figure out the steps. Everything we have addressed has been a non-procedural approach.<\/div>\r\n<div id=\"sdfootnote2sym\"><a href=\"#sdfootnote2anc\">2<\/a>Flow Control means the actions taken to prevent information or data from flowing in a way that it reaches unauthorized uses.<\/div>\r\n<div id=\"sdfootnote3sym\"><a href=\"#sdfootnote3anc\">3<\/a>The W3 schools website C# Tutorial (https:www.w3schools.com\/cs\/index.php) is based on Visual Studio 2019. The screenshots are different from what you will see in this chapter.<\/div>\r\n<div id=\"sdfootnote4sym\"><a href=\"#sdfootnote4anc\">4<\/a>C#. This is pronounced as \u201cC Sharp\u201d and this is a reference to a symbol used in written music (Unicode U+1D130 and U + 1D131). Since the standard keyboard does not have this symbol, the pound sign is used as a work-around, which is Unicode U+0023. This is a programming language that was developed by Microsoft. It runs on the .NET Framework. It is used to develop web apps, desktop apps, mobile apps, games, and more. It is similar to C++, Java, and JavaScript. The explanations in this chapter assume no background in this programming language.<\/div>\r\n<div id=\"sdfootnote5sym\"><a href=\"#sdfootnote5anc\">5<\/a>The .NET 8 has been out since Spring 2024. While working on this edition, I have decided to delay doing an upgrade. At this writing, .NET 9 is in early release status.<\/div>\r\n<div id=\"sdfootnote6sym\"><a href=\"#sdfootnote6anc\">6<\/a>There are lines that are used in every C# program. When Microsoft designed the support for writing C# code, they provided the option of hiding these \u201cboilerplate\u201d code lines into another file. When learning to program in C#, it is good to see these lines.<\/div>\r\n<div id=\"sdfootnote7sym\"><a href=\"#sdfootnote7anc\">7<\/a>You are providing a string value to the connection object. You are working with an API.<\/div>\r\n<div id=\"sdfootnote8sym\"><a href=\"#sdfootnote8anc\">8<\/a>A cookie is a small file stored on a person\u2019s computer. This may store a shopping basket list. This file may contain the password for a website and the previously used queries.<\/div>\r\n<div id=\"sdfootnote9sym\"><a href=\"#sdfootnote9anc\">9<\/a>Our style guide has each word capitalized. Java, C#, and other programming languages have programmers that have decided upon the customs and approaches for coding. In these two programming languages, minor variables follow the camel casing approach. This is not a problem since the values are passed to the database instead of the actual variable name.<\/div>\r\n<div id=\"sdfootnote10sym\"><a href=\"#sdfootnote10anc\">10<\/a>Recall that we can use the <span style=\"color: #3366ff\">CHECK<\/span> operator to ensure that the permitted values are used.<\/div>\r\n<div id=\"sdfootnote11sym\"><a href=\"#sdfootnote11anc\">11<\/a>From Geeks for Geeks:<\/div>\r\n<div style=\"padding-left: 40px\">SQL Server Replication is a robust feature used to distribute and synchronize data across multiple databases, ensuring consistency and data integrity. By leveraging the \u201cPublish and Subscribe\u201d model, SQL Server allows for flexible data distribution, whether it\u2019s full database replication or specific parts such as tables and views.<\/div>\r\n<div>This topic is beyond the scope of this chapter and textbook. For more information see https:\/\/www.geeksforgeeks.org\/sql-server-replication\/<\/div>\r\n<div id=\"sdfootnote12sym\"><a href=\"#sdfootnote12anc\">12<\/a>Ahmad Yaseen explained this in his article. See the reference list for the article citation.<\/div>\r\n<div id=\"sdfootnote13sym\"><a href=\"#sdfootnote13anc\">13<\/a>By using<span style=\"color: #3366ff\"> UNION ALL<\/span>, duplicates would be retained. Without testing the example, I am thinking that the aliasing action is not needed.<\/div>\r\n<div id=\"sdfootnote14sym\"><a href=\"#sdfootnote14anc\">14<\/a>Many programming languages have support for GoTo and for break. In 1968 Edsger W Dijkstra, a pioneer in computer science, published \u201cGo To Statement Considered Harmful.\u201d The issue with these two is that the created code is hard to follow. Today it is rare to see GoTo in a program. The break keyword has continued. But it is slowly on its way out. In Java 14, the switch structure was changed to avoid using the break keyword. Instead, lambda arrows are used. https:\/\/nipafx.dev\/java-switch\/ shows the old way and the new way with examples. https:\/\/nipafx.dev\/java-13-switch-expressions\/ explained the issues with the old way in some detail.<\/div>\r\n<div id=\"sdfootnote15sym\"><a href=\"#sdfootnote15anc\">15<\/a>When this line is not used, the default behavior is ON. This causes SQL Server to follow the ISO rules. A create table command like the following succeeds:<\/div>\r\n<div style=\"padding-left: 40px\"><span style=\"color: #3366ff\">CREATE TABLE<\/span> \"select\" (\"identity\" <span style=\"color: #3366ff\">INT IDENTITY NOT NULL<\/span>, \"order\" <span style=\"color: #3366ff\">INT NOT<\/span> NULL);<\/div>\r\n<div>With the OFF option, this would fail. Notice the words in double quotes are normally used as reserved keyword names. Otherwise, we would not need to use any quotes.<\/div>\r\n<div>The ON option requires that literals or strings must be inside single quotes, because entries in double quotes are being treated as object names. The following example shows a pair of double quotes around the table name and four single quotes in the text string:<\/div>\r\n<div style=\"padding-left: 40px\"><span style=\"color: #3366ff\">INSERT INTO<\/span> dbo.\"Test\" <span style=\"color: #3366ff\">VALUES<\/span> (7, 'Text with a single '' quote');<\/div>\r\n<div style=\"padding-left: 40px\">OUTPUT: 7 Text with a single \u2018 quote<\/div>\r\n<div>For more single quote examples, see Chapter 9 \u201cDML: INSERT INTO\u201d section, Figure 9.35, Figure 9.45, and Figure 9.47.<\/div>\r\n<div>Figure 9.38 shows that Microsoft\u2019s error messages use single quotes too.<\/div>\r\n<div>Figure 9.24 shows the correct usage of double quotes.<\/div>\r\n<div>See the reference for \u201cSET QUOTED_IDENTIFIER (Transact-SQL).\u201d<\/div>\r\n<div>Be aware that in programming languages, a single quote is for a single character. Double quotes are used for strings.<\/div>\r\n<div id=\"sdfootnote16sym\"><a href=\"#sdfootnote16anc\">16<\/a>User40980 wrote about this on February 26, 2013, but the person did not provide a reference. See https:\/\/softwareengineering.stackexchange.com\/questions\/188455\/why-do-programming-languages-especially-c-use-curly-braces-and-not-square-ones<\/div>\r\n<\/div>","rendered":"<div class=\"chapter-13-programs-to-work-with-a-database\">\n<p class=\"import-Standard\">Original Material to the textbook: Fred Strickland<\/p>\n<h2>Learning Outcomes<\/h2>\n<table style=\"width: 467.5pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>Computing Sub Discipline<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>Document Code, Reference Code, and Page Number<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>Text<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\n<td class=\"TableNormal-C\" style=\"border-top: solid #00000A 0.5pt;border-right: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\" rowspan=\"3\">\n<p class=\"import-Standard\">Computer Science<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CS2013<\/p>\n<p class=\"import-Standard\">IM\/Query Languages<\/p>\n<p class=\"import-Standard\">(Page 116)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">4. Create a non-procedural<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote1anc\" href=\"#sdfootnote1sym\">1<\/a><\/sup> query by filling in templates of relations to construct an example of the desired query result. [Usage]<\/p>\n<p class=\"import-Standard\">5. Embed object-oriented queries into a stand-alone language such as C++ or Java (e.g., SELECT Col.Method() FROM Object). [Usage]<\/p>\n<p class=\"import-Standard\">6. Write a stored procedure that deals with parameters and has some control flow<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote2anc\" href=\"#sdfootnote2sym\">2<\/a><\/sup> , to provide a given functionality. [Usage]<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CS2023<\/p>\n<p class=\"import-Standard\">DM-Querying: Query Construction<\/p>\n<p class=\"import-Standard\">(Page 118)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CS Core 1b. Programmatic execution of an SQL query<\/p>\n<p class=\"import-Standard\">Non-core 6. Different ways to invoke non-procedural queries in conventional languages.<\/p>\n<p class=\"import-Standard\">Non-core 8. Stored procedures<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CS2023<\/p>\n<p class=\"import-Standard\">DM-Security: Data Security and Privacy<\/p>\n<p class=\"import-Standard\">(Page 121)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CS Core 2. Protecting data and database systems from attacks, including injection attacks such as SQL injection<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\" rowspan=\"3\">\n<p class=\"import-Standard\">Data Science<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">DS2021<\/p>\n<p class=\"import-Standard\">Programming, Data Structures, and Algorithms (PDA) &#8211; Programming<\/p>\n<p class=\"import-Standard\">(Pages 112-113)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Manipulate data from selected sources (e.g., databases, &#8230; utilizing appropriate techniques (e.g., database queries, API calls, regular expressions).<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 59.35pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">DS2021<\/p>\n<p class=\"import-Standard\">SDM-Software Design and Development<\/p>\n<p class=\"import-Standard\">(Page 119)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Students need to have T1 level of knowledge of<\/p>\n<p class=\"import-Standard\">\u2022Integration with Information Management\/Database systems<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 31.9pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Skills<\/p>\n<p class=\"import-Standard\">(Page 120)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Describe how to integrate or interact with Information Management\/Database Systems.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 67.9pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Information Systems<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">IS2020<\/p>\n<p class=\"import-Standard\">A3.2.1 Competency Area \u2013 Data \/ Information Management<\/p>\n<p class=\"import-Standard\">(Page 101)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">3. Programming database systems using functions and triggers. (Page 103)<\/p>\n<p class=\"import-Standard\">4. Secure a database. (Page 103)<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 60.25pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\" rowspan=\"2\">\n<p class=\"import-Standard\">Information Technology<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">IT2017<\/p>\n<p class=\"import-Standard\">ITE-IMA Domain: Information Management<\/p>\n<p class=\"import-Standard\">(Page 56)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">E. Perform major database administration tasks such as create and manage database users, roles and privileges, &#8230; to ensure organizational efficiency, continuity, and information security. (Testing and performance)<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 60.25pt\">\n<td class=\"TableNormal-C\" style=\"border-right: solid #00000A 0.5pt;border-bottom: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\">\n<p class=\"import-Standard\">IT2017<\/p>\n<p class=\"import-Standard\">ITE-IMA-04 Database query languages [L3]<\/p>\n<p class=\"import-Standard\">(Page 92)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"border-right: solid #00000A 0.5pt;border-bottom: solid #00000A 0.5pt;border-left: solid #00000A 0.5pt;padding: 0pt 5.4pt 0pt 5.65pt\">\n<p class=\"import-Standard\">d. Use embedded SQL queries.<\/p>\n<p class=\"import-Standard\">f. Create updatable and non-updatable views.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Introduction to Chapter 13<\/h2>\n<p class=\"import-Standard\">We have been looking at relational DBMS from a hands-on or application viewpoint. And we have touched upon the different DBMSs. We have looked at the theory for any relational DBMS. We looked under the hood to see how the DBMS functions. In this chapter, we will begin to explore how to create a front end to a DBMS. We will be installing Microsoft\u2019s Visual Studio. We will be using the C# programming language. We will create some simple front-end programs for accessing a DBMS. In the process, we will touch upon secure coding concepts. We will look at tools that are stored in the DBMS such as stored procedures, functions, and triggers. We will wrap up this chapter by exploring how to create views.<\/p>\n<h2>The Third Edition Style Guide<\/h2>\n<p class=\"import-Standard\">This is the style guide that this book will follow for this chapter and for the other chapters.<\/p>\n<table style=\"width: 229.25pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Naming Convention:<\/p>\n<ul>\n<li>All English names<\/li>\n<li>Plural table names<\/li>\n<li>Singular column names<\/li>\n<li>Capitalized words<\/li>\n<li>Pascal Case for composite names<\/li>\n<li>No underscores or special characters<\/li>\n<li>No unique SQL commands<\/li>\n<li>No object prefixes<\/li>\n<\/ul>\n<p class=\"import-Standard\">Using the IE\u2019s Notation with Crow\u2019s Foot Notation.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.1 The database style guide. Adapted from https:\/\/vertabelo.com\/blog\/database-schema-naming-conventions\/<\/p>\n<p class=\"import-Standard\">The examples will conform to the style guide.<\/p>\n<h2>Microsoft\u2019s Visual Studio<\/h2>\n<h3>Installing Microsoft\u2019s Visual Studio<\/h3>\n<p class=\"import-Standard\">Search for \u201cMicrosoft Visual Studio.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image1-8.png\" alt=\"image\" width=\"618.143937007874px\" height=\"537.071916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.2 Screenshot of a hit for the search phrase \u201cMicrosoft Visual Studio.\u201d<\/p>\n<p class=\"import-Standard\">This chapter will be working with Visual Studio instead of Visual Studio Code. In October 2024, the current edition is 2022<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote3anc\" href=\"#sdfootnote3sym\">3<\/a><\/sup>. There are three versions.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image2-8.png\" alt=\"image\" width=\"624px\" height=\"519.196745406824px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.3 The Visual Studio download screen with the three versions shown.<\/p>\n<p class=\"import-Standard\">The Community edition is free. By clicking on the Community button, the download starts immediately. At the same time, you are taken to an information web page. This is a rich resource that you can explore on your own.<\/p>\n<p class=\"import-Standard\">Install the software. At one point, you will see the \u201cWorkloads\u201d screen.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image3-10.png\" alt=\"image\" width=\"624px\" height=\"315.2543832021px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.4 The Workloads screen.<\/p>\n<p class=\"import-Standard\">Select the data storage option.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image4-9.png\" alt=\"image\" width=\"624px\" height=\"316.463937007874px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.5 Selecting the data storage option.<\/p>\n<p class=\"import-Standard\">You can come back later and add more pieces to your Visual Studio.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image5-10.png\" alt=\"image\" width=\"624px\" height=\"345.148766404199px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.6 Screenshot of the installed items in Visual Studio.<\/p>\n<p class=\"import-Standard\">Now sign into Visual Studio. Or you could skip doing this action for later on. Microsoft has an interesting approach. You can sign into Visual Studio or into Hotmail. These are related in some fashion.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image6-9.png\" alt=\"image\" width=\"624px\" height=\"314.006299212598px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.7 The Visual Studio sign-in screen.<\/p>\n<h3>Starting Up Visual Studio<\/h3>\n<p class=\"import-Standard\">On a Windows computer, the start button is in the \u201cV\u201d part of the listing.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image7-11.png\" alt=\"image\" width=\"259.996745406824px\" height=\"172.991916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.8 Location of the start button for Visual Studio.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image8-7.png\" alt=\"image\" width=\"624px\" height=\"385.40157480315px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.9 The splash screen during start up.<\/p>\n<p class=\"import-Standard\">The opening screen shows your previous work and provides some options.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image9-5.png\" alt=\"image\" width=\"543.983937007874px\" height=\"362.111916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.10 The Visual Studio opening screen.<\/p>\n<h3>Testing Our Connection to the SQL Server<\/h3>\n<p class=\"import-Standard\">I used the information provided by the Programmingempire.<\/p>\n<p class=\"import-Standard\">Create a new <em>console project<\/em> (a program that does not use a graphic interface (GUI)).<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image10-7.png\" alt=\"image\" width=\"624px\" height=\"46.5983202099738px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.11 Creating a new project.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image11-7.png\" alt=\"image\" width=\"429.129553805774px\" height=\"285.657532808399px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.12 Selecting a console project out of the list of possible project types.<\/p>\n<p class=\"import-Standard\">Select C#<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote4anc\" href=\"#sdfootnote4sym\">4<\/a><\/sup> as the desired programming language.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image12-7.png\" alt=\"image\" width=\"168.979107611549px\" height=\"220.991916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.13 The available programming languages.<\/p>\n<p class=\"import-Standard\">Fill out the floating dialog box. Figure 13.14 shows a screenshot from my personal computer:<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image13-7.png\" alt=\"image\" width=\"542.323149606299px\" height=\"349.68px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.14 Screenshot of the \u201cConfigure your new project\u201d floating dialog box on my personal computer.<\/p>\n<p class=\"import-Standard\">Note: The location line will be different for your computer. There is a checkbox toward the bottom. Do not use it.<\/p>\n<p class=\"import-Standard\">Most tutorial websites will recommend using \u201c.NET 7.0 (Standard Term Support) on the \u201cAdditional information\u201d floating dialog box.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image14-6.png\" alt=\"image\" width=\"569.087979002625px\" height=\"218.985511811024px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.15 Selecting the \u201c.NET 7.0 (Standard Term Support)\u201d Framework<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote5anc\" href=\"#sdfootnote5sym\">5<\/a><\/sup>.<\/p>\n<p class=\"import-Standard\">Check the \u201cDo not use the top-level statements<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote6anc\" href=\"#sdfootnote6sym\">6<\/a><\/sup>.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image15-7.png\" alt=\"image\" width=\"419.078320209974px\" height=\"190.070341207349px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13. 16 The updated \u201cAdditional information\u201d floating dialog box.<\/p>\n<p class=\"import-Standard\">The Visual Studio has enough information to create a starting file.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image16-6.png\" alt=\"image\" width=\"624px\" height=\"116.073595800525px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.17 Screenshot of the generated C# lines.<\/p>\n<p class=\"import-Standard\">Look for the \u201cServer Explorer.\u201d It is under the \u201cView\u201d menu tab.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image17-7.png\" alt=\"image\" width=\"257.087979002625px\" height=\"192.076745406824px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.18 Navigating to the \u201cServer Explorer.\u201d<\/p>\n<p class=\"import-Standard\">When the \u201cData Connection\u201d is present, then do a right mouse click and select \u201cAdd Connection.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image18-5.png\" alt=\"image\" width=\"407.059107611549px\" height=\"170.083149606299px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.19 Selecting the option for connecting to a current database.<\/p>\n<p class=\"import-Standard\">Select the \u201cMicrosoft SQL Server\u201d option from the \u201cChoose Data Source.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image19-5.png\" alt=\"image\" width=\"375.724724409449px\" height=\"288.451128608924px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.20 The opening screen of the \u201cChoose Data Source\u201d dialog box.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image20-5.png\" alt=\"image\" width=\"464.390341207349px\" height=\"364.271916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.21 Selecting the \u201cMicrosoft SQL Server\u201d option.<\/p>\n<p class=\"import-Standard\">Another floating dialog box will appear. This is the \u201cAdd Connection\u201d dialog box. It will look for SQL Servers and populate the drop-down menu.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image21-5.png\" alt=\"image\" width=\"624px\" height=\"438.911916010499px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.22 The \u201cAdd Connection\u201d floating dialog box.<\/p>\n<p class=\"import-Standard\">In additional, the floating dialog box will populate the names of the dialog box. The \u201cPlease Wait\u201d floating dialog box is blocking view of the \u201cConnect to a database\u201d section.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image22-5.png\" alt=\"image\" width=\"606.537532808399px\" height=\"185.615958005249px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.23 The list of discovered databases on the SQL Server.<\/p>\n<p class=\"import-Standard\">If you have installed the AdventureWorks database, then you can select it.<\/p>\n<p class=\"import-Standard\">At the bottom of the floating dialog box is a button for testing the connection.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image23-5.png\" alt=\"image\" width=\"362.083149606299px\" height=\"156.019107611549px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.24 The result of testing the connection.<\/p>\n<p class=\"import-Standard\">When you hit the \u201cOK\u201d button, the screen will update and display the details from the SQL Server.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image24-5.png\" alt=\"image\" width=\"344.0543832021px\" height=\"263.059107611549px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.25 The Server Explorer shows the connection to the AdventureWorks2022 database.<\/p>\n<p class=\"import-Standard\">From inside Visual Studio, you can do some of the basic SQL Server Management Studio tasks.<\/p>\n<h2>Using Microsoft\u2019s Visual Studio for Accessing a DBMS<\/h2>\n<p class=\"import-Standard\">It is beyond the scope of this chapter to provide a detailed description of C# coding with objects. And it is beyond the scope of this chapter to teach you how to use Microsoft\u2019s Visual Studio. You will be provided with enough information in order to create a successful program. You will not be writing raw lines. Instead you will be using an <em>Application Programming Interface<\/em> (API) approach whereby you provide input to built-in classes and methods.<\/p>\n<p class=\"import-Standard\">In the code template, you need to type the following line as the first executable line:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">using Microsoft.Data.sqlClient;<\/p>\n<h3>Adding the Microsoft.Data.sqlClient Package<\/h3>\n<p class=\"import-Standard\">If you receive an error message about this component not existing, then you will need to add the NuGet Package.<\/p>\n<p class=\"import-Standard\">Right mouse click on the project name and look for \u201cManage NuGet Packages.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image25-5.png\" alt=\"image\" width=\"395.711916010499px\" height=\"412.953595800525px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.26 First step for adding the missing Microsoft.Data.sqlClient package.<\/p>\n<p class=\"import-Standard\">Click on the \u201cBrowse\u201d button. Assuming your computer has an active Internet connection, the list will populate.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image26-5.png\" alt=\"image\" width=\"543.983937007874px\" height=\"338.457532808399px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.27 Opening screen for NuGet.<\/p>\n<p class=\"import-Standard\">Once the list has populated, page down until you find \u201cMicrosoft.Data.SqlClient.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image27-4.png\" alt=\"image\" width=\"593.193595800525px\" height=\"396.287979002625px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.28 The populated NuGet list.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image28-8.png\" alt=\"image\" width=\"443.711916010499px\" height=\"101.855958005249px\" \/><\/p>\n<p class=\"import-Standard\">Figure 1329 The \u201cMicrosoft.Data.SqlClient\u201d piece.<\/p>\n<p class=\"import-Standard\">Install the Microsoft.Data.SqlClient.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image29-5.png\" alt=\"image\" width=\"428.937532808399px\" height=\"461.068766404199px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.30 The installation screen for Microsoft.Data.SqlClient.<\/p>\n<p class=\"import-Standard\">Follow the prompts.<\/p>\n<h3>Working with the SqlConnection Object<\/h3>\n<p class=\"import-Standard\">From Figure 12.24, we can view the <em>connection string<\/em>, which is a series of value pairs that is needed by a program in order to access a database. We need to code this in our program. We need to work with the SqlConnection Object. Understand that the SqlConnection object is used to handle the actual communications between our C# program and the SQL Server database. The SqlConnection Object creates an <em>instance<\/em> (a running example or session) and it is populated with a Connection String. This instance is passed (or shared) with another part of the program. Figure 12.30A shows the connection string template. Figure 12.25B shows an example based on my personal computer.<\/p>\n<table style=\"width: 478.85pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>A<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>string<\/strong> connString = @&#8221;Data Source=&#8221; + datasource + &#8220;;Initial Catalog=&#8221; + database + &#8220;;Persist Security Info=True;User ID=&#8221; + username + &#8220;;Password=&#8221; + password;<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>B<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>string <\/strong>connString = &#8220;Data Source=FRED-WINDOWS-10;Initial Catalog=AdventureWorks2022; Integrated Security=True; TrustServerCertificate=True\u201d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.31 Connection string template and example.<\/p>\n<p class=\"import-Standard\">The connection string is passed to the SqlConnectionStringBuilder object:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlConnectionStringBuilder builder= new SqlConnectionStringBuilder(connString)<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote7anc\" href=\"#sdfootnote7sym\">7<\/a><\/sup>;<\/p>\n<p class=\"import-Standard\">Then the created builder object is passed to the SqlConnection object:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlConnection connection = new SqlConnection(builder);<\/p>\n<p class=\"import-Standard\">Now we can open the connection to the database.<\/p>\n<p class=\"import-Standard\">Connection.Open()<\/p>\n<h2>Four Ways for a Program to Work with a Database<\/h2>\n<p class=\"import-Standard\">There are four ways of working with a database:<\/p>\n<ul>\n<li>A concatenated string<\/li>\n<li>Prepared statements with parameters<\/li>\n<li>Stored procedures<\/li>\n<li>Allow-list input validation<\/li>\n<\/ul>\n<h3>Using a Concatenated String<\/h3>\n<p class=\"import-Standard\">Imagine that we wish to select name and collation_name from the sys.databases table. Imagine that we have created a front end that looks similar to Figure 12.31.<\/p>\n<table style=\"width: 478.85pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Type in the desired column names separated by a comma.<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Type in the desired table name.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\n<\/td>\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.32 A fictitious front-end.<\/p>\n<p class=\"import-Standard\">Our user fills out the form as shown in Figure 12.32.<\/p>\n<table style=\"width: 478.85pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Type in the desired column names separated by a comma.<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Type in the desired table name.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">name, collation_name<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">sys.databases<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.33 Example entries in the fictitious front-end.<\/p>\n<p class=\"import-Standard\">Behind the front-end, the entries are <em>concatenated<\/em> or combined or added to a string:<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">\u201cSELECT<\/span> \u201d + &lt;words from the column name box&gt; + \u201c<span style=\"color: #3366ff\"> FROM<\/span> \u201d + &lt;words from the table name box&gt;<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases\u201d<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">String sql = \u201c <span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases\u201d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.34 The behind the front-end work.<\/p>\n<p class=\"import-Standard\">This string is added to the SqlCommand object and this is sent out to the database for processing:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlCommand command new SqlCommand(sql, connection)<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SqlDataReader reader = command.ExcuteReader();<\/p>\n<p class=\"import-Standard\">This will return a <em>result set <\/em>(the desired rows).<\/p>\n<p class=\"import-Standard\">This is bad coding, because a hacker could add another command at the end. Look at Figure 12.35.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources\u201d<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">String sql = \u201c<span style=\"color: #3366ff\">SELECT<\/span> \u201d + \u201cname, collation_name\u201d + \u201c <span style=\"color: #3366ff\">FROM<\/span> \u201d + \u201csys.databases; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources\u201d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.35 Example of how a hacker could obtain more data from a database.<\/p>\n<p class=\"import-Standard\">This is known as an <em>SQL injection attack<\/em>. There are three additional versions of this attack:<\/p>\n<ul>\n<li>Use the <span style=\"color: #3366ff\">UNION<\/span> keyword. This combines two SQL statements. This is similar to using a semicolon as shown in Figure 12.34.<\/li>\n<li>Malformed SQL statement. A SQL Server will return an error message with the desired data.<\/li>\n<li>Blind SQL attack. The hacker creates queries that return true or false. The hacker inspects the results. Then the hacker crafts a SQL query that will return the desired data.<\/li>\n<\/ul>\n<p class=\"import-Standard\">A skillful hacker could access cookies<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote8anc\" href=\"#sdfootnote8sym\">8<\/a><\/sup> on a person\u2019s computer. The hacker could change the contents of the cookie file and cause the query to execute differently.<\/p>\n<p class=\"import-Standard\">Some websites will put pieces of a query in the URL. A hacker could change the URL to execute differently.<\/p>\n<p class=\"import-Standard\">And a hacker could execute commands that would change the data or add bogus data.<\/p>\n<p class=\"import-Standard\">Some database administrators have attempted to stop hackers by requiring the authorized users to add their userid and passwords to the fill-in boxes. The login credentials would be added to the <span style=\"color: #3366ff\">WHERE<\/span> clause. Hackers have defeated this by adding the <span style=\"color: #3366ff\">OR<\/span> connector with a Boolean statement that is always true.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">sql = &#8220;<span style=\"color: #3366ff\">SELECT<\/span> id <span style=\"color: #3366ff\">FROM<\/span> users <span style=\"color: #3366ff\">WHERE<\/span> username='&#8221; + user + &#8220;&#8216; <span style=\"color: #3366ff\">AND<\/span> password='&#8221; + pass + &#8220;&#8216;&#8221;<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">After the pass variable, add: <span style=\"color: #3366ff\">OR<\/span> 5 = 5<\/p>\n<p class=\"import-Standard\">The hacker can type anything for the login credentials and the query will still execute.<\/p>\n<p class=\"import-Standard\">These are just some of the ways that a hacker can attack a concatenated string front end. Admir Dizdar\u2019s article covered these examples in greater detail plus provided insights on other exploits.<\/p>\n<h3>Using Prepared Statements with Parameters<\/h3>\n<p class=\"import-Standard\">Instead of collecting the user\u2019s entries, we define a parameter or variable for each item.<\/p>\n<p class=\"import-Standard\">Instead of a very generic front-end, we will make it narrower.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">To access your account balance, enter your user name<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.36 Revised front-end for collecting a parameter.<\/p>\n<p class=\"import-Standard\">Our user fills out the form as in Figure 13.37.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">To access your account balance, enter your user name.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"background-color: #dddddd;padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">IamAwonderfulUser<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.37 Example entry in the fictitious front-end.<\/p>\n<p class=\"import-Standard\">Behind the front-end, the entries are fed into the parameters and we create a <em>prepared statement<\/em>.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>Java Code<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">String customerName = request.getParameter(\u201cName\u201d)<\/p>\n<p class=\"import-Standard\">String sql \u201c<span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName = ?\u201d;<\/p>\n<p class=\"import-Standard\">PreparedStatement preparedStatement = connection.prepareStatement (sql);<\/p>\n<p class=\"import-Standard\">preparedStatement.setString (1, <span style=\"background-color: #ffff00\">customerName<\/span>);<\/p>\n<p class=\"import-Standard\">resultSet results = preparedStatement.executeQuery();<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>C# Code<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">String sql \u201c<span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName = @userName\u201d;<\/p>\n<p class=\"import-Standard\">using (SqlCommand command new SqlCommand(sql, connection);<\/p>\n<p class=\"import-Standard\">command.Parameters.AddWithValue(\u201d@userName\u201d,<span style=\"background-color: #ffff00\"> customerName<\/span>;<\/p>\n<p class=\"import-Standard\">using (SqlDataReader reader = command.ExecuteReader())<\/p>\n<p class=\"import-Standard\">while (reader.Read()<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">\/\/ retrieve the data.<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The value stored in sql is: <span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName \u201cIamAwonderfulUser\u201d;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.38 The behind the front-end work with the variable customerName<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote9anc\" href=\"#sdfootnote9sym\">9<\/a><\/sup> is connected to the front-end.<\/p>\n<p class=\"import-Standard\">Suppose the hacker adds something extra to the name box.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">IamAwonderfulUser; <span style=\"color: #3366ff\">SELECT<\/span> * <span style=\"color: #3366ff\">FROM<\/span> HumanResources;<\/p>\n<p class=\"import-Standard\">The query would become:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> AccountBalance <span style=\"color: #3366ff\">FROM<\/span> UserData <span style=\"color: #3366ff\">WHERE<\/span> UserName \u201cIamAwonderfulUser; SELECT * FROM HumanResources;\u201d<\/p>\n<p class=\"import-Standard\">The system would look for a person with the name of \u201cIamAwonderfulUser; SELECT * FROM HumanResources;\u201d The search fails since there is no person in the database with that name!<\/p>\n<h3>Using Stored Procedures<\/h3>\n<p class=\"import-Standard\">Prepared statements work with the actual SQL command inside the programming language. <em>Stored procedures<\/em> work with the actual SQL command inside the database environment. The approach is similar in that data parameters are collected and are sent to the database. The difference is that you need to define the name of each parameter.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>Java Code Example using a Single Parameter<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\/\/ Separate definition of user inputs<\/p>\n<p class=\"import-Standard\">String custname = request.getParameter(&#8220;customerName&#8221;);<\/p>\n<p class=\"import-Standard\">\/\/ Executing the stored procedure sp_getAccountBalancer<\/p>\n<p class=\"import-Standard\">try {<\/p>\n<p class=\"import-Standard\">CallableStatement cs = connection.prepareCall(&#8220;{call sp_getAccountBalance(?)}&#8221;);<\/p>\n<p class=\"import-Standard\">cs.setString(1, custname);<\/p>\n<p class=\"import-Standard\">ResultSet results = cs.executeQuery();<\/p>\n<p class=\"import-Standard\">\/\/ result set handling<\/p>\n<p class=\"import-Standard\">} catch (SQLException se) {<\/p>\n<p class=\"import-Standard\">\/\/ logging and error handling<\/p>\n<p class=\"import-Standard\">}<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>C# Code Example Using More Than One Parameter<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">command.CommandText = &#8220;HumanResources.uspGetEmployeesTest2&#8221;;<\/p>\n<p class=\"import-Standard\">\/\/ This tells the environment that we are working with a stored procedure.<\/p>\n<p class=\"import-Standard\">command.CommandType = CommandType.StoredProcedure;<\/p>\n<p class=\"import-Standard\">\/\/ Add the input parameter and set its properties.<\/p>\n<p class=\"import-Standard\">SqlParameter parameter = new SqlParameter();<\/p>\n<p class=\"import-Standard\">parameter.ParameterName = &#8220;@FirstName&#8221;;<\/p>\n<p class=\"import-Standard\">parameter.SqlDbType = SqlDbType.NVarChar;<\/p>\n<p class=\"import-Standard\">parameter.Direction = ParameterDirection.Input;<\/p>\n<p class=\"import-Standard\">parameter.Value = &#8220;Pilar&#8221;; \/\/ FirstName. The value is provided to the stored procedure.<\/p>\n<p class=\"import-Standard\">command.Parameters.Add(&#8220;@FirstName&#8221;, SqlDbType.NVarChar).Value = &#8220;Pilar&#8221;;<\/p>\n<p class=\"import-Standard\">parameter.ParameterName = &#8220;@LastName&#8221;;<\/p>\n<p class=\"import-Standard\">parameter.SqlDbType = SqlDbType.NVarChar;<\/p>\n<p class=\"import-Standard\">parameter.Direction = ParameterDirection.Input;<\/p>\n<p class=\"import-Standard\">parameter.Value = &#8220;Ackerman&#8221;; \/\/ LastName. The value is provided to the stored procedure.<\/p>\n<p class=\"import-Standard\">command.Parameters.Add(&#8220;@LastName&#8221;, SqlDbType.NVarChar).Value = &#8220;Ackerman&#8221;;<\/p>\n<p class=\"import-Standard\">\/\/ Open the connection and execute the reader.<\/p>\n<p class=\"import-Standard\">connection.Open();<\/p>\n<p class=\"import-Standard\">try<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">using (SqlDataReader reader = command.ExecuteReader())<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">if (reader.HasRows)<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">while (reader.Read())<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">Console.WriteLine(&#8220;{0}: {1:C}&#8221;, reader[0], reader[1]);<\/p>\n<p class=\"import-Standard\">Console.WriteLine(reader[&#8220;FirstName&#8221;] + &#8221; &#8221; + reader[&#8220;LastName&#8221;] + &#8221; in &#8221; + reader[&#8220;Department&#8221;]);<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">else<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">Console.WriteLine(&#8220;No rows found.&#8221;);<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">reader.Close();<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">catch (SqlException ex)<\/p>\n<p class=\"import-Standard\">{<\/p>\n<p class=\"import-Standard\">Console.WriteLine(&#8220;Inside the catch block. &#8221; + ex);<\/p>\n<p class=\"import-Standard\">}<\/p>\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.39 Java and C# examples using a stored procedure.<\/p>\n<h3>Using Allow-List Input Validation<a id=\"_Hlk180124495\"><\/a><\/h3>\n<p class=\"import-Standard\">The user inputs are validated in some fashion.<\/p>\n<p class=\"import-Standard\">One approach is to use drop down lists. This is done for postal information (such the two-letter codes used in North America), for dates, for gender, and for other known lists of values.<\/p>\n<p class=\"import-Standard\">A <em>regular expression<\/em> could be used. A regular expression does a pattern match against permitted or not permitted characters. For example, a regular expression could be used to handle all of the current forms of ten-digit telephone numbers as used in North America:<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]\\d{3}[\\s.-]\\d{4}$<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">123-456-7890<\/p>\n<p class=\"import-Standard\">(123) 456-7890<\/p>\n<p class=\"import-Standard\">123 456 7890<\/p>\n<p class=\"import-Standard\">123.456.7890<\/p>\n<p class=\"import-Standard\">+91 (123) 456-7890<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.40 A regular expression for finding valid ten-digit telephone numbers.<\/p>\n<p class=\"import-Standard\">Support for regular expressions is found in every programming language such as C++, C#, Java, and others. Many editing programs use regular expressions. There are many resources for learning more about this topic.<\/p>\n<ul>\n<li>\u201cRegex Tutorial \u2013 How to write Regular Expressions?\u201d Geeks for Geeks, April 12, 2024. (<a class=\"rId36\" href=\"https:\/\/www.geeksforgeeks.org\/write-regular-expressions\/\">https:\/\/www.geeksforgeeks.org\/write-regular-expressions\/<\/a>)<\/li>\n<li>Regular expressions 101 (<a class=\"rId37\" href=\"https:\/\/regex101.com\/\">https:\/\/regex101.com<\/a>)<\/li>\n<li>Regex (<a class=\"rId38\" href=\"https:\/\/regexr.com\">https:\/\/regexr.com<\/a>)<\/li>\n<\/ul>\n<p class=\"import-Standard\">The various environments may have slightly different regular expression rules.<\/p>\n<p class=\"import-Standard\">Validating user input should be included for prepared statements and for stored procedures.<\/p>\n<h2>Templates<\/h2>\n<p class=\"import-Standard\">Templates exist in the SQL Server Management Studio. These are found inside the View tab.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image30-4.png\" alt=\"image\" width=\"624px\" height=\"471.686299212598px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.41 Screenshot of the path to the SQL Server Management Studio templates. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">Select a template and do a right mouse click to open it up.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image31-3.png\" alt=\"image\" width=\"324.739107611549px\" height=\"570.863937007874px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.42 Opening up the \u201cCreate Database\u201d template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">A query window will open with the T-SQL script present.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image32-4.png\" alt=\"image\" width=\"400.060787401575px\" height=\"237.052703412073px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.43 Test of the \u201cCreate Database\u201d template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">You can modify the template and then execute it.<\/p>\n<p class=\"import-Standard\">If you wish to make the changes permanent, then you can edit the selected template.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image33-3.png\" alt=\"image\" width=\"332.937532808399px\" height=\"462.652703412073px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.44 The editing option. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">After the changes are made, then select File Save.<\/p>\n<p class=\"import-Standard\">Reopening the template view will show the revised changes.<\/p>\n<p class=\"import-Standard\">Creating a new template involves using the New folder steps. Look for \u201cCustom Templates.\u201d<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image34-3.png\" alt=\"image\" width=\"624px\" height=\"341.52px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.45 The create new template option. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">Right mouse click on \u201cCustom Templates\u201d and select the New Template path. Enter a useful name.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image35-4.png\" alt=\"image\" width=\"624px\" height=\"415.74719160105px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.46 Continuing the steps for creating a new template. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">Enter the T-SQL lines. When finished, hit File Save.<\/p>\n<h2>Functions<\/h2>\n<p class=\"import-Standard\">In the chapter on SQL commands, we worked with AVG (), with COUNT(), with MAX(), with MIN(), and with others. These were SQL <em>functions<\/em>. The W3 schools website has grouped the Microsoft SQL Server functions in this fashion:<\/p>\n<ul>\n<li>SQL Server String Functions<\/li>\n<li>SQL Server Math\/Numeric Functions<\/li>\n<li>SQL Server Date Functions<\/li>\n<li>SQL Server Advanced Functions<\/li>\n<\/ul>\n<p class=\"import-Standard\">The SQL Server Advanced functions provide solutions to challenging problems. CAST() and CONVERT() will change a value from one data type to another data type. For example, you could change a decimal to a whole number. Or you could change a string representing a number to a numeric that could be manipulated with mathematical operators.<\/p>\n<p class=\"import-Standard\">When working with NULLs, the Math\/Numeric functions will have strange results. The COALESCE function will solve this issue. The W3 schools COALESCE function web page does not explain this function fully. The following will render NULLs as zeros:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> <span style=\"color: #3366ff\">COALESCE<\/span>(TotalAmount, 0) <span style=\"color: #3366ff\">FROM<\/span> Products;<\/p>\n<p class=\"import-Standard\">Microsoft recommends using the following approach:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">SELECT<\/span> isnull(TotalAmount 0) <span style=\"color: #3366ff\">AS<\/span> TotalAmount <span style=\"color: #3366ff\">FROM<\/span> Products;<\/p>\n<p class=\"import-Standard\">As the Microsoft writer explained in the 2008 article, COALESCE is based on the ANSI SQL standard whereas the ISNULL is a Microsoft proprietary T-SQL function.<\/p>\n<p class=\"import-Standard\">Troels Arvin has put together a web page that compares the different SQL implementations against the SQL 2008 standard.<\/p>\n<h2>Triggers<\/h2>\n<p class=\"import-Standard\">Recall the Chapter 9 section about cascading updates and deletes (\u201cDDL: CREATE TABLE with the Cascading Update and Cascading Delete\u201d). These are examples of DML <em>triggers<\/em>. Again, these are invoked automatically in response to INSERT, UPDATE, and DELETE events against database tables.<\/p>\n<p class=\"import-Standard\">There are two more types of triggers:<\/p>\n<ul>\n<li>DDL triggers. These react to CREATE, ALTER, and DROP statements.<\/li>\n<li>Some system defined stored procedures would cause a DDL trigger to fire.<\/li>\n<li>Logon triggers<\/li>\n<\/ul>\n<h3>Creating DML Triggers<\/h3>\n<p class=\"import-Standard\">Figure 13.47 shows the syntax for a create trigger statement:<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">CREATE<\/span> <span class=\"import-hljs-keyword\">TRIGGER<\/span> <\/span>[schema_name.]trigger_name<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> table_name<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AFTER<\/span> {[<span class=\"import-hljs-keyword\">INSERT<\/span>],[<span class=\"import-hljs-keyword\">UPDATE<\/span>],[<span class=\"import-hljs-keyword\">DELETE<\/span>]}<\/p>\n<p class=\"import-Standard\">[<span class=\"import-hljs-keyword\">NOT<\/span> <span class=\"import-hljs-keyword\">FOR<\/span> <span class=\"import-hljs-keyword\">REPLICATION<\/span>]<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\">{sql_statements}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.47 Create trigger syntax. (The text was not changed to conform with our style guide.) Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">SQL Server has two predefined tables that support triggers. One table is for insert events and the other table is for delete events. These are used to capture the data before and after an action. Figure 13.48 explains how these work.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>DML event<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>INSERTED table holds<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><strong>DELETED table holds<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">INSERT<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">rows to be inserted<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">empty<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">UPDATE<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">new rows modified by the update<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">existing rows modified by the update<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">DELETE<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">empty<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">rows to be deleted<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.48 INSERTED and DELETED tables Source of table notes: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">SQLServer Tutorial.net has a nice example. The following is that example with changes to follow our style guide.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Production.Products<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">ID<\/p>\n<p class=\"import-Standard\">Name<\/p>\n<p class=\"import-Standard\">BrandID<\/p>\n<p class=\"import-Standard\">CategoryID<\/p>\n<p class=\"import-Standard\">ModelYear<\/p>\n<p class=\"import-Standard\">ListPrice<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.49 SQLServer Tutorial.net example table that has been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">We need a table for logging the changes to the Production.Products table. We are naming this table as Production.ProductAudits<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE TABLE<\/span> Production.ProductAudits(<\/p>\n<p class=\"import-Standard\">Id INT IDENTITY PRIMARY KEY,<\/p>\n<p class=\"import-Standard\">ProductId INT NOT NULL,<\/p>\n<p class=\"import-Standard\">ProductName VARCHAR(255) NOT NULL,<\/p>\n<p class=\"import-Standard\">BrandId INT NOT NULL,<\/p>\n<p class=\"import-Standard\">CategoryId INT NOT NULL,<\/p>\n<p class=\"import-Standard\">ModelYear SMALLINT NOT NULL,<\/p>\n<p class=\"import-Standard\">ListPrice DEC(10,2) NOT NULL,<\/p>\n<p class=\"import-Standard\">UpdatedAt DATETIME NOT NULL,<\/p>\n<p class=\"import-Standard\">Operation CHAR(3) NOT NULL,<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CHECK<\/span><sup class=\"import-FootnoteReference\"><a id=\"sdfootnote10anc\" href=\"#sdfootnote10sym\">10<\/a><\/sup>(Operation = &#8216;INS&#8217; or Operation=&#8217;DEL&#8217;)<\/p>\n<p class=\"import-Standard\">);<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.50 SQLServer Tutorial.net example changes tracking table that has been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">Now, we need to create a trigger. Figure 12.51 has the trigger code with explanations.<\/p>\n<table style=\"width: 478.85pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE TRIGGER<\/span> Production.TriggerProductAudit<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\u201cProduction\u201d is the schema name and it is optional.<\/p>\n<p class=\"import-Standard\">The trigger name is defined by the author.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">ON<\/span> Production.Products<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The keyword<span style=\"color: #3366ff\"> ON<\/span> precedes the name of the table that we wish to define a trigger for.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AFTER<\/span> INSERT, DELETE<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The keyword <span style=\"color: #3366ff\">AFTER<\/span> states that the trigger will fire after an event (INSERT, UPDATE, or DELETE). Here we are stating that we want this trigger to fire for all inserts and for all deletes.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The \u201cNOT FOR REPLICATION\u201d option instructs the SQL Server not to fire the trigger when data modification is made as part of a replication process<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote11anc\" href=\"#sdfootnote11sym\">11<\/a><\/sup>.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\" style=\"height: 31pt\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">BEGIN<\/span><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Ends the instructions and marks the beginning of the actual SQL lines.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">SET NOCOUNT ON;<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">We do not want a row report to be sent to the calling agent.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">INSERT INTO<\/span><\/p>\n<p class=\"import-Standard\">Production.ProductAudits<\/p>\n<p class=\"import-Standard\">(<\/p>\n<p class=\"import-Standard\">ProductId,<\/p>\n<p class=\"import-Standard\">ProductName,<\/p>\n<p class=\"import-Standard\">BrandId,<\/p>\n<p class=\"import-Standard\">CategoryId,<\/p>\n<p class=\"import-Standard\">ModelYear,<\/p>\n<p class=\"import-Standard\">ListPrice,<\/p>\n<p class=\"import-Standard\">UpdatedAt,<\/p>\n<p class=\"import-Standard\">Operation<\/p>\n<p class=\"import-Standard\">)<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span><\/p>\n<p class=\"import-Standard\">i.ProductId,<\/p>\n<p class=\"import-Standard\">ProductName,<\/p>\n<p class=\"import-Standard\">BrandId,<\/p>\n<p class=\"import-Standard\">CategoryId,<\/p>\n<p class=\"import-Standard\">ModelYear,<\/p>\n<p class=\"import-Standard\">i.ListPrice,<\/p>\n<p class=\"import-Standard\">GETDATE(),<\/p>\n<p class=\"import-Standard\">&#8216;INS&#8217;<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span><\/p>\n<p class=\"import-Standard\">Inserted <span style=\"color: #3366ff\">AS<\/span> i<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">UNION ALL<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span><\/p>\n<p class=\"import-Standard\">d.ProductId,<\/p>\n<p class=\"import-Standard\">ProductName,<\/p>\n<p class=\"import-Standard\">BrandId,<\/p>\n<p class=\"import-Standard\">CategoryId,<\/p>\n<p class=\"import-Standard\">ModelYear,<\/p>\n<p class=\"import-Standard\">d.ListPrice,<\/p>\n<p class=\"import-Standard\">GETDATE(),<\/p>\n<p class=\"import-Standard\">&#8216;DEL&#8217;<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span><\/p>\n<p class=\"import-Standard\">Deleted <span style=\"color: #3366ff\">AS<\/span> d;<\/p>\n<p class=\"import-Standard\">END<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">We are listing the target columns.<\/p>\n<p class=\"import-Standard\">When the values are coming from a database table, then the keyword VALUES is not used<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote12anc\" href=\"#sdfootnote12sym\">12<\/a><\/sup>. We are drawing from the Inserted system table and from the Deleted system table.<\/p>\n<p class=\"import-Standard\">SQLServer Tutorial.net writer aliased these two tables and used these for the product ID and for the list price<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote13anc\" href=\"#sdfootnote13sym\">13<\/a><\/sup>.<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">UNION ALL<\/span> retains duplicated actions.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.51 SQLServer Tutorial.net example trigger creation lines that have been revised based on our style guide. Source of text: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">You must execute the code. Then it will be added to the list of triggers. Figure 12.52 shows the location of this new trigger.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image36-2.jpeg\" alt=\"image\" width=\"375.80157480315px\" height=\"357.465511811024px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.52 SQLServer Tutorial.net example showing where it would be stored in a database.. Source of image: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<p class=\"import-Standard\">If something is added to this table, the trigger would fire. If something is deleted from this table, the trigger would fire. Here is the output from the ProductAudits table:<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image37-3.jpeg\" alt=\"image\" width=\"624px\" height=\"55.8623622047244px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.53 SQLServer Tutorial.net example showing the output for two actions.. Source of image: https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/p>\n<h3>Creating DDL Triggers<\/h3>\n<p class=\"import-Standard\">SQL Server DDL triggers can react to database events such as <span style=\"color: #3366ff\">CREATE, ALTER, DROP, GRANT, DENY, REVOKE<\/span>, and <span style=\"color: #3366ff\">UPDATE<\/span> <span style=\"color: #3366ff\">STATISTICS<\/span>. DDL triggers are useful for recording changes to the database scheme. Instead of pulling from the Inserted system table or from the Deleted system table, you would execute the EVENTDATA() function and capture the output into the user created event tracking table. For a detailed example, see the reference for the URL.<\/p>\n<h3>Creating Logon Triggers<\/h3>\n<p class=\"import-Standard\">A logon trigger can be used for five purposes:<\/p>\n<ul>\n<li>Restrict users to only login at certain times.<\/li>\n<li>Restrict number of concurrent sessions for a specific login.<\/li>\n<li>Restrict total number of connections.<\/li>\n<li>Restrict login by host name or IP Address.<\/li>\n<li>Use a logon trigger for auditing.<\/li>\n<\/ul>\n<p class=\"import-Standard\">The syntax is similar to the DML trigger.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE OR ALTER TRIGGER<\/span> [Name of Trigger]<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">ON<\/span> ALL SERVER<\/p>\n<p class=\"import-Standard\">FOR LOGON<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\">BEGIN<\/p>\n<p class=\"import-Standard\">&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p class=\"import-Standard\">END<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.54 MSSQL Tips showing the basic syntax for working with a logon trigger.. Source of T-SQL: https:\/\/www.mssqltips.com\/sqlservertip\/6103\/sql-server-logon-trigger-examples\/<\/p>\n<p class=\"import-Standard\">If the logon trigger is built incorrectly, you could find yourself locked out of your own database. Bhavesh Patel has an example for each of the five use cases.<\/p>\n<p class=\"import-Standard\">We did not address the fact that SQL Server has triggers in the Template Explorer. See Figure 13.41 for the location of the Database Trigger folder. See Figure 13.45 for the location of the general Trigger folder.<\/p>\n<h2>Stored Procedures<\/h2>\n<p class=\"import-Standard\">Stored procedures were mentioned earlier in the chapter as one of four ways for a program to work with a database. We did not explore the benefits and drawbacks of using a stored procedure. Nor did we explore how to create a stored procedure. We will address these points in this section.<\/p>\n<h3>The Big Debate<\/h3>\n<p class=\"import-Standard\">There are forums that have debated the question of which is better. There are well-written articles that attempt to show both sides. Some individuals point out that the advance of technology has rendered some reasons as moot. Do not expect this section to be the be-all-and-end-all on this topic. The following lists are some of the points made by individuals on different sides of this debate.<\/p>\n<h4>The Pros of using stored procedures.<\/h4>\n<ul>\n<li>These support modular programming.<\/li>\n<li>These allow faster execution.<\/li>\n<li>These reduce the volume of network traffic.<\/li>\n<li>These add another layer of security.<\/li>\n<li>The application developer can concentrate on the code while the database programmer can create the stored procedures.<\/li>\n<li>Changes made to the stored procedures do not require the source code to be recompiled. This is assuming that the stored procedures have the same parameter list.<\/li>\n<li>Older versions of SQL Server could not optimize SQL statements from a program, but could do it for stored procedures.\n<ul>\n<li>New versions of SQL Server support statement-level optimization.<\/li>\n<\/ul>\n<\/li>\n<li>Stored procedures can be invoked by numerous applications and programs.<\/li>\n<li>Query statements can be inspected without the need for the program to be executing.<\/li>\n<\/ul>\n<h4>The Cons of using stored procedures.<\/h4>\n<ul>\n<li>Stored procedures tend to bloat. New stored procedures are added, but old ones rarely are deleted.<\/li>\n<li>There is no documentation that states who might use a specific stored procedure. There is the fear that removing a stored procedure might break something.<\/li>\n<li>If the stored procedure is using dynamic SQL, then parameterized queries can be used to launch an SQL injection attack.\n<ul>\n<li>A well-designed program block would support the generation of SQL code on the fly.<\/li>\n<\/ul>\n<\/li>\n<li>Writers may not encapsulate pieces. This makes working with and debugging the stored procedures difficult.<\/li>\n<li>Fake data cannot be used in a stored procedure.\n<ul>\n<li>Testing out a stored procedure requires against some database tables. So a testing database is needed.<\/li>\n<\/ul>\n<\/li>\n<li>A database administrator would need to conduct performance tuning.<\/li>\n<li>Stored procedures tend to be based on a specific DBMS. Changing to a different DBMS would require rewriting the stored procedures.<\/li>\n<li>If a function is <em>deprecated<\/em> (planned removal), then any stored procedures using that function will not work.<\/li>\n<li>Source control is difficult to do for stored procedures. (Some individuals disagree with this statement.)<\/li>\n<\/ul>\n<p class=\"import-Standard\">There have been efforts to add an object relational model support (Entity Framework). This gets into Code-First and Database-First mappings of a database to programming classes. The Language Integrated Query (LINQ) that works with LAMBDA expressions generates lines that resemble SQL syntax. For a time, it looked like Microsoft was dropping LINQ. Then they changed and now it is being improved in every release of .NET. In a blog, there was a paragraph about a situation when LINQ could greatly increase the generated code size.<\/p>\n<p class=\"import-Standard\">For this edition, we will not explore LINQ. When LINQ is more stable and more mainstream, then we will consider adding more information about LINQ.<\/p>\n<h3>Creating Stored Procedures<\/h3>\n<p class=\"import-Standard\">Microsoft has developed two ways of creating a stored procedure within the SQL Server Management Studio.<\/p>\n<p class=\"import-Standard\">The first way is using the GUI support. Recall that the Template Explorer was at a high level above the individual databases. For creating a stored procedure, it is more linked to the current working database.<\/p>\n<p class=\"import-Standard\">You would work down to the Programmability folder. Figure 13.55 is a screenshot of a database using VisualBasic. Our C# example would be similar.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image38-1.jpeg\" alt=\"image\" width=\"624px\" height=\"351.08157480315px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.55 A screenshot of the \u201cObject Explorer\u201d tree with the \u201cProgrammability\u201d folder visible. Source of image: https:\/\/i.ytimg.com\/vi\/7ZwcfvUYkTg\/maxresdefault.jpg<\/p>\n<p class=\"import-Standard\">Expanding the Programmability folder will reveal the Stored Procedure folder. The first folder has the System Stored Procedures. See Figure 13.56.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image39-3.png\" alt=\"image\" width=\"516.739107611549px\" height=\"544.329553805774px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.56 Screenshot of part of the items in the Programmability folder. Source of image: https:\/\/i.sstatic.net\/7piek.png<\/p>\n<p class=\"import-Standard\">You would do a right mouse click on the Stored Procedures folder. You would select New Stored Procedure. A new query window would appear with boilerplate lines for the new stored procedure.<\/p>\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image40-3.png\" alt=\"image\" width=\"624px\" height=\"307.353595800525px\" \/><\/p>\n<p class=\"import-Standard\">Figure 13.57 Screenshot of the boilerplate stored procedure text. Source of image: https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/<\/p>\n<p class=\"import-Standard\">On the Query menu, select Specify Values for Template Parameters. Figure 12.58 shows the example entries.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Author<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">Name<\/span>\u00a0with your name.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Create Date<\/strong>: Enter today&#8217;s date.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Description<\/strong>: Briefly describe what the procedure does.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Procedure_Name<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">ProcedureName<\/span>\u00a0with the new stored procedure name.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Param1<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">@p1<\/span>\u00a0with your first parameter name, such as\u00a0<em class=\"import-Emphasis\">@ColumnName1<\/em>.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Datatype_For_Param1<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">int<\/span>\u00a0with your first parameter&#8217;s datatype, such as\u00a0<em class=\"import-Emphasis\">nvarchar<\/em><em class=\"import-Emphasis\">(<\/em><em class=\"import-Emphasis\">50)<\/em>.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Default_Value_For_Param1<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">0<\/span>\u00a0with your first parameter&#8217;s default value, or\u00a0<em class=\"import-Emphasis\">NULL<\/em>.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Param2<\/strong>: Replace\u00a0<span class=\"import-HTMLCode\">@p2<\/span>\u00a0with your second parameter name, such as\u00a0<em class=\"import-Emphasis\">@ColumnName2<\/em>.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">@Datatype_For_Param2<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">int<\/span>\u00a0with your second parameter&#8217;s datatype, such as\u00a0<em class=\"import-Emphasis\">nvarchar<\/em><em class=\"import-Emphasis\">(<\/em><em class=\"import-Emphasis\">50)<\/em>.<\/p>\n<p class=\"import-Standard\" style=\"background-color: #ffffff;margin-left: 18pt\"><strong class=\"import-Strong\">Default_Value_For_Param2<\/strong>: As appropriate, replace\u00a0<span class=\"import-HTMLCode\">0<\/span>\u00a0with your second parameter&#8217;s default value, or\u00a0<em class=\"import-Emphasis\">NULL<\/em>.<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image41-3.png\" alt=\"image\" width=\"372.92157480315px\" height=\"252.287979002625px\" \/><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">A. Suggested Example Text<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">B. Screenshot of the completed floating dialog box.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.58 The Specify Values for Template Parameters dialog box. Source of image: https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16<\/p>\n<p class=\"import-Standard\">When finished, hit \u201cOK.\u201d<\/p>\n<p class=\"import-Standard\">You would be doing the actual editing inside the Query Editor. Figure 13.59 shows the example stored procedure.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; =======================================================<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Create Stored Procedure Template for Azure SQL Database<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; =======================================================<\/span><\/p>\n<p class=\"import-Standard\">SET ANSI_NULLS ON<\/p>\n<p class=\"import-Standard\">GO<\/p>\n<p class=\"import-Standard\">SET QUOTED_IDENTIFIER ON<\/p>\n<p class=\"import-Standard\">GO<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; =============================================<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Author: My Name<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Create Date: 01\/23\/2024<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Description: Returns the customer&#8217;s company name.<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; =============================================<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> SalesLT.uspGetCustomerCompany<\/p>\n<p class=\"import-Standard\">(<\/p>\n<p class=\"import-Standard\">&#8212; Add the parameters for the stored procedure here<\/p>\n<p class=\"import-Standard\">@LastName nvarchar(50) = NULL,<\/p>\n<p class=\"import-Standard\">@FirstName nvarchar(50) = NULL<\/p>\n<p class=\"import-Standard\">)<\/p>\n<p class=\"import-Standard\">AS<\/p>\n<p class=\"import-Standard\">BEGIN<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; SET NOCOUNT ON added to prevent extra result sets from<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; interfering with SELECT statements.<\/span><\/p>\n<p class=\"import-Standard\">SET NOCOUNT ON<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Insert statements for procedure here<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> SalesLT.Customer<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName AND LastName = @LastName;<\/p>\n<p class=\"import-Standard\">END<\/p>\n<p class=\"import-Standard\">GO<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.59 The final version of the running example.<\/p>\n<p class=\"import-Standard\">The Query menu has a Parse button that will check for syntax errors.<\/p>\n<p class=\"import-Standard\">Executing these lines will create the actual stored procedure and will store it as an object in the database. Revisit the Stored Procedure and select Refresh.<\/p>\n<p class=\"import-Standard\">To execute the new stored procedure, do a right mouse click on the stored procedure name and select Execute Stored Procedure. In the Execute Procedure window, you will need to enter some values for the blank parameters. Then hit the OK button.<\/p>\n<p class=\"import-Standard\">If you were using the Microsoft\u2019s AdventureWorksLT2022 database, then entering \u201cCannon\u201d for the @LastName parameter and \u201cChris\u201d for the @FirstName parameter would yield the following output:<\/p>\n<p class=\"import-Standard\">Chris Cannon Outdoor Sporting Goods<\/p>\n<p class=\"import-Standard\">The second way is using only the Transact-SQL lines. You would have the same text as Figure 13.59 without the comment lines. You would enter these lines manually.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> SalesLT.uspGetCustomerCompany1<\/p>\n<p class=\"import-Standard\">@LastName nvarchar(50),<\/p>\n<p class=\"import-Standard\">@FirstName nvarchar(50)<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\">SET NOCOUNT ON;<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM S<\/span>alesLT.Customer<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName <span style=\"color: #3366ff\">AND<\/span> LastName = @LastName;<\/p>\n<p class=\"import-Standard\">GO<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.60 The raw Transact-SQL lines.<\/p>\n<p class=\"import-Standard\">Rajendra Gupta\u2019s article is based on an older version of the SQL Server Management Studio.<\/p>\n<p class=\"import-Standard\">The sources used for this section did not explain the actual lines. Also, the sources did not explain that the text of the created stored procedure is different from the creation command lines.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\" style=\"text-align: center\"><strong>Extracted lines from the Microsoft Stored Procedure Example<\/strong><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\" style=\"text-align: center\"><strong>An Explanation<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; ======================================<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Create Stored Procedure Template for Azure SQL Database<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; ======================================<\/span><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Most programming languages use a pair of right leaning slant bars to start a comment. In SQL, it is a pair of hyphens (U+0045).<\/p>\n<p class=\"import-Standard\">SQL Server Management Studio uses green font to show that a line is not an executable line.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">SET ANSI_NULLS ON<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">When ANSI_NULLS is ON, a <span style=\"color: #3366ff\">SELECT<\/span> statement that uses <span style=\"color: #3366ff\">WHERE<\/span> column_name = NULL returns zero rows even if there are NULL values in <em>column_name<\/em>. A <span style=\"color: #3366ff\">SELECT<\/span> statement that uses WHERE column_name &lt;&gt; NULL returns zero rows even if there are non-NULL values in <em>column_name<\/em>.<\/p>\n<p class=\"import-Standard\">Prior to SQL Server 2017, the OFF option would have returned rows with NULL values.<\/p>\n<p class=\"import-Standard\">Beginning with SQL Server 2017, the OFF option has been deprecated.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">GO<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">Recall that Microsoft SQL came from the Sybase database environment. Over time, new features were added, but the GO statement was retained<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote14anc\" href=\"#sdfootnote14sym\">14<\/a><\/sup>.<\/p>\n<p class=\"import-Standard\">The GO command is used inside the Transit-SQL code when batches are being processed. It is not a true SQL command. It is recognized by the SQL Server Management Studio and by other SQL Server tools.<\/p>\n<p class=\"import-Standard\">Attempting to create two stored procedures would require placing the word GO between the two.<\/p>\n<p class=\"import-Standard\">Changing to a different database would require the word GO.<\/p>\n<p class=\"import-Standard\">Locally declared variables exist only between the GO words.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">SET QUOTED_IDENTIFIER ON<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">This is the default setting.<\/p>\n<p class=\"import-Standard\">OFF would treat single quotes and double quote strings the same.<\/p>\n<p class=\"import-Standard\">ON would instruct the SQL Server to treat values inside a pair of double quotes an identifier<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote15anc\" href=\"#sdfootnote15sym\">15<\/a><\/sup>.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">GO<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">This follows the end of a batch.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; ======================================<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Author: My Name<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Create Date: 01\/23\/2024<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Description: Returns the customer&#8217;s company name.<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; ======================================<\/span><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The generated stored procedure template has a spot for adding your name and a short description of the purpose for the stored procedure.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">CREATE PROCEDURE SalesLT.uspGetCustomerCompany<\/p>\n<p class=\"import-Standard\">(<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Add the parameters for the stored procedure here<\/span><\/p>\n<p class=\"import-Standard\">@LastName nvarchar(50) = NULL,<\/p>\n<p class=\"import-Standard\">@FirstName nvarchar(50) = NULL<\/p>\n<p class=\"import-Standard\">)<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">This is the header for the created block. It contains the name of the table and the name of the stored procedure. The \u201cusp\u201d is a convention that is used to identify a <strong>u<\/strong>ser defined <strong>s<\/strong>tored <strong>p<\/strong>rocedure.<\/p>\n<p class=\"import-Standard\">The at symbol (@) identifies the name of a variable.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">This is not explained, but based on the use of this word as a key word for changing the name of an output, it appears this is stating that the parameters will be used in the following block.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">BEGIN<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; SET NOCOUNT ON added to prevent extra result sets from<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; interfering with SELECT statements.<\/span><\/p>\n<p class=\"import-Standard\">SET NOCOUNT ON<\/p>\n<p class=\"import-Standard\"><span style=\"color: #00ff00\">&#8212; Insert statements for procedure here<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> FirstName, LastName, CompanyName<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> SalesLT.Customer<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> FirstName = @FirstName <span style=\"color: #3366ff\">AND<\/span> LastName = @LastName;<\/p>\n<p class=\"import-Standard\">END<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">The actual lines are inside a BEGIN-END block. These two key words are optional. Many programming languages use curved braces. Wirth based languages such as Algo, Pascal, and Modula family do use the BEGIN-END markers<sup class=\"import-FootnoteReference\"><a id=\"sdfootnote16anc\" href=\"#sdfootnote16sym\">16<\/a><\/sup>.<\/p>\n<p class=\"import-Standard\">When the SQL query is executed, it may report on how many lines are in the result set. The SET NOCOUNT ON will prevent this message from being generated.<\/p>\n<p class=\"import-Standard\">The last few lines are the actual SQL lines.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">GO<\/p>\n<\/td>\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.61 The raw Transact-SQL lines with explanations.<\/p>\n<p class=\"import-Standard\">Another way of executing a stored procedure is with the EXEC command:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">EXEC SalesLT.uspGetCustomerCompany @FirstName = \u201cChris\u201d @LastName = \u201cCannon\u201d<\/p>\n<p class=\"import-Standard\">The EXEC is optional. You could execute the stored procedure by simply typing the name of the stored procedure:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">SalesLT.uspGetCustomerCompany @FirstName = \u201cChris\u201d @LastName = \u201cCannon\u201d<\/p>\n<p class=\"import-Standard\">Just like you can drop tables, you can drop stored procedures:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\"><span style=\"color: #3366ff\">DROP PROCEDURE<\/span> SalesLT.uspGetCustomerCompany<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">GO<\/p>\n<p class=\"import-Standard\">If you need an output to be used elsewhere, then you would need to declare an <em>OUT parameter<\/em>. Figure 12.62 shows how to declare the OUT parameter and how to use it.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">CREATE PROCEDURE<\/span> dbo.uspGetAddressCount @City nvarchar(30), @AddressCount int <span style=\"color: #3366ff\">OUT<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> @AddressCount = count(*)<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">FROM<\/span> AdventureWorks.Person.Address<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">WHERE<\/span> City = @City<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">DECLARE @AddressCount int<\/p>\n<p class=\"import-Standard\">EXEC dbo.uspGetAddressCount @City = &#8216;Calgary&#8217;, @AddressCount = @AddressCount OUT<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\">SELECT<\/span> @AddressCount<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.62 Creating a stored procedure that has an OUT parameter and showing an example execution. Source of example: https:\/\/www.mssqltips.com\/sqlservertutorial\/163\/returning-sql-server-stored-procedure-parameter-values-to-a-calling-stored-procedure\/<\/p>\n<p class=\"import-Standard\">The OUT parameter could be passed to a calling program. This is how this would be done:<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">cmd.Parameters.Add(&#8220;@ClientName&#8221;, SqlDbType.VarChar, 100);<\/p>\n<p class=\"import-Standard\">cmd.Parameters[&#8220;@ClientName&#8221;].Direction = ParameterDirection.Output;<\/p>\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\">clientName = Convert.ToString(cmd.Parameters[&#8220;@ClientName&#8221;].Value);<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.63 Extract for declaring and receiving output values from a SQL stored procedure. Source of extract: https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp<\/p>\n<p class=\"import-Standard\">This has been a simple, high-level coverage of stored procedures. The body of a stored procedure could have been deleted and drop lines. There could be calls to other stored procedures. And stored procedures can have many lines. We have avoided covering dynamic SQL commands, because this approach could result in an SQL injection attack.<\/p>\n<h2>Creating Views<\/h2>\n<p class=\"import-Standard\">A <em>view <\/em>is a virtual table that is the result of a query. There are three reasons for creating a view:<\/p>\n<ul>\n<li>To focus, simplify, and customize the perception each user has of the database.<\/li>\n<li>As a security mechanism by allowing users to access data through the view, without granting the users permissions to directly access the underlying base tables.<\/li>\n<li>To provide a backward compatible interface to emulate a table whose schema has changed.<\/li>\n<\/ul>\n<p class=\"import-Standard\">The syntax has a column list in the header and a select statement in the body.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">CREATE<\/span> <span class=\"import-hljs-keyword\">VIEW<\/span><\/span> [<span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">OR<\/span> <span class=\"import-hljs-keyword\">ALTER<\/span><\/span>] schema_name.view_name [(column_list)]<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">AS<\/span><\/p>\n<p class=\"import-Standard\">The select lines;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.64 Simple syntax of a create view command. Source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\n<p class=\"import-Standard\">If the column list is not used in the header, then column names would come from the SELECT statement.<\/p>\n<p class=\"import-Standard\">Imagine that your database has a Products table, a Sales.OrderItems table, and a Sales.Orders table. And imagine that upper management is interested in the total sales by date and by product. Upper management has no interest in the number of sold items. We could e-mail the SQL lines (Figure 13.65) and let them execute this query.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">SELECT<\/span><\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">year<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> y,<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">month<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> m,<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\">day<\/span>(order_date) <span class=\"import-hljs-keyword\">AS<\/span> d,<\/p>\n<p class=\"import-Standard\">p.product_id,<\/p>\n<p class=\"import-Standard\">product_name,<\/p>\n<p class=\"import-Standard\">quantity * i.list_price <span class=\"import-hljs-keyword\">AS<\/span> sales<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">FROM<\/span><\/p>\n<p class=\"import-Standard\">sales.orders <span class=\"import-hljs-keyword\">AS<\/span> o<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">INNER<\/span> <span class=\"import-hljs-keyword\">JOIN<\/span><\/span> sales.order_items <span class=\"import-hljs-keyword\">AS<\/span> i<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> o.order_id = i.order_id<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">INNER<\/span> <span class=\"import-hljs-keyword\">JOIN<\/span> <\/span>production.products <span class=\"import-hljs-keyword\">AS<\/span> p<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">ON<\/span> p.product_id = i.product_id;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.65 Extracting data from a combination of three tables. Unchanged source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\n<p class=\"import-Standard\">The other option is to take the lines from Figure 13.65 and place in the body of the<span style=\"color: #3366ff\"> CREATE VIEW<\/span> and create a view with the name of Sales.DailySales. Then we could e-mail the lines from Figure 12.66 to upper management.<\/p>\n<table style=\"width: 478.8pt\">\n<tbody>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">SELECT<\/span> *<\/p>\n<p class=\"import-Standard\"><span class=\"import-hljs-keyword\" style=\"color: #3366ff\">FROM<\/span><\/p>\n<p class=\"import-Standard\">Sales.DailySales<\/p>\n<p class=\"import-Standard\"><span style=\"color: #3366ff\"><span class=\"import-hljs-keyword\">ORDER<\/span> <span class=\"import-hljs-keyword\">BY<\/span><\/span> y, m, d, product_name;<\/p>\n<p class=\"import-Standard\">\n<\/td>\n<\/tr>\n<tr class=\"TableNormal-R\">\n<td class=\"TableNormal-C\" style=\"padding: 0pt 5.4pt 0pt 5.65pt;border: solid #00000A 0.5pt\">\n<p class=\"import-Standard\"><img decoding=\"async\" src=\"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-content\/uploads\/sites\/2211\/2025\/01\/image42-3.png\" alt=\"image\" width=\"461.596745406824px\" height=\"245.135958005249px\" \/><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"import-Standard\">Figure 13.66 The View lines and example output. Source of code: https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/p>\n<p class=\"import-Standard\">To make a change, the header line is \u201c<span style=\"color: #3366ff\">CREATE OR ALTER,<\/span>\u201d which is different from the syntax for changing a table. You would repeat the column names and add the new column name. The <span style=\"color: #3366ff\">SELECT<\/span> block would include the old lines plus the new line.<\/p>\n<p class=\"import-Standard\">The SQLSERVER Tutorial.net has additional examples.<\/p>\n<h2>A Word About Prefixes<\/h2>\n<p class=\"import-Standard\">You may have noticed that system defined stored procedures use \u201csp_\u201d at the beginning of the name. This is a standard naming convention and you must not use it for your own created stored procedures. If you do, then the SQL Server will search the master database for your stored procedure before visiting your user database.<\/p>\n<p class=\"import-Standard\">The user defined examples used prefixes in order to make the examples clearer. As noted elsewhere in this textbook, prefixes are not needed.<\/p>\n<h2>Key Terms<\/h2>\n<p class=\"import-Standard\"><strong>Application Programming Interface (API)<\/strong><strong>: <\/strong>A programming language will have objects and classes. Programmers will use these instead of creating their own block of code for a task. An example would be the SqlConnection object.<\/p>\n<p class=\"import-Standard\"><strong>concatenated<\/strong>: In programming, pieces are combined or added to form a string.<\/p>\n<p class=\"import-Standard\"><strong>connection string<\/strong>: This is a series of value pairs that is needed by a program in order to access a database.<\/p>\n<p class=\"import-Standard\"><strong>console project<\/strong>: This will return the rows that semi join had rejected.<\/p>\n<p class=\"import-Standard\"><strong>deprecated<\/strong><em>:<\/em> This means that the software feature is usable, but is obsolete. The practice is to state in a revision that a certain method or class or function will be removed in a future version. The word \u201cdeprecated\u201d is used in the warning.<\/p>\n<p class=\"import-Standard\"><strong>functions<\/strong>: These are built-in blocks of SQL lines for performing tasks such as obtaining the average of values in a column, counting the number of items in a column, and so on.<\/p>\n<p class=\"import-Standard\"><strong>graphic user interface (GUI)<\/strong>: The eye-pleasing front end to a program.<\/p>\n<p class=\"import-Standard\"><strong>instance<\/strong>: This is a running example or session.<\/p>\n<p class=\"import-Standard\"><strong>OUT parameter<\/strong>: This is used within the SQL Server environment for returning a value other than a result set. If this is being sent to the calling program, then that program would need to have an out variable declared.<\/p>\n<p class=\"import-Standard\"><strong>prepared statement<\/strong>: This is a programming approach whereby values are collected and added to a specially created statement for routing to a database.<\/p>\n<p class=\"import-Standard\"><strong>regular expression<\/strong><em>: <\/em>This does a pattern match against permitted or not permitted characters.<\/p>\n<p class=\"import-Standard\"><strong>result set<\/strong><strong>:<\/strong> What comes back from a SQL query.<\/p>\n<p class=\"import-Standard\"><strong>SQL injection attack<\/strong><strong>:<\/strong> This is a technique whereby a hacker can craft a SQL query that can obtain more data than wanted by the database managers.<\/p>\n<p class=\"import-Standard\"><strong>Stored procedures<\/strong>: These work with the actual SQL command inside the database environment.<\/p>\n<p class=\"import-Standard\"><strong>triggers<\/strong>: These are SQL lines that are invoked when an action takes place.<\/p>\n<p class=\"import-Standard\"><strong>view<\/strong>: This is a virtual table that is the result of a query.<\/p>\n<h2>Exercises<\/h2>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">1. Explain the following terms:<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">1. Application Programming Interface (API)<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">2 concatenated<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">3. connection string<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">4. console project<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">5. deprecated<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">6. function<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">7. graphic user interface<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">8. instance<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">9, OUT parameter<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">10. prepared statement<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">11. regular expression<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">12. result set<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">13. SQL Injection Attack<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">14. stored procedures<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">15. triggers<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">16. view<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">2. What are the four ways of working with a database?<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">3. Explain how a hacker could trick a concatenated string into providing more data. [IS2020 A3.2.14]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">4. Using an example from Java or from C# or from another programming language, show how you would embed a <span style=\"color: #3366ff\">SELECT<\/span> query. [CS2013 IM\/Query Languages 5 and IT2017 ITE-IMA-04d.]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">5. For the previous question, list and explain the API calls. [DS2021 PDA Programming]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">6. You are collecting address information from a person. Which fields could be handled without using a text box?<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">7. Explain how a regular expression could be used for validating a user\u2019s input.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">8. Using the references in this chapter, come up with a regular expression for something. Explain why you made this string as your answer.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">9. What is a SQL Server template? How is it used? [CS2013 IM\/Query Languages 4.]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">10. You know that a city uses a house numbering scheme whereby the house numbers differ by four. The database has all of the addresses stored in a database table. A dead-end street is being extended for a distance. You have been asked to add to the database the next 20 house numbers. Explain how this task could be completed by using functions.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">11. If the task in the previous question took place frequently, then a trigger action could be done. Explain how this might be achieved.<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">12. What are the benefits of using functions and triggers. [IS2020 A3.2.1 3]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">13. Write a stored procedure that uses at least two parameters. Explain how you could prevent unauthorized users from firing off your stored procedure. [CS2013 IM\/Query Languages 6.]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">14. What are some ways that a user could interact with a database. [DS2021 SDM-Software Design and Development Skills]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">15. Provide an example of a view. State who is the user. State why the view would be a good approach for this user. [IT2017 ITE-IMA-04f.]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">16. What are some ways of securing a database. I am looking for at least two ways of securing a database. [IS2020 A3.2.1 4]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">17. This was implied in this chapter, but never explained. Explain why we would want to write a program to access a database. [DS2021 SDM-Software Design and Development]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">18. Roles were mentioned in Chapter 11, but you were not asked to demonstrate an understanding of this topic. Describe how you might go about creating and managing database users. [IT2017 ITE-IMA Domain Information Management E.]<\/p>\n<p class=\"import-Standard\" style=\"margin-left: 18pt\">19. Write about three ways of providing security to the database. This is an open-ended question. [IT2017 ITE-IMA Domain Information Management E.]<\/p>\n<h2>A Running Project<\/h2>\n<p class=\"import-Standard\">You should have your project in great shape.<\/p>\n<p class=\"import-Standard\">Some of the learning outcomes for this chapter are of an application nature. The following tasks will provide an opportunity to demonstrate your understanding.<\/p>\n<p class=\"import-Standard\">1. Using your project, create a query by filling in a template. [CS2013 IM\/Query Languages 4 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\n<p class=\"import-Standard\">2. Use the insights from this chapter to write a query that is requested from a programming language. This query should select at least one column from a table. [CS2013 IM\/Query Languages 5 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\n<p class=\"import-Standard\">3. Use the insights from this chapter to create a stored procedure. The stored procedure needs to work with at least two parameters. [CS2013 IM\/Query Languages 6 and ITS2017 ITE-IMA-04 Database query languages d.]<\/p>\n<p class=\"import-Standard\">4. Use the insights from this chapter to create one trigger. [IS2020 A3.2.1 3.]<\/p>\n<p class=\"import-Standard\">5. Using any of the foregoing tools, create something that would use a function. [IS2020 A3.2.1 3.]<\/p>\n<p class=\"import-Standard\">6. Image the regular user of your project database. How would you limit what this person could see? [IT2017 ITE-IMA Domain Information Management E.]<\/p>\n<p class=\"import-Standard\">7. Create two views:<\/p>\n<p class=\"import-Standard\" style=\"padding-left: 40px\">A. A view that is fixed and will always produce the same result set.<\/p>\n<p class=\"import-Standard\" style=\"padding-left: 40px\">B. A view that permits the user to select different parameters and thus have a different result set.<\/p>\n<p class=\"import-Standard\">[IT2017 ITE-IMA-04 Database query languages f.]<\/p>\n<h2>Attribution<\/h2>\n<p class=\"import-Standard\">This chapter of <em>Database Design<\/em> is a brand-new addition.<\/p>\n<p class=\"import-Standard\">This chapter drew from many sources.<\/p>\n<h2>Image Attributions<\/h2>\n<p class=\"import-Standard\">No second edition images were used.<\/p>\n<h2>References<a id=\"_Hlk180124541\"><\/a><\/h2>\n<p class=\"import-Standard\">Troels Arvin. \u201cComparison of different SQSL implementations,\u201d Troels Arvin, December 29, 2018. <a class=\"rId52\" href=\"https:\/\/troels.arvin.dk\/db\/rdbms\/\">https:\/\/troels.arvin.dk\/db\/rdbms\/<\/a><\/p>\n<p class=\"import-Standard\">Daniel Calbimonte. \u201cSQL GO command in SQL Server,\u201d SQLShack, May 18, 2021. https:\/\/www.sqlshack.com\/sql-go-command-in-sql-server\/<\/p>\n<p class=\"import-Standard\">\u201cCreate a stored procedure,\u201d Learn Microsoft, January 30, 2024. <a class=\"rId53\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/stored-procedures\/create-a-stored-procedure?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">\u201cCREATE VIEW (Transact-SQL),\u201d Learn Microsoft, May 23, 2023. <a class=\"rId54\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-view-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-view-transact-sql?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">Admir Dizdar. \u201cSQL Injection Payloads: How SQLi exploits work,\u201d Bright, September 16, 2021 (Updated on November 14, 2023). <a class=\"rId55\" href=\"https:\/\/brightsec.com\/blog\/sql-injection-payloads\/\">https:\/\/brightsec.com\/blog\/sql-injection-payloads\/<\/a><\/p>\n<p class=\"import-Standard\">\u201cDifferences between ISNUL and COALESCE,\u201d Learn Microsoft, June 26, 2008. <a class=\"rId56\" href=\"https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/sqltips\/differences-between-isnull-and-coalesce\">https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/sqltips\/differences-between-isnull-and-coalesce<\/a><\/p>\n<p class=\"import-Standard\" style=\"margin-left: 36pt\">The Stackoverflow forum discussed this topic. One writer cited the Microsoft article, but modified the example. I used the modified example, because it was clearer. See <a class=\"rId57\" href=\"https:\/\/stackoverflow.com\/questions\/19115040\/replace-null-with-blank-value-or-zero-in-sql-server\">https:\/\/stackoverflow.com\/questions\/19115040\/replace-null-with-blank-value-or-zero-in-sql-server<\/a><\/p>\n<p class=\"import-Standard\">Rajendra Gupta. \u201cSET QUOTED_IDENTIFIER settings in SQL Server,\u201d SQLShack, October 17, 2019. <a class=\"rId58\" href=\"https:\/\/www.sqlshack.com\/set-quoted_identifier-settings-in-sql-server\/\">https:\/\/www.sqlshack.com\/set-quoted_identifier-settings-in-sql-server\/<\/a><\/p>\n<p class=\"import-Standard\">Rajendra Gupta. \u201cScript templates in SQL Server Management Studio (SMS),\u201d SQLShack, April 27, 2020. <a class=\"rId59\" href=\"https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/\">https:\/\/www.sqlshack.com\/script-templates-in-sql-server-management-studio-ssms\/<\/a><\/p>\n<p class=\"import-Standard\">Bar Hofesh. \u201cSQL Injection Attack: how It Works, Examples and Prevention,\u201d Bright, April 8, 2022. <a class=\"rId60\" href=\"https:\/\/brightsec.com\/blog\/sql-injection-attack\/\">https:\/\/brightsec.com\/blog\/sql-injection-attack\/<\/a><\/p>\n<p class=\"import-Standard\" style=\"padding-left: 40px\">Bar Hofesh referenced a cheat sheet in his article. See https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/SQL_Injection_Prevention_Cheat_Sheet.html<\/p>\n<p class=\"import-Standard\">\u201cHow to Setup a Connection with SQL Serer Database in Visual Studio,\u201d Programmingempire, December 17, 2022 (updated on April 6, 2022). <a class=\"rId61\" href=\"https:\/\/www.programmingempire.com\/how-to-setup-a-connection-with-sql-server-database-in-visual-studio\/\">https:\/\/www.programmingempire.com\/how-to-setup-a-connection-with-sql-server-database-in-visual-studio\/<\/a><\/p>\n<p class=\"import-Standard\">Amit Mohanty. \u201cHow To Use Output Parameter In Stored Procedure In Stored Procedure In C#,\u201d C3 Corner, October 19, 2023. <a class=\"rId62\" href=\"https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp\">https:\/\/www.c-sharpcorner.com\/Blogs\/example-on-how-to-use-output-parameter-in-stored-procedure-in-c-sharp<\/a><\/p>\n<p class=\"import-Standard\">Bhavesh Patel. \u201cSQL Server Logon Trigger Examples,\u201d MSSQL Tips, n.d. https:\/\/www.mssqltips.com\/sqlservertip\/6103\/sql-server-logon-trigger-examples\/<\/p>\n<p class=\"import-Standard\">\u201cSET ANSI_NULLS (Transact-SQL),\u201d Learn Microsoft, April 5, 2024. <a class=\"rId63\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-ansi-nulls-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-ansi-nulls-transact-sql?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">\u201cSET NOCOUNT (Transact-SQL),\u201d Learn Microsoft, September 3, 2024. <a class=\"rId64\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-nocount-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-nocount-transact-sql?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">\u201cSET QUOTED_IDENTIFIER (Transact-SQL),\u201d Learn Microsoft, August 9, 2024. <a class=\"rId65\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-quoted-identifier-transact-sql?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-quoted-identifier-transact-sql?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">\u201cSQL Server CREATE TRIGGER,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId66\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/\">https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-create-trigger\/<\/a><\/p>\n<p class=\"import-Standard\">\u201cSQ; Server CREATE VIEW,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId67\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/\">https:\/\/www.sqlservertutorial.net\/sql-server-views\/sql-server-create-view\/<\/a><\/p>\n<p class=\"import-Standard\">\u201cSQL Server DDL Trigger,\u201d SQLSERVER Tutorial.net, n.d. <a class=\"rId68\" href=\"https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-ddl-trigger\/\">https:\/\/www.sqlservertutorial.net\/sql-server-triggers\/sql-server-ddl-trigger\/<\/a><\/p>\n<p class=\"import-Standard\">\u201cSQL Server Functions,\u201d W3 schools, n.d. <a class=\"rId69\" href=\"https:\/\/www.w3schools.com\/sqL\/sql_ref_sqlserver.asp\">https:\/\/www.w3schools.com\/sqL\/sql_ref_sqlserver.asp<\/a><\/p>\n<p class=\"import-Standard\">Stephen Toub. \u201cPerformance Improvements in .NET 9,\u201d Dev Blogs, September 12, 2024. <a class=\"rId70\" href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-9\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-9\/<\/a><\/p>\n<p class=\"import-Standard\">\u201cUse templates in SQL Server Management Studio,\u201d Learn Microsoft, March 3, 2023. <a class=\"rId71\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/ssms\/template\/templates-ssms?view=sql-server-ver16<\/a><\/p>\n<p class=\"import-Standard\">Ahmad Yaseen. \u201cINSERT INTO T-SQL Statement in SQL Server,\u201d SQLShack, March 27, 2020. <a class=\"rId72\" href=\"https:\/\/www.sqlshack.com\/insert-into-t-sql-statement-in-sql-server\/\">https:\/\/www.sqlshack.com\/insert-into-t-sql-statement-in-sql-server\/<\/a><\/p>\n<p>&nbsp;<\/p>\n<div id=\"sdfootnote1sym\"><a href=\"#sdfootnote1anc\">1<\/a>A procedural query spells out the steps for obtaining a result set. A non-procedural query states what is desired and leaves it to the system to figure out the steps. Everything we have addressed has been a non-procedural approach.<\/div>\n<div id=\"sdfootnote2sym\"><a href=\"#sdfootnote2anc\">2<\/a>Flow Control means the actions taken to prevent information or data from flowing in a way that it reaches unauthorized uses.<\/div>\n<div id=\"sdfootnote3sym\"><a href=\"#sdfootnote3anc\">3<\/a>The W3 schools website C# Tutorial (https:www.w3schools.com\/cs\/index.php) is based on Visual Studio 2019. The screenshots are different from what you will see in this chapter.<\/div>\n<div id=\"sdfootnote4sym\"><a href=\"#sdfootnote4anc\">4<\/a>C#. This is pronounced as \u201cC Sharp\u201d and this is a reference to a symbol used in written music (Unicode U+1D130 and U + 1D131). Since the standard keyboard does not have this symbol, the pound sign is used as a work-around, which is Unicode U+0023. This is a programming language that was developed by Microsoft. It runs on the .NET Framework. It is used to develop web apps, desktop apps, mobile apps, games, and more. It is similar to C++, Java, and JavaScript. The explanations in this chapter assume no background in this programming language.<\/div>\n<div id=\"sdfootnote5sym\"><a href=\"#sdfootnote5anc\">5<\/a>The .NET 8 has been out since Spring 2024. While working on this edition, I have decided to delay doing an upgrade. At this writing, .NET 9 is in early release status.<\/div>\n<div id=\"sdfootnote6sym\"><a href=\"#sdfootnote6anc\">6<\/a>There are lines that are used in every C# program. When Microsoft designed the support for writing C# code, they provided the option of hiding these \u201cboilerplate\u201d code lines into another file. When learning to program in C#, it is good to see these lines.<\/div>\n<div id=\"sdfootnote7sym\"><a href=\"#sdfootnote7anc\">7<\/a>You are providing a string value to the connection object. You are working with an API.<\/div>\n<div id=\"sdfootnote8sym\"><a href=\"#sdfootnote8anc\">8<\/a>A cookie is a small file stored on a person\u2019s computer. This may store a shopping basket list. This file may contain the password for a website and the previously used queries.<\/div>\n<div id=\"sdfootnote9sym\"><a href=\"#sdfootnote9anc\">9<\/a>Our style guide has each word capitalized. Java, C#, and other programming languages have programmers that have decided upon the customs and approaches for coding. In these two programming languages, minor variables follow the camel casing approach. This is not a problem since the values are passed to the database instead of the actual variable name.<\/div>\n<div id=\"sdfootnote10sym\"><a href=\"#sdfootnote10anc\">10<\/a>Recall that we can use the <span style=\"color: #3366ff\">CHECK<\/span> operator to ensure that the permitted values are used.<\/div>\n<div id=\"sdfootnote11sym\"><a href=\"#sdfootnote11anc\">11<\/a>From Geeks for Geeks:<\/div>\n<div style=\"padding-left: 40px\">SQL Server Replication is a robust feature used to distribute and synchronize data across multiple databases, ensuring consistency and data integrity. By leveraging the \u201cPublish and Subscribe\u201d model, SQL Server allows for flexible data distribution, whether it\u2019s full database replication or specific parts such as tables and views.<\/div>\n<div>This topic is beyond the scope of this chapter and textbook. For more information see https:\/\/www.geeksforgeeks.org\/sql-server-replication\/<\/div>\n<div id=\"sdfootnote12sym\"><a href=\"#sdfootnote12anc\">12<\/a>Ahmad Yaseen explained this in his article. See the reference list for the article citation.<\/div>\n<div id=\"sdfootnote13sym\"><a href=\"#sdfootnote13anc\">13<\/a>By using<span style=\"color: #3366ff\"> UNION ALL<\/span>, duplicates would be retained. Without testing the example, I am thinking that the aliasing action is not needed.<\/div>\n<div id=\"sdfootnote14sym\"><a href=\"#sdfootnote14anc\">14<\/a>Many programming languages have support for GoTo and for break. In 1968 Edsger W Dijkstra, a pioneer in computer science, published \u201cGo To Statement Considered Harmful.\u201d The issue with these two is that the created code is hard to follow. Today it is rare to see GoTo in a program. The break keyword has continued. But it is slowly on its way out. In Java 14, the switch structure was changed to avoid using the break keyword. Instead, lambda arrows are used. https:\/\/nipafx.dev\/java-switch\/ shows the old way and the new way with examples. https:\/\/nipafx.dev\/java-13-switch-expressions\/ explained the issues with the old way in some detail.<\/div>\n<div id=\"sdfootnote15sym\"><a href=\"#sdfootnote15anc\">15<\/a>When this line is not used, the default behavior is ON. This causes SQL Server to follow the ISO rules. A create table command like the following succeeds:<\/div>\n<div style=\"padding-left: 40px\"><span style=\"color: #3366ff\">CREATE TABLE<\/span> &#8220;select&#8221; (&#8220;identity&#8221; <span style=\"color: #3366ff\">INT IDENTITY NOT NULL<\/span>, &#8220;order&#8221; <span style=\"color: #3366ff\">INT NOT<\/span> NULL);<\/div>\n<div>With the OFF option, this would fail. Notice the words in double quotes are normally used as reserved keyword names. Otherwise, we would not need to use any quotes.<\/div>\n<div>The ON option requires that literals or strings must be inside single quotes, because entries in double quotes are being treated as object names. The following example shows a pair of double quotes around the table name and four single quotes in the text string:<\/div>\n<div style=\"padding-left: 40px\"><span style=\"color: #3366ff\">INSERT INTO<\/span> dbo.&#8221;Test&#8221; <span style=\"color: #3366ff\">VALUES<\/span> (7, &#8216;Text with a single &#8221; quote&#8217;);<\/div>\n<div style=\"padding-left: 40px\">OUTPUT: 7 Text with a single \u2018 quote<\/div>\n<div>For more single quote examples, see Chapter 9 \u201cDML: INSERT INTO\u201d section, Figure 9.35, Figure 9.45, and Figure 9.47.<\/div>\n<div>Figure 9.38 shows that Microsoft\u2019s error messages use single quotes too.<\/div>\n<div>Figure 9.24 shows the correct usage of double quotes.<\/div>\n<div>See the reference for \u201cSET QUOTED_IDENTIFIER (Transact-SQL).\u201d<\/div>\n<div>Be aware that in programming languages, a single quote is for a single character. Double quotes are used for strings.<\/div>\n<div id=\"sdfootnote16sym\"><a href=\"#sdfootnote16anc\">16<\/a>User40980 wrote about this on February 26, 2013, but the person did not provide a reference. See https:\/\/softwareengineering.stackexchange.com\/questions\/188455\/why-do-programming-languages-especially-c-use-curly-braces-and-not-square-ones<\/div>\n<\/div>\n","protected":false},"author":2276,"menu_order":13,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":["fredstrickland"],"pb_section_license":""},"chapter-type":[],"contributor":[66],"license":[],"class_list":["post-1393","chapter","type-chapter","status-publish","hentry","contributor-fredstrickland"],"part":3,"_links":{"self":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapters\/1393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/wp\/v2\/users\/2276"}],"version-history":[{"count":3,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapters\/1393\/revisions"}],"predecessor-version":[{"id":1396,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapters\/1393\/revisions\/1396"}],"part":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapters\/1393\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/wp\/v2\/media?parent=1393"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/pressbooks\/v2\/chapter-type?post=1393"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/wp\/v2\/contributor?post=1393"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/pressbooks.bccampus.ca\/nelson\/wp-json\/wp\/v2\/license?post=1393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}