Hướng dẫn học Microsoft SQL Server 2008 part 20 ppsx

10 278 0
Hướng dẫn học Microsoft SQL Server 2008 part 20 ppsx

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

Thông tin tài liệu

Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 152 Part I Laying the Foundation $s = new-object (’Microsoft.SqlServer.Management.Smo.Server’) ‘SQLTBWS\INST01’ $bkdir = $s.Settings.BackupDirectory $dbs = $s.Databases $dbs | foreach-object { $db = $_ if ($db.IsSystemObject -eq $False -and $db.IsMirroringEnabled -eq $False) { $dbname = $db.Name $dt = get-date -format yyyyMMddHHmmss $dbbk = new-object (’Microsoft.SqlServer.Management.Smo.Backup’) $dbbk.Action = ‘Database’ $dbbk.BackupSetDescription = "Full backup of " + $dbname $dbbk.BackupSetName = $dbname + " Backup" $dbbk.Database = $dbname $dbbk.MediaDescription = "Disk" $dbbk.Devices.AddDevice($bkdir + "\" + $dbname + "_db_" + $dt + ".bak", ‘File’) $dbbk.SqlBackup($s) # Simple Recovery Model has a Value Property of 3 if ($db.recoverymodel.value__ -ne 3) { $dt = get-date -format yyyyMMddHHmmss $dbtrn = new-object (’Microsoft.SqlServer.Management.Smo.Backup’) $dbtrn.Action = ‘Log’ $dbtrn.BackupSetDescription = "Trans Log backup of " + $dbname $dbtrn.BackupSetName = $dbname + " Backup" $dbtrn.Database = $dbname $dbtrn.MediaDescription = "Disk" $dbtrn.Devices.AddDevice($bkdir + "\" + $dbname + "_tlog_" + $dt + ".trn", ‘File’) $dbtrn.SqlBackup($s) } } } While the best method for creating and modifying tables in SQL Server is to use Transact-SQL scripts, in some cases embedding this activity in application code is beneficial. Remote installation of application software is one good example. Take a look at the objects, shown in Figure 7-4, used in creating tables. As shown in Figure 7-4, the database has a Tables collection, which holds Table objects. Each Table object has a Columns collection, which holds Column objects. Listing 7-6 shows the complete script to define our tables, indexes, and foreign keys. Define the Table object first, and then create the Column objects, set their properties, and add the Column objects to the table’s Columns collection. 152 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 153 Scripting with PowerShell 7 FIGURE 7-4 The SMO Database Table, Index, and Foreign Key objects Database Tables Table Columns Column Name DataType Identity IdentitySeed IdentityIncrement Nullable Create Alter Indexes Index Name IndexKeyType IndexedColumns IndexedColumn Name ForeignKeys ForeignKey Name Columns ForeignKeyColumn ReferencedTable ReferencedTableSchema Create Alter 153 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 154 Part I Laying the Foundation After the table and columns have been defined, the next step is to define an index and set its IndexKeyType property to indicate the index is a primary key. (Without a primary key, a foreign key to the table can’t be defined.) The last step is to create a clustered index on one table to improve query performance against that table. Finally, the Create method is used to create the table. In our example scenario, AdventureWorks has acquired another company. Their employees are being merged into the AdventureWorks HR application, but key data items need to be maintained for the short term based on their old company’s records. To this end, two new tables are required. The first table, called AcquisitionCompany, will hold the name and date the acquisition occurred, plus an identity-based key called CompanyID. (In this scenario, AdventureWorks will do this again.) The second table, called AcquisitionEmployee, contains the employee’s original employee ID, original start date, number of hours available for time off this year, plus a column that indicates whether this employee earned a kind of reward called a Star Employee. The AcquisitionEmployee table also needs a column to reference the AcquisitionCompany table. These tables will be created in the HumanResources schema. After creating the tables, the next step is to add foreign key references from AcquisitionEmployee to both the AcquisitionCompany and the existing Employee tables. Because AdventureWorks man- agement likes the Star Employee idea, that column will be added to the existing Employee table but will be kept separate from the StarEmployee column in the AcquisitionEmployee table because the criteria are different. Once the tables are created, the required foreign keys to the AcquisitionEmployee table can be added by creating a ForeignKey object, defining the ForeignKey columns, and adding them to the ForeignKey object and defining the referenced table and schema. LISTING 7-6 CreateTable.ps1 #createtable.ps1 #Creates the Acquisition tables in the AdventureWorks database [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null $s = new-object ("Microsoft.SqlServer.Management.Smo.Server") "MyServer\MyInstance" #Reference the AdventureWorks database. $db = $s.Databases["AdventureWorks"] #Create reusable datatype objects $dtint = [Microsoft.SqlServer.Management.Smo.Datatype]::Int $dtvchar100 = [Microsoft.SqlServer.Management.Smo.Datatype]::NVarChar(100) $dtdatetm = [Microsoft.SqlServer.Management.Smo.Datatype]::DateTime $dtbit = [Microsoft.SqlServer.Management.Smo.Datatype]::Bit #Create the table in the HumanResources schema $tbcomp = new-object ("Microsoft.SqlServer.Management.Smo.Table") ($db, "AcquisitionCompany", "HumanResources") 154 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 155 Scripting with PowerShell 7 #Create the CompanyID column $colcoid = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbcomp, "CompanyID", $dtint) $colcoid.Identity = $true $colcoid.IdentitySeed = 1 $colcoid.IdentityIncrement = 1 $tbcomp.Columns.Add($colcoid) #Create the CompanyName column $colconame = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbcomp, "CompanyName", $dtvchar100) $colconame.Nullable = $false $tbcomp.Columns.Add($colconame) #Create the AcquisitionDate column $colacqdate = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbcomp, "AcquisitionDate", $dtdatetm) $colacqdate.Nullable = $false $tbcomp.Columns.Add($colacqdate) #Create the Primary Key $idxpkcompany = new-object ("Microsoft.SqlServer.Management.Smo.Index") ($tbcomp, "PK_AcquisitionCompany") $idxpkcompany.IndexKeyType = "DriPrimaryKey" $idxpkcompany.IsClustered = $true $idxpkcompanycol = new-object ("Microsoft.SqlServer.Management.Smo.IndexedColumn") ($idxpkcompany, "CompanyID") $idxpkcompany.IndexedColumns.Add($idxpkcompanycol) $tbcomp.Indexes.Add($idxpkcompany) #Create the table $tbcomp.Create() #Create the table in the HumanResources schema $tbemp = new-object ("Microsoft.SqlServer.Management.Smo.Table") ($db, "AcquisitionEmployee", "HumanResources") #Create the EmployeeID column $colempiddt = [Microsoft.SqlServer.Management.Smo.Datatype]::Int $colempid = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "EmployeeID", $dtint) $colempid.Nullable = $false $tbemp.Columns.Add($colempid) #Create the CompanyID foreign key column $colempcolid = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "CompanyID", $dtint) $colempcolid.Nullable = $false 155 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 156 Part I Laying the Foundation $tbemp.Columns.Add($colempcolid) #Create the OriginalEmployeeID column $colorigempid = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "OriginalEmployeeID", $dtint) $colorigempid.Nullable = $false $tbemp.Columns.Add($colorigempid) #Create the OriginalHireDate column $colemporigdate = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "OriginalHireDate", $dtdatetm) $colemporigdate.Nullable = $false $tbemp.Columns.Add($colemporigdate) #Create the TimeOffHours column $colemptoh = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "TimeOffHours", $dtint) $colemptoh.Nullable = $false $tbemp.Columns.Add($colemptoh) #Create the StarEmployee column $colempstar = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbemp, "StarEmployee", $dtbit) $colempstar.Nullable = $false $tbemp.Columns.Add($colempstar) #Create the Primary Key $idxpkemp = new-object ("Microsoft.SqlServer.Management.Smo.Index") ($tbemp, "PK_AcquisitionEmployee") $idxpkemp.IndexKeyType = "DriPrimaryKey" $idxpkempcol = new-object("Microsoft.SqlServer.Management.Smo.IndexedColumn") ($idxpkemp, "EmployeeID") $idxpkemp.IndexedColumns.Add($idxpkempcol) $tbemp.Indexes.Add($idxpkemp) #Create the Clustered Index $idxciemp = new-object ("Microsoft.SqlServer.Management.Smo.Index") ($tbemp, "CI_AcquisitionEmployee") $idxciemp.IndexKeyType = "DriUniqueKey" $idxciemp.IsClustered = $true $idxciempcol = new-object("Microsoft.SqlServer.Management.Smo.IndexedColumn") ($idxciemp, "OriginalEmployeeID") $idxciemp.IndexedColumns.Add($idxciempcol) $tbemp.Indexes.Add($idxciemp) #Create the table $tbemp.Create() 156 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 157 Scripting with PowerShell 7 #Connect to the HumanResources.Employee table $tbhremp = $db.Tables | where {$_.Name -eq ‘Employee’ -and $_.Schema -eq ‘HumanResources’} #Add the StarEmployee column to the HumanResources.Employee table $colhrempstar = new-object ("Microsoft.SqlServer.Management.Smo.Column") ($tbhremp, "StarEmployee", $dtbit) $colhrempstar.Nullable = $true $tbhremp.Columns.Add($colhrempstar) #Alter the HumanResources.Employee table $tbhremp.Alter() #Define the HumanResources.Employee foreign key $fkemp = new-object ("Microsoft.SqlServer.Management.Smo.ForeignKey") ($tbemp, "FK_AcqEmployee_HREmployee") $fkcolemp = new-object("Microsoft.SqlServer.Management.Smo.ForeignKeyColumn") ($fkemp, "EmployeeID", "EmployeeID") $fkemp.Columns.Add($fkcolemp) $fkemp.ReferencedTable = "Employee" $fkemp.ReferencedTableSchema = "HumanResources" $fkemp.Create() #Define the HumanResources.AcquisitionCompany foreign key $fkco = new-object ("Microsoft.SqlServer.Management.Smo.ForeignKey") ($tbemp, "FK_AcqEmployee_AcqCompany") $fkcoid = new-object ("Microsoft.SqlServer.Management.Smo.ForeignKeyColumn") ($fkco, "CompanyID", "CompanyID") $fkco.Columns.Add($fkcoid) $fkco.ReferencedTable = "AcquisitionCompany" $fkco.ReferencedTableSchema = "HumanResources" $fkco.Create() One of the great improvements in SMO over its predecessor, DMO, is in the area of scripting. With SMO, Transact-SQL scripts can be created from objects even if they don’t yet exist. Almost all mainte- nance dialogs in SQL Server Management Studio include a button that enables a script to be generated from the changes made in that dialog. That way, the script can be executed, rather than making the changes from the dialog, and the script can be saved for future use. Another useful feature of scripting existing objects is the capability to generate scripts of all database objects for documentation or to put into source code control. This enables administrators to rebuild a database in the form it existed at the time the script was created, should some problem arise requiring that effort. At any time while creating or working with objects in SMO, those objects can be scripted for archival or later use (see Figure 7-5). 157 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 158 Part I Laying the Foundation FIGURE 7-5 SMO scripting objects Scripter ScriptDrops WithDependencies FileName IncludeHeaders AppendToFile ToFileOnly Script ClusteredIndexes Indexes DriAll Options Server The Server property enables the Scripter object to connect to the server. The remaining properties needing to be set are in the Scripter Options collection. The ScriptDrops property specifies whether the script will consist of drops for the objects or creates for the objects. If this property is set to True, the script will contain a DROP statement for each object (within an IF condition to ensure that it exists), but a False value causes the scripter to generate the CREATE statement for each object. The WithDependencies property, if true, causes the objects to be scripted in an order that respects the dependency of one scripted object on another. The FileName property contains the full path of the resultant script file. The IncludeHeaders property, when True, includes a comment indicating the name of the object and when the object was created in the script. The AppendToFile property appends the script to the end of an existing file if True, and overwrites the file if False. By default, the scripting process sends the results to the console, so setting the ToFileOnly property to True causes the scripter to send the script only to the file specified. Setting the ClusteredIndexes property to True causes the clustered index for a table to be included in the script, and setting the Indexes property to True causes the non-clustered indexes to be included 158 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 159 Scripting with PowerShell 7 in the script. The DriAll property, when set to True, causes all objects with enforced declarative referential integrity to be included in the script. The objects to be scripted need to be added to an array of type SqlSmoObject. Once the array has been populated with all the objects to be scripted, invoke the Script method and the script will be created. Listing 7-7 shows the script to create a T-SQL script of all tables in the AdventureWorks database. LISTING 7-7 Scripting.ps1 #Script all the table objects in the AdventureWorks database [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null $s = new-object (’Microsoft.SqlServer.Management.Smo.Server’) ‘MyServer\MyInstance’ $db = $s.Databases[’AdventureWorks’] $scrp = new-object (’Microsoft.SqlServer.Management.Smo.Scripter’) ($s) $scrp.Options.ScriptDrops = $False $scrp.Options.WithDependencies = $True $scrp.Options.FileName = ‘c:\dbscript.sql’ $scrp.Options.IncludeHeaders = $True $scrp.Options.AppendToFile = $True $scrp.Options.ToFileOnly = $True $scrp.Options.ClusteredIndexes = $True $scrp.Options.DriAll = $True $scrp.Options.Indexes = $True $scrp.Script($db.Tables) Data-based tasks In the section on ADO.NET you saw an example that returned the results from a query to the user, using a DataAdapter object to fill a DataSet. This method is fine as long as there’s enough memory to hold all the results of the query. If the result set is very large, though, it is better to use the ExecuteReader method of the SqlCommand object. The following example, shown in Listing 7-8, uses the AdventureWorks2008 database to extract department employee information by DepartmentID, and creates a separate physical file for each department. The files will be text files with commas separating the columns returned. This format is easily understood by most programs that import data. The ExecuteReader method returns a DataReader object, and the columns must be retrieved from the object using the GetValue method of the DataReader, supplying the column index number to GetValue. The script sets a local variable for each of the columns retrieved for each row. Once those have been set, the script tests whether the DepartmentID value has changed. If so, a ‘‘header’’ row is created in a string variable ($r) and written to a file with the name of the department Name valueanda.txt extension. Once the header has been written, the data row just read is written to the file. 159 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 160 Part I Laying the Foundation LISTING 7-8 dept_birthdays.ps1 #dept_birthdays.ps1 #This script will extract information for employees by Department #and write the results into text files named with the department name. $cn = new-object System.Data.SqlClient.SqlConnection("Data Source=MyServer\ MyInstance;Integrated Security=SSPI;Initial Catalog=AdventureWorks2008"); $cn.Open() $q = "SELECT d.[DepartmentID]" $q = $q + " ,d.[Name]" $q = $q + " ,p.[FirstName]" $q = $q + " ,p.[LastName]" $q = $q + " ,e.[JobTitle]" $q = $q + " ,e.[BirthDate]" $q = $q + " ,e.[SalariedFlag]" $q = $q + " FROM [AdventureWorks2008].[Person].[Person] p" $q = $q + " INNER JOIN [AdventureWorks2008].[HumanResources].[Employee] e" $q = $q + " ON p.[BusinessEntityID] = e.[BusinessEntityID]" $q = $q + " INNER JOIN [AdventureWorks2008] .[HumanResources].[EmployeeDepartmentHistory] dh" $q = $q + " ON p.[BusinessEntityID] = dh.[BusinessEntityID]" $q = $q + " INNER JOIN [AdventureWorks2008].[HumanResources].[Department] d" $q = $q + " ON dh.[DepartmentID] = d. [DepartmentID]" $q = $q + " WHERE p.[PersonType] = ‘EM’" $q = $q + " AND dh.[EndDate] IS NULL" $q = $q + " ORDER BY d.DepartmentID, p.LastName" $cmd = new-object "System.Data.SqlClient.SqlCommand" ($q, $cn) $cmd.CommandTimeout = 0 $dr = $cmd.ExecuteReader() $did = "" while ($dr.Read()) { $DepartmentID = $dr.GetValue(0) $Name = $dr.GetValue(1) $FirstName = $dr.GetValue(2) $LastName = $dr.GetValue(3) $JobTitle = $dr.GetValue(4) $BirthDate = $dr.GetValue(5) $SalariedFlag = $dr.GetValue(6) if ($DepartmentID -ne $did) { $r = """DepartmentID"",""Name"",""FirstName"",""LastName" $r = $r + """,""JobTitle"",""BirthDate"",""SalariedFlag""" $f = $Name + ".txt" 160 www.getcoolebook.com Nielsen c07.tex V4 - 07/23/2009 9:03pm Page 161 Scripting with PowerShell 7 $r | out-file $f -append -encoding ASCII $did = $DepartmentID } $r = """" + $DepartmentID + """,""" + $Name + """,""" $r = $r + $FirstName + """,""" + $LastName + """,""" $r = $r + $JobTitle + """,""" + $BirthDate + """,""" + $SalariedFlag + """" $f = $Name + ".txt" $r | out-file $f -append -encoding ASCII } $dr.Close() $cn.Close() SQL Server PowerShell Extensions With the release of SQL Server 2008, Microsoft incorporated new extensions to PowerShell specifically for working with SQL Server. The first of these is a mini-shell preconfigured with the required DLLs loaded and the providers available for use. All of the examples shown previously in this chapter run fine in standard PowerShell 1.0. The rest of the chapter focuses on the new features created for SQL Server 2008. SQLPS.exe SQL Server 2008 incorporates PowerShell into its management toolset. As part of Microsoft’s Common Engineering Criteria, all server tools now incorporate PowerShell to enable administrators to script tasks easily. Snap-ins to PowerShell are fairly easily achieved by writing what’s called a provider, which is a set of tools designed to allow easy access to data. In the case of SQL Server, the provider creates a PowerShell drive that directly connects with SQL Server, and a set of cmdlets to communicate with SQL Server from PowerShell. Using the PowerShell drive, you can browse SQL Server as though it were a file system. The cmdlets enable you to run Transact-SQL commands, evaluate policies, and convert names between the characters that SQL Server supports and the more limited set of characters that PowerShell supports. Microsoft created a special version of PowerShell (1.0) called sqlps.exe that includes the provider and preloads all of the DLLs that the provider requires, including the DLLs for SMO. Another difference between standard PowerShell and sqlps.exe is that the execution policy of PowerShell in sqlps.exe is set to RemoteSigned. This means that as soon as SQL Server 2008 is installed, sqlps.exe is ready to run scripts (on the local system, at least). The good news, considering that PowerShell 2.0 is out (or will be soon), is that the SQL Server provider can be easily loaded into standard PowerShell. Michiel Wories developed the SQL Server provider, and in his blog post at http://blogs.msdn.com/mwories/archive/2008/06/14/SQL2008 5F00 Powershell.aspx he provides the script that loads it into PowerShell. 161 www.getcoolebook.com . features created for SQL Server 200 8. SQLPS.exe SQL Server 200 8 incorporates PowerShell into its management toolset. As part of Microsoft s Common Engineering Criteria, all server tools now incorporate. datatype objects $dtint = [Microsoft. SqlServer.Management.Smo.Datatype]::Int $dtvchar100 = [Microsoft. SqlServer.Management.Smo.Datatype]::NVarChar(100) $dtdatetm = [Microsoft. SqlServer.Management.Smo.Datatype]::DateTime $dtbit. database [System.Reflection.Assembly]::LoadWithPartialName(" ;Microsoft. SqlServer.SMO") | out-null $s = new-object ( Microsoft. SqlServer.Management.Smo .Server ) ‘MyServerMyInstance’ $db = $s.Databases[’AdventureWorks’] $scrp

Ngày đăng: 04/07/2014, 09:20

Tài liệu cùng người dùng

Tài liệu liên quan