65在TableAdapters中创建新的存储过程.docx

上传人:b****8 文档编号:10042540 上传时间:2023-02-08 格式:DOCX 页数:42 大小:398.39KB
下载 相关 举报
65在TableAdapters中创建新的存储过程.docx_第1页
第1页 / 共42页
65在TableAdapters中创建新的存储过程.docx_第2页
第2页 / 共42页
65在TableAdapters中创建新的存储过程.docx_第3页
第3页 / 共42页
65在TableAdapters中创建新的存储过程.docx_第4页
第4页 / 共42页
65在TableAdapters中创建新的存储过程.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

65在TableAdapters中创建新的存储过程.docx

《65在TableAdapters中创建新的存储过程.docx》由会员分享,可在线阅读,更多相关《65在TableAdapters中创建新的存储过程.docx(42页珍藏版)》请在冰豆网上搜索。

65在TableAdapters中创建新的存储过程.docx

65在TableAdapters中创建新的存储过程

六十五:

在TableAdapters中创建新的存储过程

导言:

  本教程的DataAccessLayer(DAL)使用的是类型化的数据集(TypedDataSets).就像我们在第一章《创建一个数据访问层》里探讨的一样,该类型化的数据集由强类型的DataTable和TableAdapter构成。

DataTable描绘的是系统里的逻辑实体而TableAdapter引用相关数据库执行数据访问,包括对DataTable填充数据、执行返回标量数据(scalardata)的请求、添加,更新,删除数据库里的记录等.

  TableAdapter执行的SQL命令要么是某个特定的SQLstatements,比如SELECTcolumnListFROMTableName;要么是存储过程.本教程前面部分的TableAdapter使用的是SQLstatements.不过很多开发者和数据库管理员基于安全、便于维护等方面的考虑,偏爱使用存储过程;不过也有的人出于灵活性的考虑偏爱使用SQLstatement.就我自己而言,我也偏向于存储过程.在前面的文章,出于简化的目的我选用的是SQLstatements.

  当定义一个新TableAdapter或添加新方法时,使用TableAdapter的设置向导,我们可以很容易的创建新的或使用现有的存储过程.在本文,我们将考察如何使用设置向导自动的生产存储过程。

在下一章我们考察如何设置TableAdapter的方法使用现有的或手动创建存储过程.

  注意:

关于讨论到底使用存储过程还是使用SQLstatements的问题,可参考RobHoward的博客文章《Don'tUseStoredProceduresYet?

》(Bouma的博客文章《StoredProceduresareBad,M'Kay?

》(

存储过程基础

  一个存储过程由一系列的T-SQLstatement组成,当调用该存储过程时就执行这些T-SQLstatement.存储过程可以接受0到多个输入参数,返回标量值、输出参数,或最常见的返回SELECT查询值.

  注意:

存储过程Storedprocedures也经常引用为“sprocs”or“SPs”.

  可以使用T-SQLstatement语句CREATEPROCEDURE来创建存储过程.比如下面的T-SQL脚本创建了一个名为GetProductsByCategoryID的存储过程,它有一个名为@CategoryID的参数,并且将表Products里与CategoryID值相吻合的那条记录的ProductID,ProductName,UnitPrice,以及Discontinued值返回.

?

1

2

3

4

5

6

7

8

9

CREATEPROCEDUREGetProductsByCategoryID

 @CategoryIDint

AS

 

SELECTProductID,ProductName,UnitPrice,Discontinued

FROMProducts

WHERECategoryID=@CategoryID

创建后,我们可以用下面的代码调用它:

?

1

EXECGetProductsByCategorycategoryID

  注意:

在下篇文章我们将在VisualStudioIDE集成环境里创建存储过程.不过在本文,我们将用TableAdapter向导来自动创建存储过程.

  除了返回数据外,我们还可以在一个事务里用存储过程执行多条数据库命令.比如,假如有一个名为DeleteCategory的存储过程,其包含一个输入参数@CategoryID,并执行2个DELETEstatemets,第一个是删除相关的products,第二个是删除category。

存储过程里面的多个statements并不是自动的封装在一个事务里的.我们应添加额外的T-SQLcommands以确保存储过程里的多条数据库命令当成原子操作处理.我们将在后面的内容考察如何用事务来封装存储过程的命令.

  当在体系的某个层使用存储过程时,DataAccessLayer的方法将调用某个具体的存储过程而不是发出一个SQLstatement命令.这样一来我们可以发现、分析发出的查询命令.并可以更清楚的看到数据库是如何使用的.有关存储过程基本原理的更多信息,可参考本文结束部分的延伸阅读.

第一步:

创建数据访问层高级场景的Web页面

在开始之前,让我们花点时间创建本文及后面几篇文章要用到的页面。

新建一个名为AdvancedDAL的文件夹,然后添加如下的ASP.NET页面,记得使用母版页Site.master:

Default.aspx

NewSprocs.aspx

ExistingSprocs.aspx

JOINs.aspx

AddingColumns.aspx

ComputedColumns.aspx

EncryptingConfigSections.aspx

ManagedFunctionsAndSprocs.aspx

图1:

添加相关的页面

像其它文件夹一样,Default.aspx页面将列出本部分的内容,记得SectionLevelTutorialListing.ascx用户控件提供了该功能。

因此,将其从解决资源管理器里拖放到Default.aspx页面.

图2:

将SectionLevelTutorialListing.ascx用户控件拖到Default.aspx页面

最后,将这些页面添加到Web.sitemap文件里。

特别的,把下面的代码放在“WorkingwithBatchedData”

标签后面:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

 title="AdvancedDALScenarios"

 description="ExploreanumberofadvancedDataAccessLayerscenarios.">

  

 

 title="CreatingNewStoredProceduresforTableAdapters"

 description="LearnhowtohavetheTableAdapterwizardautomatically

 createandusestoredprocedures."/>

 

 title="UsingExistingStoredProceduresforTableAdapters"

 description="Seehowtoplugexistingstoredproceduresintoa

 TableAdapter."/>

 

 title="ReturningDataUsingJOINs"

 description="LearnhowtoaugmentyourDataTablestoworkwithdata

 returnedfrommultipletablesviaaJOINquery."/>

 

 title="AddingDataColumnstoaDataTable"

 description="MasteraddingnewcolumnstoanexistingDataTable."/>

 

 title="WorkingwithComputedColumns"

 description="Explorehowtoworkwithcomputedcolumnswhenusing

 TypedDataSets."/>

 

 title="ProtectedConnectionStringsinWeb.config"

 description="Protectyourconnectionstringinformationin

 Web.configusingencryption."/>

 

 title="CreatingManagedSQLFunctionsandStoredProcedures"

 description="SeehowtocreateSQLfunctionsandstoredprocedures

 usingmanagedcode."/>

更新Web.sitemap文件后,花点时间在浏览器里查看,左边的菜单将包括本部分的内容.

图3:

网站地图现在包含了不部分的页面

第二步:

设置TableAdapter创建新的存储过程

  我们在~/App_Code/DAL文件夹里创建一个类型化的DataSet,名称为NorthwindWithSprocs.xsd.由于我们在以前的教程里已经详细探讨了创建细节,因此我们这里一笔带过,如果你想知道详细的创建过程请参阅前面的第1章《创建一个数据访问层》在DAL文件夹上右击鼠标选“添加新项”,选DataSet模板,如图4所示.

图4:

新建一个名为NorthwindWithSprocs.xsd的数据集

  这样将会创建一个新的类型化的DataSet,打开设计器,创建一个新的TableAdapter,展开TableAdapter设置向导.向导的第一步是让我们选择要连接的数据库.在下拉列表里有一个连接到Northwind数据库的连接字符串,选中它,再点下一步。

接下来的界面让我们选择TableAdapter以哪种方式访问数据库.在以前的教程里我们选择的是“UseSQLstatements”,不过在本文我们选第二项:

“Createnewstoredprocedures”,点下一步.

图5:

设置TableAdpater创建新的存储过程

接下来,我们要指定主查询(mainquery).我们将创建一个存储过程来包含SELECT查询.

使用下面的SELECT查询:

?

1

2

3

4

SELECTProductID,ProductName,SupplierID,CategoryID,

 QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,

 ReorderLevel,Discontinued

FROMProducts

图6:

键入SELECT查询

  注意:

在名为Northwind的数据集里的ProductsTableAdapter的主查询与上面本文定义的主查询有所不同。

那个主查询还返回了每个产品的category名称和company名称.不过在后面的文章我们将对本文的TableAdapter添加这些相关的代码.再点“AdvancedOptions”按钮.我们可以指定是否让向导为TableAdapter自动生成insert,update和deletestatements;是否使用开发式并发操作(optimisticconcurrency);是否完成inserts和update操作后刷新数据表.在默认情况下,自动选中“GenerateInsert,UpdateandDeletestatements”选项。

另外,本文不用选择“Useoptimisticconcurrency”项.当选择自动创建存储过程时,“Refreshthedatatable”项将被忽略掉.不管是否选中该项,最终的insert和update存储过程都会检索刚添加或刚更新(just-insertedorjust-updatedrecord)的记录,我们将在第三步看到.

图7:

选中“GenerateInsert,UpdateandDeletestatements”项

  注意:

当选中“Useoptimisticconcurrency”项的时候,向导会在WHERE语句里添加额外的条件,当其它列的值发生改动的话,将阻止数据更新.关于使用TableAdapter内置的optimisticconcurrency功能请参阅第21章《实现开放式并发》输入SELECT主查询并选取“GenerateInsert,UpdateandDeletestatements”项后,点下一步,接下来的界面,如图8所示,让我们为selecting,inserting,updating,和deleting数据的存储过程命名.将这些存储过程的名字改为Products_Select,Products_Insert,Products_Update,和Products_Delete.

图8:

为存储过程重命名

向导创建了4个存储过程,点“PreviewSQLScript”按钮,你可以在PreviewSQLScript对话框里将脚本保存在一个文件里或复制到剪贴板.

图9:

预览生成的存储过程

  对存储过程重命名后,点下一步,对TableAdapter相应的方法命名.就像使用SQLstatements一样,我们可以创建方法来填充一个现有的DataTable或返回一个新的DataTable;我们也一个指定TableAdapter是否采用DB-Direct模式来插入、更新、删除记录.全选这3项,只不过将ReturnaDataTable方法重命名为GetProducts,如图10所示:

图10:

将方法重命名为Fill和GetProducts

点Next总览向导将执行的步骤.点Finish按钮完成设置.一旦向导结束后,将返回DataSet设计器,它此时将包括ProductsDataTable.

图11:

DataSet设计器将显示刚刚添加的ProductsDataTable

第三步:

考察刚刚创建的存储过程

  我们在第二步里用向导创建了选择、插入、更新、删除数据的存储过程.这些存储过程可以通过VisualStudio查看或修改.打开服务器资源管理器,点到数据库的存储过程文件夹。

如图12所示,Northwind数据库包含了4个新的存储过程,Products_Delete,Products_Insert,Products_Select,andProducts_Update.

图12:

可以在StoredProcedures文件夹里找到我们创建的4个存储过程

  注意:

如果你看不到服务器资源管理器,点“View”菜单,选ServerExplorer项.如果你无法找到新创建的存储过程,右击StoredProcedures文件夹,选“刷新”.

  要查看或修改某个存储过程,在服务器资源管理器里双击其名字或右击该存储过程,选”打开“。

如13显示的是打开Products_Delete存储过程的画面.

图13:

可以在VisualStudio里打开并修改存储过程

Products_Delete和Products_Select存储过程的内容很好理解。

比如下面的代码构成了Products_Insert存储过程.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

ALTERPROCEDUREdbo.Products_Insert

 @ProductNamenvarchar(40),

 @SupplierIDint,

 @CategoryIDint,

 @QuantityPerUnitnvarchar(20),

 @UnitPricemoney,

 @UnitsInStocksmallint,

 @UnitsOnOrdersmallint,

 @ReorderLevelsmallint,

 @Discontinuedbit

AS

 SETNOCOUNTOFF;

INSERTINTO[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],

 [UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])

VALUES(@ProductName,@SupplierID,@CategoryID,@QuantityPerUnit,@UnitPrice,

 @UnitsInStock,@UnitsOnOrder,@ReorderLevel,@Discontinued);

  

SELECTProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,

 UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued

FROMProducts

WHERE(ProductID=SCOPE_IDENTITY())

  在TableAdapter向导里定义的SELECT查询返回Products表里的列,这些列又作为存储过程的输入参数并运用到INSERTstatement中.紧接着的是一个SELECT查询,返回Products表里最新添加的记录的各列的值(包括ProductID)。

当使用BatchUpdate模式添加一个新记录时,刷新功能是很有用的。

因为它将最新添加的ProductRowinstances实例的ProductID属性赋值为数据库指派的自增值.

  下面的代码说明了该功能.代码创建了基于NorthwindWithSprocs数据集的ProductsTableAdapter以及ProductsDataTable。

要向数据库添加一个新的产品,我们要创建一个ProductsRowinstance实例,对其赋值,并调用TableAdapter的Update方法,再传递给ProductsDataTable.在内部,TableAdapter的Update方法遍历传递给DataTable的所有ProductsRowinstance实例(在本例,只有一个。

因为我们只添加了一个产品),并执行相应的insert,update,或delete命令。

此时,执行Products_Insert存储过程,其向Products表添加一条新记录,并返回该记录的详细信息,然后更新ProductsRowinstance实例的ProductID值。

Update方法完成后,我们就可以通过ProductsRow的ProductID属性访问新添加记录的ProductID值了.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//CreatetheProductsTableAdapterandProductsDataTable

NorthwindWithSprocsTableAdapters.ProductsTableAdapterproductsAPI=

 newNorthwindWithSprocsTableAdapters.ProductsTableAdapter();

NorthwindWithSprocs.ProductsDataTableproducts=

 newNorthwindWithSprocs.ProductsDataTable();

 

//CreateanewProductsRowinstanceandsetitsproperties

NorthwindWithSprocs.ProductsRowproduct=products.NewProductsRow();

product.ProductName="NewProduct";

product.CategoryID=1;//Beverages

product.Discontinued=false;

 

//AddtheProductsRowinstancetotheDataTable

products.AddProductsRow(product);

 

//UpdatetheDataTableusingtheBatchUpdatepattern

productsAPI.Update(products);

 

//Atthispoint,wecandeterminethevalueofthenewly-addedrecord'sProductID

intnewlyAddedProductIDValue=product.ProductID;

类似的,Products_Update存储过程的UPDATEstatement后面也包含一个SELECTstatement,如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

ALTERPROCEDUREdbo.Products_Update

 @ProductNamenvarchar(40),

 @SupplierIDint,

 @CategoryIDint,

 @QuantityPerUnitnvarchar(20),

 @UnitPricemoney,

 @UnitsIn

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 专升本

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1