使用存储过程给子表格增加多个记录

  本教程是教程《使用存储过程来增加和显示新的记录》的延续。如果你还没有阅读这个教程,请先阅读完教程《使用存储过程来增加和显示新的记录》之后再阅读本教程。
  对于许多应用程序,你想让用户能够增加新的记录。基本的Server Extensions(服务器扩展)允许你这样做,它是利用SQL_INSERT语句,但是它只能对于一个表格。在许多情况下,你可能需要同时插入数据到多个表格,这些表格有一个相同的ID区域进行连接。举个例子,Orders和OrderDetail插入就包含了一个在两个表格之间的父/子关系。在教程2中处理的是简单的例子,它只是增加一个新的父记录并且增加一个相应的子记录。但是怎样增加一个父记录和多个子记录呢?在本教程中将教你如何做。这里还是使用相同的工作应用程序,所以这里就不在重复叙述了。
  本教程是一个你为什么应该使用存储过程的一个很好的例子。我可以改变我的应用程序允许多行插入到子表格,具体做法基本上是通过改变存储过程的代码。我只有改变所有在教程2中UltraDev产生的网页。通过在你的数据库中而不是在你的网页中压缩你的应用程序逻辑,你可以节省许多设计开发的时间,并且网页应用程序会更加轻便。
  下面的例子是用VBScript,并且在NT 4.0工作站、PWS(Personal Web Server,个人网页服务器)和 SQL 7.0.中创建的。另外你可能想改变光标以及锁定在你记录集中的设置。
增加Confirmation页面:AddConfirm.asp
  这个页面在应用程序中做了所有的实际工作。调用这个网页插入新的记录到两个(或者更多)相关表格并且将新的JobID传递给两个附加的记录集以可以显示新增数据给用户。在这个网页上有几个记录集,它们同Request(请求)变量从AddJop.asp表单的信息转换成存储过程。如图1所示的数据绑定显示了所有的记录集和Request(请求)变量。
 
  其中,commJobAdd示一个基于存储过程(commJobAdd)命令,它插入一个新的记录到Jobs表格中,并且从插入中提取新的JobID,再使用它同时插入子表JobCategory。这个命令同时返回了
JobID的数值给ASP页面。
  RsJobSearch是一个记录集,它接收从commJobAdd传来的JobID并且将它作为参数再传递个一个存储过程(spJobSearch)以返回数据用于新插入的记录。
  RsJobCategories也是一个记录集,它接收来自commJobAdd的一个JobID,并且将它作为参数并
传递给存储过程(spJobCategories)以返回那个JobID的分类。

命令存储过程
commAddJob存储过程需要你正确配置命令,参见图2。

  当你在SQL 7中建立了初始的连接到存储过程,变量列表框将自动集中来自存储过程的@变量以及正确的数据类型。我们可以看到,绝大多数的变量被设置运行数值,它们被传递给存储过程。为了让命令正确运行,你需要根据在数据库表格中你是怎样配置区域的来为每一个数据类型设置大小。然后你需要增加适当的Request("fieldname")运行数值。值得提醒的是,我们标识了所有的从AddJob.asp表单的文本框和列表框,标识是用相同的名字作为存储过程变量的(负的@符号)。你可以看到所有的Request变量列表在图1中。
  你已经准备好改变UltraDev代码了吗?为了使这个网页可以使用多行插入,我不得不对commJobAdd存储过程的代码做大量的改变。现在我必须做的唯一改变示打开commAddJob命令并
改变以下变量:

名字

初始页面:类型,方向,尺寸

新页面:类型,方向,尺寸

@CategoryID

Integer, 4, in

Varchar, 100, in

缺省的数值支持:(nothing),而Run-time(运行)数值支持:Request("CategoryID")。

总体解释
  我们使用存储过程来插入数据,因为我们要插入记录到两个表格(Jobs和JobCategory)中去。当用户在AddJobs.asp表单中点击Add Job (增加工作)按钮,它将作为Request(请求)变量发送所有的表单数值给AddConfirm.asp页面。当网页装载时候这个commJobAdd存储过程运行。可以利用Request变量和使用信息来插入数据到Jobs表格中。
  Jobs表格使用JobID作为主键区域。SQL Server 7用一个特殊数据库数值,即@@标识,它等于主键区域的数值,可以用于新插入记录。这个存储记录使用@@标识数值作为JobID。
  你会注意到我们也创建了存储过程来传递一个OUTPUT数值给@JobID,@JobID示新插入工作记录的JobID数值。这个JobID数值首先传递给spJobSearch存储过程(这个过程集中了rsJobSearch记录集),同时传递给spJobCategories存储过程(这个过程集中了rsJobCategories记录集)并且显示所有的新增工作信息给用户。
存储过程
commJobAdd
  对于那些熟悉存储过程的人会注意到只需对在教程2中我们使用的存储过程做一小部分改变。
  这里我们定义@CategoryID 和 @PopulationID作为字符,因为我们要传递多选列表给存储过程。如果用户只选择列表中的一项,它将传递2(假如2是CategoryID)。如果多项被选择,它将
发送一个逗号相隔的列表,如“2,3,5”。虽然CategoryID区域示一个整数,我们必须将数值
转换为字符,这样它就可以通过存储过程正确的传送。我们创建一个动态SQL语句是为了正确
分列CategoryID。我们创建一个新变量@CatInsert作为动态SQL语句并且执行这个语句。SQL允
许当你有多行要插入时可以使用INSERT...SELECT语句,
代码如下:
DECLARE @CatInsert varchar(2000) -- Declare a new variable for the dynamic SQL
statement
SET @CatInsert = 'INSERT INTO JobCategory (JobID, CategoryID) SELECT ' +
CONVERT(varchar,@JobID) + ', Category1ID From CategoryType Where Category1ID IN ('
+ @CategoryID + ')' -- Create a SELECT statement that includes the new JOBID and
compares whatever is in @CATEGORYID list with against the values in the
CategoryType Lookup table.
如果你只选择了列表框中的一个数值,你将就只得到一行插入到JobCategory表格:

@JobID Value

@CategoryID Value

2

3



如果你只选择了列表框中的一个数值,你将就只得到一行插入到JobCategory表格:
 
@JobID Value

@CategoryID Value

2

3

2

4

2

5

具体代码如下:
Alter PROCEDURE "spAddJob"
-- Author: Rick Curtis
-- Date: July 21, 2000
-- Purpose: Insert new entry into Jobs table and related data into child tables
JobCategory and JobPopulations
-- Declare variables for inserts to all 3 tables
(@CompanyID [int], @JobTypeID [int], @RegionID [int], @JobTitle [varchar](100),
@StartDate [datetime], @CloseDate [datetime], @JobDescription [varchar](4000),
@Qualifications [varchar](4000), @SalaryBenefits [varchar](4000), @Resp
[varchar](4000), @Availability [varchar](200), @ToApply [varchar](2000),
@EmailJobs [varchar](100), @CategoryID [varchar](100), @PopulationID
[varchar](100), @JobID [int] OUTPUT)
AS
-- Insert into Jobs table

INSERT INTO Jobs

([CompanyID], [JobTypeID], [RegionID], [JobTitle], [StartDate], [CloseDate],
[JobDescription], [Qualifications], [SalaryBenefits], [Resp], [Availability],
[ToApply], [EmailJobs]) VALUES (@CompanyID, @JobTypeID, @RegionID, @JobTitle,
@StartDate, @CloseDate, @JobDescription, @Qualifications, @SalaryBenefits, @Resp,
@Availability, @ToApply, @EmailJobs)

-- Retrieve the automatically generated JobID VALUE from the Jobs table

SET @JobId = @@IDENTITY

-- Insert new values into JobCategory table

DECLARE @CatInsert varchar(2000)

SET @CatInsert = 'INSERT INTO JobCategory (JobID, CategoryID) SELECT ' +
CONVERT(varchar,@JobID) + ', Category1ID From CategoryType Where Category1ID IN ('
+ @CategoryID + ')'

exec(@CatInsert)

-- Insert new values into JobPopulation table

DECLARE @PopInsert varchar(2000)

SET @PopInsert = 'INSERT INTO JobPopulation (JobID, PopulationID) SELECT ' +
CONVERT(varchar,@JobID) + ', PopulationID From Population Where PopulationID IN ('
+ @PopulationID + ')'

exec(@PopInsert)

Return