1. Trang chủ
  2. » Công Nghệ Thông Tin

beginning microsofl sql server 2008 programming phần 7 pdf

73 390 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 73
Dung lượng 1,35 MB

Nội dung

You can test the arithmetic overflow easily by putting any large number in — anything bigger than about 13 will work for this example. Testing the 32-level recursion limit takes a little bit more modification to our sproc. This time, we’ll determine the triangular of the number. This is very similar to finding the factorial, except that we use addition rather than multiplication. Therefore, 5 triangular is just 15 (5+4+3+2+1). Let’s create a new sproc to test this one out — it will look just like the factorial sproc with only a few small changes: CREATE PROC spTriangular @ValueIn int, @ValueOut int OUTPUT AS DECLARE @InWorking int; DECLARE @OutWorking int; IF @ValueIn != 1 BEGIN SELECT @InWorking = @ValueIn - 1; EXEC spTriangular @InWorking, @OutWorking OUTPUT; SELECT @ValueOut = @ValueIn + @OutWorking; END ELSE BEGIN SELECT @ValueOut = 1; END RETURN; GO As you can see, there weren’t that many changes to be made. Similarly, we only need to change our sproc call and the PRINT text for our test script: DECLARE @WorkingOut int; DECLARE @WorkingIn int; SELECT @WorkingIn = 5; EXEC spTriangular @WorkingIn, @WorkingOut OUTPUT; PRINT CAST(@WorkingIn AS varchar) + ‘ Triangular is ‘ + CAST(@WorkingOut AS varchar); Running this with an @ValueIn of 5 gets our expected 15: 5 Triangular is 15 However, if you try to run it with an @ValueIn of more than 32, you get an error: Msg 217, Level 16, State 1, Procedure spTriangular, Line 10 Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32). 401 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 401 I’d love to say there’s some great workaround to this, but, unless you can somehow segment your recur- sive calls (run it 32 levels deep, then come all the way back out of the call stack, then run down it again), you’re pretty much out of luck. Just keep in mind that most recursive functions can be rewritten to be a more standard looping construct — which doesn’t have any hard limit. Be sure you can’t use a loop before you force yourself into recursion. Debugging Long ago and far away (SQL Server 2000), the Management Studio had real live debugging tools. They were a little clunky, in the sense that they really only worked around stored procedures (there wasn’t a way to debug just a script, and debugging triggers required you to create a sproc that would fire the trigger), but, with some work-arounds here and there, we had the long-sought-after debugger. SQL Server 2005 came along and removed all debugging functionalityfrom the Management Studio (it was in the product, but you had to use the Visual Studio installation that is part of the Business Intelligence Development Studio in order to get at it — not very handy in any case, but nonexistent if you didn’t install BIDS for some reason). I’m happy to say that debugging is back in the Management Studio, and it’s better than ever! Starting the Debugger Unlike previous versions, the debugger in SQL Server 2008 is pretty easy to find. Much of using the debugger works as it does in VB or C# — probably like most modern debuggers, for that matter. Simply choose the Debug menu (available when a query window is active). You can then choose from options to get things started: Start Debugging (Alt+F5) or Step Into (F11). Let’s do a little bit of setup to show the debugger in action, both in a standard script and in a stored pro- cedure scenario. To do this, we’ll use the script we were just working with in the previous section (to exer- cise the spTriangular stored procedure we also created earlier in the chapter). The script looked like this: DECLARE @WorkingOut int; DECLARE @WorkingIn int = 5; EXEC spTriangular @WorkingIn, @WorkingOut OUTPUT; PRINT CAST(@WorkingIn AS varchar) + ‘ Triangular is ‘ + CAST(@WorkingOut AS varchar);` With this script as the active query window, let’s start a debugging run with the Step Into option (choose it from the Debug menu or simply press F11). Parts of the Debugger Several things are worth noticing when the Debugger window first comes up: ❑ The yellow arrow on the left (Shown in Figure 12-2) indicates the current execution line — this is the next line of code that will be executed if we do a “go” or we start stepping through the code. 402 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 402 ❑ There are icons at the top (see Figure 12-3) to indicate our different options, including: ❑ Continue: This will run to the end of the sproc or the next breakpoint (including a watch condition). ❑ Step Into: This executes the next line of code and stops prior to running the following line of code, regardless of what procedure or function that code is in. If the line of code being executed is calling a sproc or function, then Step Into has the effect of calling that sproc or function, adding it to the call stack, changing the locals window to represent the newly nested sproc rather than the parent, and then stopping at the first line of code in the nested sproc. ❑ Step Over: This executes every line of code required to take us to the next statement that is at the same level in the call stack. If you are not calling another sproc or a UDF, then this command will act just like a Step Into. If, however, you are calling another sproc or a UDF, then a Step Over will take you to the statement immediately following where that sproc or UDF returned its value. ❑ Step Out: This executes every line of code up to the next line of code at the next highest point in the call stack. That is, we will keep running until we reach the same level as whatever code called the level we are currently at. ❑ Stop Debugging: Again, this does what it says — it stops execution immediately. The debugging window does remain open, however. ❑ Toggle Breakpoints and Remove All Breakpoints: In addition, you can set breakpoints by clicking in the left margin of the code window. Breakpoints are points that you set to tell SQL Server to “stop here!” when the code is running in debug mode. This is handy in big sprocs or functions where you don’t want to have to deal with every line — you just want it to run up to a point and stop every time it gets there. Figure 12-2 Figure 12-3 In addition, there is a choice that brings up the Breakpoints window, which is a list of all breakpoints that are currently set (again, handy in larger blocks of code). There are also a few of what we’ll call “sta- tus” windows; let’s go through a few of the more important of these. The Locals Window As I indicated back at the beginning of the book, I’m pretty much assuming that you have experience with some procedural language out there. As such, the Locals window (shown in Figure 12-4 as it 403 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 403 matches with the current statement shown in Figure 12-3) probably isn’t all that new of a concept to you. Simply put it shows you the current value of all the variables that are currently in scope. The list of vari- ables in the Locals window may change (as may their values) as you step into nested sprocs and back out again. Remember — these are only those variables that are in scope as of the next statement to run. In Figure 12-4, we’re at the start of our first run through this sproc, so the value for the @ValueIn param- eter has been set, but all other variables and parameters are not yet set and thus are effectively null. Figure 12-4 Three pieces of information are provided for each variable or parameter: ❑ The name ❑ The current value ❑ The data type However, perhaps the best part to the Locals window is that you can edit the values in each variable. That means it’s a lot easier to change things on the fly to test certain behaviors in your sproc. The Watch Window Here you can set up variables that you want to keep track of regardless of where you currently are in the call stack. You can either manually type in the name of the variable you want to watch, or you can select that variable in code, right click, and then select Add Watch. In Figure 12-5, I’ve added a watch for @ValueOut, but, since we haven’t addressed that variable in code, you can see that no value has been set for it as yet. Figure 12-5 404 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 404 The Call Stack Window The Call Stack window provides a listing of all the sprocs and functions that are currently active in the process that you are running. The handy thing here is that you can see how far in you are when you are running in a nested situation, and you can change between the nesting levels to verify what current vari- able values are at each level. In Figure 12-6, I’ve stepped into the code for spTriangular such that we’re down to it processing the working value of 3. If you’re following along, you can just watch the @ValueIn variable in your Locals window and see how it changes as we step in. Our call stack now has several instances of spTriangular running as we’ve stepped into it (One for 5, one for 4, and now one for 3), as well as providing informa- tion on what statement is next in the current scope. Figure 12-6 The Output Window Much as it sounds, the Output window is the spot where SQL Server prints any output. This includes result sets as well as the return value when your sproc has completed running, but also provides debug information from the process we’re debugging. Some example output from the middle of a debug run is shown in Figure 12-7. Figure 12-7 The Command Window The Command window is probably going to be beyond common use as it is in SQL Server 2008. In short, it allows you something of a command line mode to access debugger commands and other objects. It is, however, cryptic at best and, as of this writing, relatively undocumented. Examples of commands you could issue would be something like: >Debug.StepInto 405 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 405 There are a whole host of commands available to Intellisense, but you’ll find that most of these are not actually available when debugging. Using the Debugger Once It’s Started Now that we have the preliminaries out of the way and the debugger window up, we’re ready to start walking through our code. If you were walking through some of the descriptions before, stop the debug- ger and restart it so we’re in the same place. The first executable line of our sproc is a bit deceptive — it is the DELCARE statement for @WorkingIn. Normally variable declarations are not considered executable, but, in this case, we are initializing the variable as part of the declaration, so the initialization code is seen by the debugger. You should notice that none of our variables has yet been set (the initialization code will be next to run, but has not actually executed yet). Step forward (using the menu choice, the tool tip, or simply press F11) and you should see (via the Locals window) @WorkingIn get initialized to our value of 5 — @WorkingOut is not initialized as part of the declaration. Use the Step Into key one more time. We enter into our first execution of the spTriangular stored procedure and land at the first executable line in the sproc — our IF statement. Since the value of @ValueIn is indeed not equal to 1, we step into the BEGIN END block specified by our IF statement. Specifically, we move to our SELECT statement that initializes the @InWorking param- eter for this particular execution of the procedure. As we’ll see later, if the value of @ValueIn had indeed been one, we would have immediately dropped down to our ELSE statement. Again, step forward one line by pressing F11, or using the Step Into icon or menu choice, until just before you enter the next instance of spTriangular. Pay particular attention to the value of @InWorking in the Locals window. Notice that it changed to the correct value ( @ValueIn is currently 5, so 5–1 is 4) as set by our SELECT statement. Also notice that our Call Stack window has only the current instance of our sproc in it (plus the current statement) — since we haven’t stepped down into our nested versions of the sproc yet, we only see one instance. Now go ahead and step into our next statement. Since this is the execution of a sproc, we’re going to see a number of different things change in the debugger. Notice that it appears that our arrow that indicates the current statement jumped back up to the IF statement. Why? Well, this is a new instance of what is otherwise the same sproc. We can tell this based on our Call Stack window — notice that it now has two instances of our sproc listed. The one at the top (with the yellow arrow) is the current instance, and the one with the red breakpoint dot is a parent instance that is now waiting for something further up in the call stack. Notice also that the @ValueIn parameter has the value of 4 — that is the value we passed in from the outer instance of the sproc. If you want to see the value of variables in the scope of the outer instance of the sproc, just double-click on that instance’s line in the Call Stack window (the one with the green arrow) and you’ll see several things changed in our debugging windows. There are two things to notice here. First, the values of our variables have changed back to those in the scope of the outer (and currently selected) instance of the sproc. Second, the icon for our current execution 406 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 406 line is different. This new green arrow is meant to show that this is the current line in this instance of the sproc, but it is not the current line in the overall call stack. Go back to the current instance by clicking on the top item in the Call Stack window. Then step in three more times. This should bring you to the top line (the IF statement) in our third instance of the sproc. Notice that our call stack has become three deep and that the values of our variables and parameters in the Locals window have changed again. Last, but not least, notice that this time our @ValueIn parame- ter has a value of 3. Repeat this process until the @ValueIn parameter has a value of 1. Step into the code one more time and you’ll see a slight change in behavior. This time, since the value in @ValueIn is equal to 1, we move into the BEGIN END block defined with our ELSE statement. Since we’ve reached the bottom, we’re ready to start going back up the call stack. Use Step Into through the last line of our procedure and you’ll find that our call stack is back to only four levels. Also, notice that our output parameter ( @OutWorking) has been appropriately set. This time, let’s do something different and do a Step Out (Shift+F11). If you’re not paying attention, it will look like absolutely nothing has changed. So, you should now be able to see how the Debugger can be very handy indeed. .NET Assemblies Because of just how wide open a topic assemblies are, as well as their potential to add exceptional complexity to your database, these are largely considered out of scope for this title, save for one thing — letting you know they are there. .NET assemblies can be associated with your system and utilized to provide the power behind truly complex operations. You could, just as an example, use a .NET assembly in a user-defined function to provide data from an external data source (perhaps one that has to be called on the fly, such as a new In this case, to use the old cliché, looks are deceiving. Again, notice the change in the Call Stack window and in the values in the Locals window — we stepped out of what was then the current instance of the sproc and moved up a level in the Call Stack. If we now keep stepping into the code (F11), then our sproc has finished running and we’ll see the final version of our status windows and their respective finishing values. A big word of caution here! If you want to be able to see the truly final val- ues (such as an output parameter being set), make sure that you use the Step Into option to execute the last line of code. If you use an option that executes several lines at once, such as a Go or Step Out, all you will get is the output window without any final variable information. A work-around is to place a break point on the last point at which you expect to per- form a RETURN in the outermost instance of your sproc. That way, you can run in whatever debug mode you want, but still have execution halt in the end so you can inspect your final variables. 407 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 407 feed or stock quote), even though the structure and complex communications required would have ruled out such a function in prior versions. Without going into too much detail on them for now, let’s look at the syntax for adding an assembly to your database: CREATE ASSEMBLY <assembly name> AUTHORIZATION <owner name> FROM <path to assembly> WITH PERMISSION_SET = [SAFE | EXTERNAL_ACCESS | UNSAFE] The CREATE ASSEMBLY part of things works as pretty much all our CREATE statements have — it indi- cates the type of object being created and the object name. Then comes the AUTHORIZATION — this allows you to set a context that the assembly is always to run under. That is, if it has tables it needs to access, how you set the user or rolename in AUTHORIZATION will determine whether it can access those tables or not. After that, we go to the FROM clause. This is essentially the path to your assembly, along with the mani- fest for that assembly. Finally, we have WITH PERMISSION_SET. This has three options: ❑ SAFE: This one is, at the risk of sounding obvious, well . . . safe. It restricts the assembly from accessing anything that is external to SQL Server. Things like files or the network are not avail- able to the assembly. ❑ EXTERNAL_ACCESS: This allows external access, such as to files or the network, but requires that the assembly still run as managed code. ❑ UNSAFE: This one is, at the risk of again sounding obvious, unsafe. It allows your assembly not only to access external system objects, but also to run unmanaged code. .NET assemblies will be discussed extensively in Professional SQL Server 2008 Programming. I cannot stress enough the risks you are taking when running .NET assemblies in anything other than SAFE mode. Even in EXTERNAL_ACCESS mode you are allowing the users of your system to access your network, files, or other external resources in what is essentially an aliased mode — that is, they may be able to get at things that you would rather they not get at, and they will be aliased on your network to what- ever your SQL Server login is while they are making those accesses. Be very, very careful with this stuff. 408 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 408 Summary Wow! That’s a lot to have to take in for one chapter. Still, this is among the most important chapters in the book in terms of being able to function as a developer in SQL Server. Sprocs are the backbone of code in SQL Server. We can create reusable code and get improved perform- ance and flexibility at the same time. We can use a variety of programming constructs that you might be familiar with from other languages, but sprocs aren’t meant for everything. Pros to sprocs include: ❑ Usually better performance ❑ Possible use as a security insulation layer (control how a database is accessed and updated) ❑ Reusable code ❑ Compartmentalization of code (can encapsulate business logic) ❑ Flexible execution depending on dynamics established at runtime Cons to sprocs include: ❑ Not portable across platforms (Oracle, for example, has a completely different kind of imple- mentation of sprocs) ❑ May get locked into the wrong execution plan in some circumstances (actually hurting performance) Sprocs are not the solution to everything, but they are still the cornerstones of SQL Server programming. In the next chapter, we’ll take a look at the sprocs’ very closely related cousin — the UDF. 409 Chapter 12: Stored Procedures 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 409 57012c12.qxd:WroxBeg 11/25/08 6:04 AM Page 410 [...]... created as a function in SQL Server .NET assemblies in SQL Server remain, however, something of an advanced concept, and one I’ll defer to the Professional series title for SQL Server 2008 That said, it’s important to understand that the option is available and consider it as something worth researching in that “Wow, I have no idea how we’re going to do this!” situation 425 570 12c13.qxd:WroxBeg 11/25/08... 67 Adams, Jay jay0@adventure-works.com 301 Adams, Frances frances0@adventure-works.com 305 Adams, Carla carla0@adventure-works.com … … 16901 Adams, Adam adam46@adventure-works.com 16902 Adams, Eric eric 57@ adventure-works.com 16910 Adams, Jackson jackson 47@ adventure-works.com ( 87 row(s) affected) 4 17 570 12c13.qxd:WroxBeg 11/25/08 6: 07 AM Page 418 Chapter 13: User-Defined... 570 12c13.qxd:WroxBeg 11/25/08 6: 07 AM Page 411 13 User-Defined Functions Well, here we are already at one of my favorite topics Long after their introduction, user-defined functions — or UDFs — remain one of the more underutilized and misunderstood objects in SQL Server In short, these were awesome when Microsoft first introduced them in SQL Server 2000, and the addition... using a table as a return value is not hard at all — a table is just like any other SQL Server data type as far as a UDF is concerned To illustrate this, we’ll build a relatively simple one to start: USE AdventureWorks2008 GO CREATE FUNCTION dbo.fnContactList() RETURNS TABLE 416 570 12c13.qxd:WroxBeg 11/25/08 6: 07 AM Page 4 17 Chapter 13: User-Defined Functions AS RETURN (SELECT BusinessEntityID, LastName... papers, and books have been written on this subject Fortunately for us, SQL Server 2008 introduces a new methodology for dealing with hierarchical data The newly introduced features are the hierarchyID data type and a collection of built-in functions to help deal with tree type data structures 418 570 12c13.qxd:WroxBeg 11/25/08 6: 07 AM Page 419 Chapter 13: User-Defined Functions in your relational database... hierarchical functionality that is part of SQL Server 2008, check out the OrganizationNode and OrganizationLevel columns of the HumanResources.Employee table in AdventureWorks2008 To continue our discussion of hierarchical data, we are going to handle hierarchies the way we’ve been forced to for ages — call it the “old school method.” Since AdventureWorks2008 doesn't have an a good example of this... converting the date is included in the function body and the truncated date is returned Note that the preceding version is a SQL Server 2008 compatible version, relying on the coercion into the parameter’s date data type to truncate the time If you wanted to do a truncation like this in SQL Server 2005 (as we did with the query-based example), you would need to use the CONVERT function as we did before For... That’s why the shopkeeper usually keeps a close eye on things and will usually decide who gets to handle things first 433 570 12c14.qxd:WroxBeg 11/25/08 6:12 AM Page 434 Chapter 14: Transactions and Locks The SQL Server lock manager is that shopkeeper When you come into the SQL Server store, the lock manager asks what your intent is — what it is you’re going to be doing If you say “just looking,” and... value FROM table @Var BEGIN TRAN 125 Value in Table 125 125 125 75 UPDATE value, SET value = value — 50 125 125 75 UPDATE value, SET value = value — 100 125 125 (waiting for lock to clear) 75 (Finish, wait for lock to clear, then continue) 125 75 Either: -25 (If there isn’t a IF @Var >=100 END TRAN CHECK constraint enforcing > 0) Or: Error 5 47 (If there is a CHECK) Again, we have a problem Transaction... from $6.50 to $7. 50 per hour, and you want to run an UPDATE on the EmployeePayHistory table to move anyone making less than $7. 50 per hour up to the new minimum wage “No problem,” you say, and you issue the rather simple statement: UPDATE HumanResources.EmployeePayHistory SET HourlyRate = 7. 50 WHERE HourlyRate < 7. 50; ALTER TABLE Employees ADD ckWage CHECK (HourlyRate >= CONSTRAINT 7. 50); GO That was . Eric eric 57@ adventure-works.com 16910 Adams, Jackson jackson 47@ adventure-works.com ( 87 row(s) affected) 4 17 Chapter 13: User-Defined Functions 570 12c13.qxd:WroxBeg 11/25/08 6: 07 AM Page 4 17 To simplify. misunderstood objects in SQL Server. In short, these were awesome when Microsoft first introduced them in SQL Server 2000, and the addition of .NET functionality back in SQL Server 2005 just added. of a debug run is shown in Figure 12 -7. Figure 12 -7 The Command Window The Command window is probably going to be beyond common use as it is in SQL Server 2008. In short, it allows you something

Ngày đăng: 09/08/2014, 14:21

TỪ KHÓA LIÊN QUAN