http://www.chinesejy.com/jishu/508/519/2006061781665.html

主子表最常见的大概就是用在进销存、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

EXECUTE PopFirstWord
@PriceList OUTPUT, @FirstPriceWord
OUTPUT

IF @Length > 0

BEGIN

SELECT @ProductId = CONVERT(INT, @FirstProductIdWord)

SELECT @Num = CONVERT(INT, @FirstNumWord)

SELECT @Price = CONVERT(MONEY, @FirstPriceWord)

EXECUTE InsertOrderDetail @Id, @ProductId, @Price, @Num

END

END

--存储过程三

CREATE PROCEDURE PopFirstWord

@SourceString   NVARCHAR(4000) = NULL OUTPUT,

@FirstWord      NVARCHAR(4000) =
NULL OUTPUT

AS

SET NOCOUNT ON

DECLARE @Oldword        NVARCHAR(4000)

DECLARE @Length         INT

DECLARE @CommaLocation  INT

SELECT @Oldword = @SourceString

IF NOT @Oldword IS NULL

BEGIN

SELECT @CommaLocation = CHARINDEX(',',@Oldword)

SELECT @Length = DATALENGTH(@Oldword)

IF @CommaLocation = 0

BEGIN

SELECT @FirstWord =
@Oldword

SELECT @SourceString = NULL

RETURN @Length

END

SELECT @FirstWord =
SUBSTRING(@Oldword, 1, @CommaLocation -1)

SELECT @SourceString = SUBSTRING(@Oldword, @CommaLocation + 1,
@Length - @CommaLocation)

RETURN @Length - @CommaLocation

END

RETURN 0

------------------------------------------------

--存储过程四

CREATE PROCEDURE InsertOrderDetail

@OrderId    INT = NULL,

@ProductId     INT = NULL,

@Price  MONEY = NULL,

&n

小议主子表INT自增主键插入记录的方法SQL server]教程的更多相关文章

  1. mysql数据库表的自增主键号不规律,重新排列

    mysql数据库表的自增主键ID乱了,需要重新排序. 原理:删除原有的自增ID,重新建立新的自增ID. 1.删除原有主键: ALTER TABLE `table_name` DROP `id`; 2. ...

  2. Mysql数据库表的自增主键ID号乱了,需要重新排列。

    Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...

  3. 使用UUID和int自增主键的区别

    知其然,知其所以然.在看到生成UUID的代码,后带给我的百度结合自己的经验再写下来的区别 一.UUID做主键: 优点: .保证数据在表和库都是独立的,有利于后续的分库 .合并表的时候主键不会重复 .有 ...

  4. MYSQL获取自增主键【4种方法】

    通常我们在应用中对mysql执行了insert操作后,需要获取插入记录的自增主键.本文将介绍java环境下的4种方法获取insert后的记录主键auto_increment的值: 通过JDBC2.0提 ...

  5. MYSQL获取自增主键【4种方法】(转)

    转自:http://blog.csdn.net/ultrani/article/details/9351573 作者已经写的非常好了,我不废话了,直接转载收藏: 通常我们在应用中对mysql执行了in ...

  6. SQLServer 对已有数据表添加自增主键

    最近在做老表的数据整理,发现有的表没有主键标识,.NET Core 无法一键生成模型,需要带有主键的表才可以,所以需要针对已有数据添加主键,这是我找到的两种方式. 1. 主键为int 或者bigint ...

  7. mysql如何让有数据的表的自增主键重新设置从1开始连续自增

    项目开发中,有些固定数据在数据表中,主键是从1自增的,有时候我们会删除一些数据, 这种情况下,主键就会不连续.如何恢复到像第一次插入数据一样主键从1开始连续增长, 这里我找到一种解决方法: 如上面一张 ...

  8. oracle数据库建表设置自增主键

    create sequence userlogin_ID increment by 1 start with 1 minvalue 1 maxvalue 9999999999999999 nocach ...

  9. Oracle判断表、列、主键是否存在的方法

    在编写程序时,数据库结构会经常变化,所以经常需要编写一些数据库脚本,编写完成后需发往现场执行,如果已经存在或者重复执行,有些脚本会报错,所以需要判断其是否存在,现在我就把经常用到的一些判断方法和大家分 ...

随机推荐

  1. Objective-C中,类方法的getter和setter可以用点运算符吗?

    Objective-C中,对象实例property的getter和setter可以使用点运算符来操作,那么类方法的getter和setter可以使用点运算吗? 答案是肯定的. 看如下代码: #impo ...

  2. [BUAA OO]第一次博客作业

    第一次作业 第一次进行面向对象的编程,不论是针对数据设计类还是对方法进行合适的归于不同类中,都不是很熟悉.所写出来的程序还是面向过程+有函数的类(虽然现在很大程度上感觉起来也是这样).索性作业难度并不 ...

  3. 项目Beta冲刺团队随笔集

    博客集如下: Beta冲刺Day1:第一天冲刺记录 Beta冲刺Day2:第二天冲刺记录 Beta冲刺Day3:第三天冲刺记录 Beta冲刺Day4:第四天冲刺记录 Beta冲刺Day5:第五天冲刺记 ...

  4. 在visual studio中查看源代码

    地址:https://docs.microsoft.com/zh-cn/visualstudio/ide/go-to-and-peek-definition?view=vs-2017 在 Visual ...

  5. 团队作业4——第一次项目冲刺(Alpha版本)2017.11.16

    1.当天站立式会议照片 本次会议在5号公寓3楼召开,本次会议内容:①:熟悉每个人想做的模块.②:根据老师的要求将项目划分成一系列小任务.③:在上次会议内容完成的基础上增加新的任务. 2.每个人的工作 ...

  6. Java集合技巧

    集合的一些技巧:   需要唯一吗? 需要:Set 需要制定顺序:  需要: TreeSet 不需要:HashSet 但是想要一个和存储一致的顺序(有序):LinkedHashSet 不需要:List ...

  7. 由RS-232串口到PROFIBUS-DP总线的转换接口设计

    转自:http://gongkong.ofweek.com/2013-08/ART-310007-11001-28716256_2.html 1.PROFIBUS-DP网络协议 PROFIBUS的网络 ...

  8. .NET WinForm下StatusStrip控件如何设置分隔线及部分子控件右对齐

    ssInfo.LayoutStyle = ToolStripLayoutStyle.StackWithOverflow;//StatusStrip 控件 tsslUpdate.Alignment = ...

  9. [微软官方]FSUTIL

    Applies To: Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, Windows Server 2003 ...

  10. find K maximum value from an unsorted array(implement min heap)

    Maintain a min-heap with size = k, to collect the result. //Find K minimum values from an unsorted a ...