小议主子表INT自增主键插入记录的方法SQL server]教程
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]教程的更多相关文章
- mysql数据库表的自增主键号不规律,重新排列
mysql数据库表的自增主键ID乱了,需要重新排序. 原理:删除原有的自增ID,重新建立新的自增ID. 1.删除原有主键: ALTER TABLE `table_name` DROP `id`; 2. ...
- Mysql数据库表的自增主键ID号乱了,需要重新排列。
Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...
- 使用UUID和int自增主键的区别
知其然,知其所以然.在看到生成UUID的代码,后带给我的百度结合自己的经验再写下来的区别 一.UUID做主键: 优点: .保证数据在表和库都是独立的,有利于后续的分库 .合并表的时候主键不会重复 .有 ...
- MYSQL获取自增主键【4种方法】
通常我们在应用中对mysql执行了insert操作后,需要获取插入记录的自增主键.本文将介绍java环境下的4种方法获取insert后的记录主键auto_increment的值: 通过JDBC2.0提 ...
- MYSQL获取自增主键【4种方法】(转)
转自:http://blog.csdn.net/ultrani/article/details/9351573 作者已经写的非常好了,我不废话了,直接转载收藏: 通常我们在应用中对mysql执行了in ...
- SQLServer 对已有数据表添加自增主键
最近在做老表的数据整理,发现有的表没有主键标识,.NET Core 无法一键生成模型,需要带有主键的表才可以,所以需要针对已有数据添加主键,这是我找到的两种方式. 1. 主键为int 或者bigint ...
- mysql如何让有数据的表的自增主键重新设置从1开始连续自增
项目开发中,有些固定数据在数据表中,主键是从1自增的,有时候我们会删除一些数据, 这种情况下,主键就会不连续.如何恢复到像第一次插入数据一样主键从1开始连续增长, 这里我找到一种解决方法: 如上面一张 ...
- oracle数据库建表设置自增主键
create sequence userlogin_ID increment by 1 start with 1 minvalue 1 maxvalue 9999999999999999 nocach ...
- Oracle判断表、列、主键是否存在的方法
在编写程序时,数据库结构会经常变化,所以经常需要编写一些数据库脚本,编写完成后需发往现场执行,如果已经存在或者重复执行,有些脚本会报错,所以需要判断其是否存在,现在我就把经常用到的一些判断方法和大家分 ...
随机推荐
- 【NLP】使用bert
# 参考 https://blog.csdn.net/luoyexuge/article/details/84939755 小做改动 需要: github上下载bert的代码:https://gith ...
- mongodb 如何删除 字段值为 json对象中的某个字段值
例如: { attributes: { birthday:'1988-01-01', name: 'aq' } } birthday是attributes字段的value的一个字段, 我要删除birt ...
- Django_事务
介绍 函数说明 from django.db import transaction transaction.atomic # 原子性操作,把一系列操作当做一个整体,错了则集体回退 transactio ...
- 20145214 《网络对抗技术》 Web安全基础实践
20145214 <网络对抗技术> Web安全基础实践 1.实验后回答问题 (1)SQL注入攻击原理,如何防御 SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的 ...
- 20145214《网络攻防》逆向及Bof基础实践
20145214<网络攻防>逆向及Bof基础实践 实践说明 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...
- 读《我是IT小小鸟》有感
我是一只IT小小鸟,我与IT结缘.书中是作者对个人经历与经验在IT下的体会,却给了我们很好的借鉴. IT这门行业,不仅仅再局限于如我们高中老师教学所要求的内容.IT更加开放,可以通过GitHub.CS ...
- 区别mouseover与mouseenter?
区别mouseover与mouseenter? * mouseover: 在移入子元素时也会触发, 对应mouseout,进入子元素的时候,父元素显示离开状态 * mouseenter: 只在移入当前 ...
- HDU 2078 复习时间
http://acm.hdu.edu.cn/showproblem.php?pid=2078 Problem Description 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.xh ...
- 微信小程序组件 自定义多选
<view class='back'></view> <view class="container"> <!-- 睡眠记录 --> ...
- CSS 绝对定位与弹性布局合作居中
position: absolute; display:flex; justify-content:center;align-items:center;