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

MSSQL
正确配置和使用SQL mail
关于DTS导入导出丢失默认值等对象
TOP N 和SET ROWCOUNT N 哪个更快
如何在视图中使用ORDER BY短语
如何区分大小写比较?
如何将作为字符串保存的IP地址变为二进制数值?
如何随机选取n条记录或者对记录作随机排序?
SQL脚本生成的一些BUG
如何使Microsoft SQL Server的日志文件不会增大?
利用事务日志来恢复Update、Delete误操作引起的数据丢
关于MSSQL占用过多内存的问题
SQL Server非正常删除日志文件(ldf)恢复方法
处理孤立用户的存储过程
1069错误(由于登录失败而无法启动服务)解决方法
SQL Server 7.0数据库的六种数据移动方法
利用SQL Server的扩展属性象access一样显示列的注释
Stored Procedure(存储过程)编写经验和优化措施
更新你的联机丛书
关于SQL Server中几个未公布的访问注册表的扩展存储过
存储过程替换text,ntext列中的字符串

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


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