当前位置: 首页 > 图文教程 > 数据库 > MSSQL > 小议主子表INT自增主键插入记录的方法

MSSQL
SQL Server TEXT、NTEXT字段拆分的问题
SQL Server事务日志的几个常用操作
SQL Server不存在或拒绝访问故障的排除
动态创建MSSQL数据库表存储过程
教你如何在SQL Server计算列和平均值
如何应用SQL Server中的DBCC避免堵塞
SQLServer2000分布式事务错误解决方法
通用SQL数据库查询语句精华使用简介
利用typeperf工具收集SQL Server性能数据
SQL 2008 FileStream数据类型
自定义用于ASP Web站点的 SQL 7.0 数据库
SQL server 2005安装问题大全
利用"SQL"语句自动生成序号的两种方式
SQL Server数据库管理员必备的DBCC命令
讲解在SQL Server 2005中实现异步触发器架构
SQL Server 2008的新特性概述:集成服务
SQL Server 2008关系数据库引擎的新增功能
浅析SQL 2008的Change Data Capture功能
在IIS中为SQL Server 2008配置报表服务
SQL Server 2008中报表服务详解

MSSQL 中的 小议主子表INT自增主键插入记录的方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 169 ::
收藏到网摘: n/a

 

       主子表最常见的大概就是用在进销存、MRP、ERP里面,比如一张销售订单,订单Order(ID,OrderDate),订单明细OrderDetail(OrderID, ProductID, Num,Price)这个大概就是最简单的主子表了,两个表通过ID与OrderID建立关联,这里主键ID是自增的INT类型,OrderID是表OrderDetail的外键。当然,键的选择方法很多,现在我们选择的是在sql里面最简单的方法。

    对于这样的表结构,我们最常见的问题就是保存的时候怎样处理键值的问题,因为两个表关联非常的紧密,我们进行保存的时候需要把它们放在一个事务里面,这时问题就会出现,Order表中的ID是自动增长型的字段。现在需要我们录入一张订单,包括在Order表中插入一条记录以及在OrderDetail表中插入若干条记录。因为Order表中的ID是自动增长型的字段,那么我们在记录正式插入到数据库之前无法事先得知它的取值,只有在更新后才能知道数据库为它分配的是什么值,然后再用这个ID作为OrderDetail表的OrderID的值,最后更新OderDetail表。但是,为了确保数据的一致性,Order与OrderDetail在更新时必须在事务保护下同时进行,即确保两表同时更行成功,这个就会有点困扰。


解决这类问题常见的主要有两类方法:


一种是微软在网上书店里使用的方法,使用了四个存储过程。改装一下,使之符合现在的例子


--存储过程一


CREATE PROCEDURE InsertOrder

 

    @Id                INT = NULL OUTPUT,

 

    @OrderDate        DATETIME = NULL,

 

    @ProductIDList     NVARCHAR(4000) = NULL,

 

    @NumList          NVARCHAR(4000) = NULL,

 

    @PriceList          NVARCHAR(4000) = NULL

 

AS

 

    SET NOCOUNT ON

 

    SET XACT_ABORT ON

 

    BEGIN TRANSACTION

 

   --插入主表

 

    INSERT Orders(OrderDate) select @OrderDate

 

     SELECT @Id = @@IDENTITY

 

      -- 插入子表

 

     IF @ProductIDList IS NOT NULL

 

            EXECUTE InsertOrderDetailsByList @Id, @ProductIdList, @numList, @PriceList

 

    COMMIT TRANSACTION

 

    RETURN 0

 

--存储过程二

 

CREATE PROCEDURE InsertOrderDetailsByList

 

    @Id        INT,

 

    @ProductIDList     NVARCHAR(4000) = NULL,

 

    @NumList      NVARCHAR(4000) = NULL,

 

    @PriceList      NVARCHAR(4000) = NULL

 

AS

 

    SET NOCOUNT ON

 

    DECLARE @Length INT

 

    DECLARE @FirstProductIdWord NVARCHAR(4000)

 

    DECLARE @FirstNumWord NVARCHAR(4000)

 

    DECLARE @FirstPriceWord NVARCHAR(4000)

 

    DECLARE @ProductId INT

 

    DECLARE @Num INT

 

    DECLARE @Price MONEY

 

    SELECT @Length = DATALENGTH(@ProductIDList)

 

    WHILE @Length > 0

 

    BEGIN

 

        EXECUTE @Length = PopFirstWord @@ProductIDList OUTPUT, @FirstProductIdWord OUTPUT

 

        EXECUTE PopFirstWord @NumList OUTPUT, @FirstNumWord OUTPUT

 

 &n