Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
547,37 KB
Nội dung
} catch (Exception ex) { // Process exception. Console.WriteLine(ex.Message); } Finally, the code used to navigate the relationship is re-written using the new, strongly typed methods and properties in the classes generated by the data source: foreach (FolktaleDBDataSet.ClassificationRow classificationRow in ds.Classification) { Console.WriteLine(“Classification: {0}“, classificationRow.Classification); FolktaleDBDataSet.StoryRow[] childRows = classificationRow.GetStoryRows(); if (childRows.Length > 0) { foreach (FolktaleDBDataSet.StoryRow storyRow in childRows) { Console.WriteLine(“Story: {0}“, storyRow.Name); } } else { Console.WriteLine(“No stories.”); } Console.WriteLine(); } As you can see, using code in this way is much easier. Perhaps the only disadvantage is that each data adapter opens and closes a connection independently. However, that’s something that you can cus- tomize if you want — the data adapters have a Connection property that you can use to set your own connection to use, which you could open and close manually to prevent the extra processing. To be hon- est, however, unless you are using a lot of data adapters, this overhead will be minimal because connec- tion pooling will be used, and the improved code simplicity is more than worth the cost in most applications. Summary In this chapter you have extended your knowledge of ADO.NET to the point where you can use it in your applications without data binding to controls. You have learned to perform basic operations such as making connections and executing commands as well as using data readers to read data, and data adapters and DataSet objects to obtain disconnected data for reading and modification. You’ve also seen how to use powerful typed DataSet classes to make your code simpler and save you a lot of work. Specifically, you have looked at: ❑ How to make database connections using the SqlConnection class, and how to store connec- tion strings in web.config and app.config configuration files. You learned why the state of 239 Accessing Databases Programmatically 44063c06.qxd:WroxBeg 9/12/06 3:52 PM Page 239 the connection (open or closed) is important, and how connection pooling can improve applica- tion performance. ❑ How to create execute commands of various types using the SqlCommand class, how to execute SQL queries and stored procedures, and how to use parameters to pass values to commands. ❑ How to defend against SQL injection attacks, which required you to think more about exactly what SQL command you send to a database and how that command will be interpreted. You saw how parameters set by users should be checked before you use them, especially if you use user input to generate SQL queries manually. ❑ How to read schema, row, and other data using data readers. You used the SqlDataReader class to read data sequentially, and learned that this quick, efficient access is often all you need to use in your applications. ❑ How to configure data adapters. You saw how SqlDataAdapter objects require commands to interact with a database, although it is possible to generate those commands automatically using SqlCommandBuilder. You also saw how you can use data adapters to read schema data, and how to customize data adapter behavior by using table mappings. ❑ How to use DataSet objects to store and manipulate DataTable objects. You used data adapters to exchange data between a DataSet instance and a database, and you defined rela- tionships between tables in a DataSet. ❑ How to create, use, and customize typed DataSet classes. In the next chapter you learn to use additional database features such as views and procedures to streamline your database applications, and how to use custom code in place of DataSet objects to facili- tate database access. Exercises 1. When you dispose of a connection it is discarded and cannot be used again. True or false? Why? 2. In what ways could you obtain schema information from a database table? 3. Which of the following ADO.NET classes would you use to read and display data in the most efficient way possible? a. SqlCommand b. DataSet c. SqlDataReader d. SqlConnection e. SqlDataAdapter f. DataTable 4. If you had a table with a column called ThisIsAnExtremelyLongAndSillyColumnName, how would you put data from this column into a DataTable with a column name of SensibleName when using a data adapter? 240 Chapter 6 44063c06.qxd:WroxBeg 9/12/06 3:52 PM Page 240 7 Views and Stored Procedures Now that you’ve covered the basics of database access, using both data binding and programmatic techniques, it’s time to delve deeper into getting the best out of databases. So far all of the access you’ve performed has been using simple select statements taking data from single database tables. In many circumstances that’s all you need, and you can do a lot with the data you obtain by manip- ulating it in your code. However, by changing the way you obtain data from a database, you can go a lot further and reduce the amount of work that you have to do in your applications to use the data you want. Views and stored procedures help you do this. You can use views to work with data combined from multiple tables, instead of using data from those tables individually and then having to navi- gate relationships yourself. Of course you can use select statements with joins to combine data when you fetch it, but by defining views you can improve performance since the DBMS is capable of optimizing their behavior. There can also be security bonuses because you can restrict data access to views rather than underlying table data. Stored procedures are another way in which you can improve the functionality of your applica- tions. Like views, stored procedures can provide you with alternative ways of accessing data, but they also enable you to do a lot more and they assemble result sets in complex ways to suit your needs. Again, this is something that you could do using C# code in your application — but stored procedures can encapsulate algorithms and generally make your life easier. They can perform multiple tasks in one go, make use of conditional and looping logic, and, like views, their behavior is optimized by the DBMS. To summarize, in this chapter you learn: ❑ How to create and use database views ❑ How to create and use stored procedures 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 241 Database Views A view, as you learned in Chapter 1, is a stored SQL query that you can access as if it were a table. This means that you can use simpler syntax to access your data, as you will see in this section. You were introduced to the subject of performing joins between tables when executing select statements in Chapter 1. For example, you can obtain data from ProductCategory and Product tables with a one- to-many relationship defined by a ProductCategoryId column as follows: SELECT * FROM Product INNER JOIN ProductCategory ON Product.ProductCategoryId = ProductCategory.ProductCategoryId This acquires column data from both tables, with a result set consisting of one row for each row in the Product table, with additional data from the ProductCategory table being included in each row. That means data may well be duplicated in the result set because data from rows in the ProductCategory table may be reproduced once or many times (or not at all). However, while the result includes this redundancy, it does mean that you have easy access to data from the parent table ProductCategory without having to navigate through relationships between these tables in your code. Queries such as this would be an ideal use for a view, called something like Product_with_Category. You could read data from that view as if it were a table containing all the linked data, and that can sim- plify code in your application that displays this information. Alternatively, you could use a view to list rows in the ProductCategory table along with the number of rows in the Product table that are child rows, like this: SELECT COUNT(ProductId) AS ProductCount, ProductCategory.ProductCategoryId, ProductCategory.CategoryName FROM ProductCategory INNER JOIN Product ON ProductCategory.ProductCategoryId = Product.ProductCategoryId GROUP BY ProductCategory.ProductCategoryId, ProductCategory.CategoryName This uses the COUNT() aggregate function to count rows according to the grouping specification in the GROUP BY clause of the statement. A view containing this query might be called something like Category_ProductCount. These queries can be executed directly from your code, but once a view has been defined, you can use simpler syntax. For example: SELECT * FROM Category_ProductCount You can also reference views from other views, making even more complicated result sets that are still just as easy to access from your code. Another situation in which views can be useful is where you want to protect data in underlying tables. Because you can apply different access rules to tables and views, you could, for instance, allow users to access views but prevent them from directly accessing data in the tables that store the data used in the view. In the following sections, you look at creating and using views, and examine considerations for updat- ing data through views. 242 Chapter 7 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 242 Views and Stored Procedures 243 Creating Views You can create views in two ways: ❑ Graphically, using Visual C# Express, SQL Server Management Studio Express, or another visual tool ❑ Using SQL script You can even create views on-the-fly from applications if you need to. Many advanced users prefer to create views from script because it offers more flexibility. It also enables you to copy views from one location to another with ease — you can generate the script required to create a table at its source location, and then execute the script against a remote server. Assuming all the other database objects required by the view exist (tables, functions, stored procedures, and so on), the view will be recreated exactly as it was in its original location. Let’s first look at graphically creating views, and then move on to the script required to achieve the same ends. Graphical View Creation The graphical tool used to create views in Visual C# Express is the same as the one used in SQL Server Management Express, so in this section most techniques apply to both. About the only real difference is how you open the tool in the first place. In Visual C# Express you have two options, both of which become available when you are looking at a database connection in the Database Explorer window. With a project open, select an open database connection and you can add a view using the Data ➪ Add New ➪ View menu option. Alternatively, if you haven’t got a project open or if you just prefer, you can expand the database, right-click the Views folder, and choose Add New View as shown in Figure 7-1. Figure 7-1: Creating a view In SQL Server Management Studio Express, you can create a view in an existing database by right-click- ing the Views folder in a database and selecting New View, or though the Summary window that you can see when the Views folder is selected. (To add a new view in the Summary window, right-click in the Summary window and select New View.) Whichever method you choose to add a view, the main display changes to the view creation tool. In actual fact, in Visual C# Express this tool is the general tool used to design queries, and as such is 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 243 referred to as the Query Designer tool. Because views consist primarily of a query, however, the usage is the same. When the tool opens, you are immediately prompted with the Add Table dialog box, as shown in Figure 7-2. Figure 7-2: Add Tables dialog box From this tool you can add references to tables, views, functions, and synonyms (synonyms are alterna- tive names for other database objects), so the name of the dialog box is slightly misleading. Any database objects you select here are added to the FROM clause of the query that defines your new view. You don’t have to configure your query this way, as you will see shortly, but it is a helpful starting point. As you add objects from the Add Table dialog box, relationships between them are automatically detected from foreign key relationships and used to define the nature of the table joins to add to your query. For example, adding the Story, CharacterStory, and Character tables from the FolktaleDB database adds the following FROM clause: FROM dbo.Story INNER JOIN dbo.CharacterStory ON dbo.Story.StoryId = dbo.CharacterStory.StoryId INNER JOIN dbo.Character ON dbo.CharacterStory.CharacterId = dbo.Character.CharacterId That may not be the exact relationship you want to add, but it is easy enough to change, as you will see. Once you have added database objects using this query (or not added them, as the case may be), they and any relationships between them are visible at the top of the View Editor display. The query gener- ated for the view can be seen below it. Figure 7-3 shows a full display. The View Editor is divided into the following four sections (from top to bottom): ❑ Diagram pane: Shows the tables, views, and other objects that return tabular data in your query. It also shows the relationships between those objects and the fields output by the query, as well as additional information such as fields used for grouping, and primary key fields in bold. ❑ Criteria pane: Shows the specification of your query in tabular form when you modify the query with output columns, grouping columns, filtering information, sorting information, and so on. ❑ SQL pane: Displays the text of the SQL query you have created. ❑ Results pane: Displays the results of your testing your query. 244 Chapter 7 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 244 Views and Stored Procedures 245 Figure 7-3: View Editor The top three panes all enable you to edit the query. You can do so graphically in the diagram pane, schematically in the criteria pane, or using SQL in the SQL pane. Any modifications you make in any of these panes are automatically applied to all three panes — so, for example, if you add a table in the SQL pane, it appears in the diagram pane. There are some circumstances when the diagram pane does not display information from your query, such as when you use the UNION keyword to join two result sets together. In that case the diagram pane is unavailable. In both Visual C# Express and SQL Server Management Studio Express an additional toolbar — the View Builder toolbar (see Figure 7-4) — appears when you are building a view. In a slightly modified form, that toolbar is also used when you add other types of SQL objects such as queries. Figure 7-4: View Builder toolbar Here’s a brief description of the View Builder toolbar buttons’ functions: ❑ Toggles diagram pane open/closed ❑ Toggles criteria pane open/closed ❑ Toggles SQL pane open/closed ❑ Toggles results pane open/closed 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 245 These first four buttons are shown active in Figure 7-4, as reflected in the display shown in Figure 7-3. ❑ Executes your query and shows you the results ❑ Verifies the syntax of your SQL query without executing it (useful when the query modifies data or takes a long time to execute; not as useful in views) ❑ Toggles the edit mode for the diagram and criteria panes such that columns are added as GROUP BY columns (more on this shortly) ❑ Click to add objects to your query through the Add Table dialog box ❑ Click to add objects to your query via a derived table for you to edit (more details on this shortly) In the following sections, you explore each of the panes in the View Builder in more detail. Using the Diagram Pane The diagram pane displays the objects that make up your query. Each table is displayed as a window, which you can move around or resize as you see fit without affecting the query. This can help you to understand the query visually. The icon in the top left of the object’s window reflects the type of object it is. (All of the objects in Figure 7-3 are tables, and they all have the same icon.) Hover the mouse pointer over any of the objects in the diagram pane and a ToolTip displays additional information — the name of a table, the name and data type of a column, or the specification of a join, for example. When you select an item in this pane, its properties display in the Properties window. For instance, you can see additional data type information for columns, although you can’t edit that information through the display. The most basic use of the diagram pane is to select which columns from the available objects will be included in your view. Each column has a checkbox to its left; select the checkbox for each column you want to include in the query, or check the box for * (all columns) to select all the columns in the object. You can also add columns to the GROUP BY clause of your query in the diagram pane. To do so, click the Add Group By button in the View Builder toolbar, and then select columns the same way as before. To go back to adding columns in the normal way, click the Add Group By button again to unselect it. If you add a column as a GROUP BY column, an icon appears to the right of the column name; the icon looks the same as the Add Group By button in the toolbar. Add an ORDER BY clause to a query by right-clicking a column and selecting either Sort Ascending or Sort Descending. You can clear sort specifications for columns by right-clicking and selecting the appro- priate option. You can also clear filter expressions for columns through the right-click menu, although you cannot add filter expressions using the diagram pane. If a sort or filter specification is used for a col- umn, an icon is displayed to the right of the column name. It is possible, depending on your query, for a single column to have icons for sort, filter, and group-by specifications. You can also modify the joins between objects in the diagram pane, although again you cannot add new joins through this pane. Right-click a relationship to delete it; change it to a right, left, or full outer join by selecting combinations of the Select All Rows From options; and view and edit the join using the Join Condition And Type property. This property also has an editor associated with it, which you can open via the Properties window. The Join dialog box is shown in Figure 7-5. 246 Chapter 7 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 246 Views and Stored Procedures 247 Figure 7-5: Join dialog The Join dialog box also enables you to select the type of join by including all rows from one or both objects in the join, and you can change the operator used in the join if you want. Additionally, you can use the diagram pane to add a derived table. A derived table is an intermediate, dynamic table that you can use in your query. In effect, using a derived table is like having a view that references another view, but with the referenced view being defined as part of the referencing view. This additional step enables more complex result processing, although it can make things more confusing. To add a derived table, use the toolbar icon or right-click in the design pane and select Add New Derived Table. Either way, once you have added a derived table you cannot edit it further using the design pane, although you can see and select its columns once they are defined. You can define derived tables only in the SQL pane. In some circumstances you may be able to design queries completely using the diagram pane. More often than not, however, you need to use one of the other panes to complete your query. Using the Criteria Pane Columns and other items that you add to your query appear in the criteria pane. You can configure your query by entering information in this pane. Specifically, the rows in the criteria pane display the follow- ing information: ❑ Columns selected as output columns from the tables and other objects in the query ❑ Calculated column specifications, including function calls and aggregate functions ❑ Aliases for selected columns, including names for calculated columns ❑ Query sorting specifications ❑ Query filter specifications ❑ Columns used to group data When designing other types of queries in the criteria pane, you can also set other information here, such as new values used in insert and update queries. The layout of the criteria pane consists of a number of rows with columns as follows: ❑ Column: Enter the name of a column from a table or other object in the query, or enter a column specification. If you are entering the name of an existing column, you can use a drop-down 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 247 selector in this column, as shown in Figure 7-6. You can choose all the columns in a table by selecting * for that table, for example dbo.Story.*. (The dbo part of this name refers to the schema for the table as defined in the database.) Figure 7-6: Column selection ❑ Alias: Type the alias to be used for a column, or the name to use for a calculated column. If mul- tiple columns are specified (if * is used, for example), this column is unavailable. ❑ Table: Specifies the table from which the column is to be taken, if appropriate. For some columns, such as where columns in two or more tables in the query have the same name, you can use a drop-down to change the table that the column is taken from. This setting is unavail- able for calculated columns. ❑ Output: Use the checkbox to specify whether the column will be output as part of the query result. It is possible to sort or filter by a column without having it output. ❑ Sort Type: If the column is part of the sorting specification for your query, specify whether it is sorted in Ascending or Descending order. You can select the type by using a drop-down, which also includes the entry Unsorted to clear the column value. ❑ Sort Order: Where multiple columns in the query are used to sort the results, set the order in which sorting is applied by entering numbers in this column. The lower the number, the greater the priority given to sorting by the specified column. For example, you might order people’s names by last name, then first names, so you would have a lower number for the priority of sorting for the last name column. ❑ Filter and Or: If the data column is used to filter data (that is, used in a WHERE or HAVING clause), you can set the criteria here. Where multiple filter expressions exist for a single column, you can use multiple rows in the criteria pane to combine them using the AND operator, or use the Or columns to include multiple criteria combined using OR. You can add additional Or columns by pressing the Tab key in the rightmost one. The order in which data columns and other output data appears in the criteria pane will match the order that columns are returned in the query result, which in the case of views means the order of columns in the view. You can reorder columns in the criteria view by dragging the row for the data column to the position you require using the selection column to the left of the Column column. Of course, you can reorder columns in the SQL pane if you prefer — the reordering is automatically reflected in the criteria pane if you do so. If the query you are designing includes a grouping specification, the behavior of the criteria pane alters slightly. First, the drop-down in the Column column enables you to select COUNT(*) and COUNT_BIG(*) aggregate functions directly — COUNT_BIG(*) works the same way as COUNT(*) but returns a different data type (a bigint instead of an int). An additional column called Group By appears in the criteria 248 Chapter 7 44063c07.qxd:WroxBeg 9/12/06 3:29 PM Page 248 [...]... parse multiple tabular result sets 264 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 265 Views and Stored Procedures In the following example, you create and use a stored procedure in a Windows application Try It Out Stored Procedure Execution 1 Open Visual C# Express and create a new Windows application called Ex0703 - Using Sprocs Save the project in the C:\BegVC #Databases\ Chapter07 directory, with the... remove the Fill button from the form 16 Add a form load event handler and the following code: private void Form1_Load(object sender, EventArgs e) { try { // Get endings and fill dropdrown FolktaleDBDataSetTableAdapters.EndingTableAdapter endingTableAdapter = new FolktaleDBDataSetTableAdapters.EndingTableAdapter(); 266 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 267 Views and Stored Procedures endingTableAdapter.Fill(folktaleDBDataSet.Ending);... its anchor property set to Top, Bottom, Left, or Right From the Data Sources window, drag the GetStoriesByEnding item onto Form1 to create a DataGridView and associated controls 265 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 266 Chapter 7 Figure 7-11: Control positioning 10 Execute the application When it’s running, type the text Sad in the EndingType text box and click Fill to obtain the stories with... methods are executed in C# objects Stored procedures are a lot like views in many ways You can use then to wrap a portion of SQL script in the same way, and the return value of a stored procedure can be a tabular result set just like a view However, additional functionality is available in stored procedures above and beyond what is to be had in views 2 56 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 257 Views... procedure, by specifying the name, data type, and default value for each one Although two parameters may be enough, it’s likely you will be editing the script manually to add more 260 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 261 Views and Stored Procedures Click OK with the default values shown in Figure 7-9, and the script changes as follows: ============================================= Author:... security settings via each owner You can, if you want, include a semicolon and a number for your stored procedure after the name For example: CREATE PROCEDURE dbo.ProcedureName;1 261 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 262 Chapter 7 You can create multiple stored procedures with the same name but using different numbers Those procedures are then considered to be grouped together, and can be deleted... and an output parameter called @ExtendedInfo that returns a result set via a cursor ( @MyIdentifier int = -1, @MySearch varchar(50) = ‘%‘, @ExtendedInfo CURSOR VARYING OUTPUT ) 262 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 263 Views and Stored Procedures You can also apply a few advanced options at the end of the parameter specification for a stored procedure They determine how the stored procedure... Right, Bottom 15 Run the applications and verify that you can view rows from the Story table with data included from the Classification, Ending, and Source tables 16 Close the application and Visual C# Express 252 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 253 Views and Stored Procedures Figure 7-7: Form layout How It Works In this example you created a simple viewing application for data in the FolktaleDB... the solution directory for the previous Try It Out, C:\BegVC #Databases\ Chapter07\ Ex0701 - Using Views, to a new directory, C:\BegVC #Databases\ Chapter07\Ex0702 Updating Views Open the copied solution file and rename the solution and project 254 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 255 Views and Stored Procedures 2 3 Open the DataSet Designer for the FolktaleDBDataSet typed DataSet class Examine... you could alter the database such that the child rows are deleted when the parent row is deleted However, that’s not done in this example 12 Close the application and Visual C# Express 255 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 2 56 Chapter 7 How It Works This exercise modifies the earlier example application to allow data to be modified and updated through the view you created for that application . app.config configuration files. You learned why the state of 239 Accessing Databases Programmatically 44 063 c 06. qxd:WroxBeg 9/12/ 06 3:52 PM Page 239 the connection (open or closed) is important, and. DataTable with a column name of SensibleName when using a data adapter? 240 Chapter 6 44 063 c 06. qxd:WroxBeg 9/12/ 06 3:52 PM Page 240 7 Views and Stored Procedures Now that you’ve covered the basics. the Properties window. The Join dialog box is shown in Figure 7-5. 2 46 Chapter 7 44 063 c07.qxd:WroxBeg 9/12/ 06 3:29 PM Page 2 46 Views and Stored Procedures 247 Figure 7-5: Join dialog The Join dialog