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

MSSQL
系统存储过程sp_MSforeachtable和sp_MSforeachdb使用说明
一些文件未注册导致mssql表文件无法找开的解决方法
用sql获取某字符串中的数字部分的语句
SQL 判断字段类型语句
MSSQL 生成日期列表代码
MSSQL 计算两个日期相差的工作天数的语句
SqlServer 实用操作小技巧集合
sql中all,any,some用法
最常用的SQL语句
SQL语法 分隔符理解小结
sql 服务器知识
隐藏在SQLServer 字段中的超诡异字符解决过程
将备份数据还原到数据库的步骤
SQL Server 高速缓存依赖分析
SQL 多表连接查询实现语句
sql convert函数使用小结
sqlserver2005 行列转换实现方法
跨服务器查询导入数据的sql语句
返回SQL执行时间的存储过程
MSSQL ISQL命令详解

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 72 ::
收藏到网摘: 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