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

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

10 282 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 355,87 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

FIGURE 7-4The SMO Database Table, Index, and Foreign Key objects Database Tables Table Columns Column Name DataType Identity IdentitySeed IdentityIncrement Nullable Create Alter Indexes

Trang 1

$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 aTablescollection, which holdsTableobjects Each

Tableobject has aColumnscollection, which holdsColumnobjects Listing 7-6 shows the complete

script to define our tables, indexes, and foreign keys

Define theTableobject first, and then create theColumnobjects, set their properties, and add the

Columnobjects to the table’sColumnscollection

Trang 2

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

Trang 3

After the table and columns have been defined, the next step is to define an index and set its

IndexKeyTypeproperty 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, theCreatemethod 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, calledAcquisitionCompany, will hold the name and date the acquisition occurred,

plus an identity-based key calledCompanyID (In this scenario, AdventureWorks will do this again.)

The second table, calledAcquisitionEmployee, 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 TheAcquisitionEmployeetable

also needs a column to reference theAcquisitionCompanytable These tables will be created in the

HumanResourcesschema

After creating the tables, the next step is to add foreign key references fromAcquisitionEmployee

to both theAcquisitionCompanyand the existingEmployeetables Because AdventureWorks

man-agement likes the Star Employee idea, that column will be added to the existingEmployeetable but

will be kept separate from theStarEmployeecolumn in theAcquisitionEmployeetable because

the criteria are different

Once the tables are created, the required foreign keys to theAcquisitionEmployeetable can be

added by creating aForeignKeyobject, defining theForeignKeycolumns, and adding them to the

ForeignKeyobject 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")

Trang 4

#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

Trang 5

#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()

Trang 6

#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)

Trang 7

FIGURE 7-5

SMO scripting objects

Scripter

ScriptDrops WithDependencies FileName IncludeHeaders AppendToFile ToFileOnly

Script

ClusteredIndexes Indexes DriAll

Options Server

TheServerproperty enables theScripterobject to connect to the server The remaining properties

needing to be set are in the Scripter Options collection

TheScriptDropsproperty specifies whether the script will consist of drops for the objects or creates

for the objects If this property is set toTrue, the script will contain aDROPstatement for each object

(within anIFcondition to ensure that it exists), but aFalsevalue causes the scripter to generate the

CREATEstatement for each object TheWithDependenciesproperty, if true, causes the objects to

be scripted in an order that respects the dependency of one scripted object on another TheFileName

property contains the full path of the resultant script file TheIncludeHeadersproperty, whenTrue,

includes a comment indicating the name of the object and when the object was created in the script

TheAppendToFileproperty appends the script to the end of an existing file if True, and overwrites

the file ifFalse

By default, the scripting process sends the results to the console, so setting theToFileOnly

property toTruecauses the scripter to send the script only to the file specified Setting the

ClusteredIndexesproperty toTruecauses the clustered index for a table to be included in the

script, and setting theIndexesproperty toTruecauses the non-clustered indexes to be included

Trang 8

in the script TheDriAllproperty, when set toTrue, 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 typeSqlSmoObject Once the array has

been populated with all the objects to be scripted, invoke theScriptmethod 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 aDataAdapterobject to fill aDataSet 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

ExecuteReadermethod of theSqlCommandobject

The following example, shown in Listing 7-8, uses theAdventureWorks2008database to extract

department employee information byDepartmentID, 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 TheExecuteReadermethod returns a

DataReaderobject, and the columns must be retrieved from the object using the GetValuemethod

of theDataReader, supplying the column index number toGetValue 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

DepartmentIDvalue has changed If so, a ‘‘header’’ row is created in a string variable ($r) and written

to a file with the name of the departmentNamevalue and a txtextension Once the header has been

written, the data row just read is written to the file

Trang 9

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]"

.[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"

Trang 10

$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) calledsqlps.exethat includes the provider and

preloads all of the DLLs that the provider requires, including the DLLs for SMO Another difference

between standard PowerShell andsqlps.exeis that the execution policy of PowerShell insqlps.exe

is set to RemoteSigned This means that as soon as SQL Server 2008 is installed,sqlps.exeis 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 athttp://blogs.msdn.com/mwories/archive/2008/06/14/SQL2008 5F00

Powershell.aspxhe provides the script that loads it into PowerShell

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

TỪ KHÓA LIÊN QUAN