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. 【NLP】使用bert

    # 参考 https://blog.csdn.net/luoyexuge/article/details/84939755 小做改动 需要: github上下载bert的代码:https://gith ...

  2. mongodb 如何删除 字段值为 json对象中的某个字段值

    例如: { attributes: { birthday:'1988-01-01', name: 'aq' } } birthday是attributes字段的value的一个字段, 我要删除birt ...

  3. Django_事务

    介绍 函数说明 from django.db import transaction transaction.atomic # 原子性操作,把一系列操作当做一个整体,错了则集体回退 transactio ...

  4. 20145214 《网络对抗技术》 Web安全基础实践

    20145214 <网络对抗技术> Web安全基础实践 1.实验后回答问题 (1)SQL注入攻击原理,如何防御 SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的 ...

  5. 20145214《网络攻防》逆向及Bof基础实践

    20145214<网络攻防>逆向及Bof基础实践 实践说明 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...

  6. 读《我是IT小小鸟》有感

    我是一只IT小小鸟,我与IT结缘.书中是作者对个人经历与经验在IT下的体会,却给了我们很好的借鉴. IT这门行业,不仅仅再局限于如我们高中老师教学所要求的内容.IT更加开放,可以通过GitHub.CS ...

  7. 区别mouseover与mouseenter?

    区别mouseover与mouseenter? * mouseover: 在移入子元素时也会触发, 对应mouseout,进入子元素的时候,父元素显示离开状态 * mouseenter: 只在移入当前 ...

  8. HDU 2078 复习时间

    http://acm.hdu.edu.cn/showproblem.php?pid=2078 Problem Description 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.xh ...

  9. 微信小程序组件 自定义多选

    <view class='back'></view> <view class="container"> <!-- 睡眠记录 --> ...

  10. CSS 绝对定位与弹性布局合作居中

    position: absolute; display:flex; justify-content:center;align-items:center;