?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

湖南打转转麻将技巧:银河999官网 电玩:小议主子表INT自增主键插入记录的方法

?

长沙转转麻将必胜口诀 www.fv7j.com.cn 主子表最常见的大年夜概便是用在进销存、MRP、ERP里面,比如一张贩卖订单,订单Order(ID,OrderDate),订单明细OrderDetail(OrderID, ProductID, Num,Price)这个大年夜概便是最简单的主子表了,两个表经由过程ID与OrderID建立关联,这里主键ID是自增的INT类型,OrderID是表OrderDetail的外键。当然,键的选择措施很多,现在我们选择的是在sql里面最简单的措施。

对付这样的表布局,我们最常见的问题便是保存的时刻如何处置惩罚键值的问题,由于两个表关联异常的慎密,我们进行保存的时刻必要把它们放在一个事务里面,这时问题就会呈现,Order表中的ID是自动增长型的字段。现在必要我们录入一张订单,包括在Order表中插入一银河999官网 电玩笔记录以及在OrderDetail表中插入多少笔记录。由于Order表中的ID是自动增长型的字段,那么我们在记录正式插入到数据库之前无法事先得知它的取值,只有在更新后才能知道数据库为它分配的是什么值,然后再用这个ID作为OrderDetail表的OrderID的值,着末更新OderDetail表。然则,为了确保数据的同等性,Order与OrderDetail在更新时必须在事务?;は峦苯?,即确保两表同时更行成功,这个就会有点困扰。

办理这类问题常见的主要有两类措施:

一种是微软在网上书店里应用的措施,应用了四个存储历程。改装一下,使之相符现在的例子

--存储历程一

CREATE PROCEDURE InsertOrder

@IdINT = NULL OUTPUT,

@OrderDateDATETIME = NULL,

@ProductIDListNVARCHAR(4000) = NULL,

@NumListNVARCHAR(4000) = NULL,

@PriceListNVARCHAR(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银河999官网 电玩

COMMIT TRANSACTION

RETURN 0

--存储历程二

CREATE PROCEDURE InsertOrderDetailsByList

@IdINT,

@ProductIDListNVARCHAR(4000) = NULL,

@NumListNVARCHAR(4000) = NULL,

@PriceListNVARCHAR(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

@SourceStringNVARCHAR(4000) = NULL OUTPUT,

@FirstWordNVARCHAR(4000) = NULL OUTPUT

AS

SET NOCO银河999官网 电玩UNT ON

DECLARE @OldwordNVARCHAR(4000)

DECLARE @LengthINT

DECLARE @CommaLocationINT

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

@OrderIdINT = NULL,

@ProductIdINT = NULL,

@PriceMONEY = NULL,

@NumINT = NULL

AS

SET NOCOUNT ON

INSERT OrderDetail(OrderId,ProductId,Price,Num)

SELECT @OrderId,@ProductId,@Price,@Num

RETURN 0

插入时,传入的子表数据都是长度为4000的NVARCHAR类型,各个字段应用“,”瓜分,然后调用PopFirstWord分拆后分手调用InsertOrd银河999官网 电玩erDetail进行保存,由于在InsertOrder中进行了事务处置惩罚,数据的安然性也对照有保障,几个存储历程设计的精美新奇,很故意思,然则子表的几个数据大年夜小不能跨越4000字符,生怕不大年夜保险。

第二种措施是我对照常用的,为了方便,就不用存储历程了,这个例子用的是VB.NET。

‘处置惩罚数据的类

Public class DbTools

private Const _IDENTITY_SQL As String = "SELECT @@IDENTITY AS ID"

private Const _ID_FOR_REPLACE As String = "_ID_FOR_REPLACE"

‘对主子表插入记录

Public Function InsFatherSonRec(ByVal main_sql As String, ByVal ParamArray arParam() As String) As Integer

Dim conn As New SqlConnection(StrConn)

Dim ID AS INTEGER

conn.Open()

Dim trans As SqlTransaction = conn.BeginTransaction

Try

'主记录

myDBTools.SqlData.ExecuteNonQuery(trans, CommandType.Text, main_sql)

'返回新增ID号

ID = myDBTools.SqlData.ExecuteScalar(trans, CommandType.Text, _IDENTITY_SQL)

'从记录

If Not arParam Is Nothing Then

For Each sql In arParam

'将刚得到的ID号代入

sql = sql.WordStr(_ID_FOR_REPLACE, ID)

myDBTools.SqlData.ExecuteNonQuery(trans, CommandType.Text, sql)

Next

End If

trans.Commit()

Catch e As Exception

trans.Rollback()

Finally

conn.Close()

End Try

Return ID

End Function

End class

上面这段代码里有myDBTools,是对常见的数据库操作封装后的类,这个类对数据库进行直接的操作,有履历的.NET数据库法度榜样员基础上都邑有,一些闻名的例子法度榜样一样平常也都供给。

上面的是通用部分,下面是对详细单据的操作

Publid class Order

Public _OrderDate as date‘主表记录

Public ChildDt as datatable‘子表记录,布局与OrderDetail同等

Public function Save() as integer

Dim str as string

Dim i as integer

Dim arParam() As String

Dim str as string=”insert into Order(OrderDate) values(‘” & _OrderDate & “’)”

If not Chi银河999官网 电玩lddt is nothing then

arParam = New String(ChildDT.Rows.Count - 1) {}

for i=0 to Childdt.rows.count-1

arparam(i)= ”insert into OrderDetail(OrderID,ProductID,Num,Price) Values(_ID_FOR_REPLACE,” & drow(“ProductID) & “,” & drow(“Num”) & “,” drow(“price”) & “)”

next i

End if

Return (new dbtools). InsFatherSonRec(str,arparam)

End class

上面的两个例子为了方便解释,去掉落了一些查验验证历程,有兴趣的同伙可以参照网上书店的例子钻研第一种措施,或者根据自己的必要对第二种措施进行改动。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: