yhxhappy 发表于 2018-4-13 10:53:15

[已解决] MsSQL 如何在插入行时同时获取自增ID

本帖最后由 yhxhappy 于 2018-4-15 12:13 编辑

表有两列,结构是这样:ID int identity(1,1) PRIMARY KEY, Model varchar(30)
第1列ID每插入一行自动递增

现在可以做到先插入行,再查询表的最新ID,但这样做法缺点是,在查询ID之前如果其他用户又插入一行,得到的ID值就是错误的。

所以想在插入行的同时获取该行的ID。
在 SQL Server Management Studio 中按以下操作可以实现:
INSERT "表" ("MODEL") VALUES (115) SELECT @@IDENTITY


以下代码已更新,可以解决我的问题。Func _MsSQL_InsertTable($Obj, $Table, $Field, $Value)                        ;插入行,字段与值对应,可部分或完全填写
   If Not IsObj($Obj) Then
          SetError(1)
          Return 0
   ElseIf $Table = "" Or $Field = "" Or $Value = "" Then
          SetError(4)
          Return 0
   EndIf

   $FieldArray = StringSplit($Field, ",")
   $ValueArray = StringSplit($Value, ",")
   If $FieldArray <> $ValueArray Then
          SetError(2)
          Return 0
   EndIf

   Local $FieldText = "", $ValueText
   For $i = 1 To $ValueArray
          $ValueText &= "'" & $ValueArray[$i] & "',"
   Next
   $ValueText = StringTrimRight($ValueText, 1)

   $RS = ObjCreate("ADODB.Recordset")
   $RS.ActiveConnection = $Obj

   ConsoleWrite("SELECT MAX(ID)+1 FROM "& $Table &" INSERT " & $Table & " (" & $Field & ") VALUES (" & $ValueText & ")" & @CRLF)
   $RS.Open("SELECT MAX(ID)+1 FROM "& $Table &" INSERT " & $Table & " (" & $Field & ") VALUES (" & $ValueText & ")")
   If @error Then
          SetError(3)
          Return 0
   EndIf

   $ID = $RS.Fields(0).value
   $RS.close
   Return $ID
EndFunc

298311657 发表于 2018-4-14 19:55:06

如果你的数据库存在同时多人更新数据的情况,那么你应该使用SCOPE_IDENTITY() 函数,而不是@@IDENTITY。因为@@IDENTITY返回的值是不区分作用域的,如果你在A表插入了一条数据,同时有人在B表插入数据,那你将会返回来自B表的@@IDENTITY值。
至于查询语句可以试试Select SCOPE_IDENTITY()as id

kk_lee69 发表于 2018-4-15 01:42:45

回复 1# yhxhappy

UPDATE 跟 INSERT 之後不會返回任何值

所以要返回的資料 要再 一開始就處理

你的語法改一下應該就有結果

SELECT MAX(ID)+1FROM XXXX
INSET INTO....................

然後 用 RS OPEN 去執行 就會返回 SELECT MAX(ID)+1FROM XXXX的結果

但是 你的目的是甚麼??其實 這都不是最安全的方式
最安全的方式 是鎖表把表 LOCK 只有你可以新增 查詢等你做完你要做的別人才可以繼續處理....

yhxhappy 发表于 2018-4-15 09:42:16

本帖最后由 yhxhappy 于 2018-4-15 10:54 编辑

回复 3# kk_lee69

MAX(ID)+1如果ID列会自动叠加(ID int identity(1,1)),再加下这个动作会不会重复?
还有能不能把 这两行合到一行来写。因为我感觉AU3操作SQL,步骤越多出错的机率越多,还要做很多判断。
SELECT MAX(ID)+1FROM XXXX
INSET INTO....................

我目的是想检查刚写入的数据是否写入成功。

比如我写入了一行 123456
为保险起见,再重新读取行数据看是否已存在。但有可能表上以前就写过相同的一行,返回结果不好判断。
所以想通过唯一的 ID 来判断是否成功。

yhxhappy 发表于 2018-4-15 10:51:56

回复 2# 298311657

谢谢提醒,因为对SQL不熟悉没考虑到这些细节。

在 SQL Server Management Studio 中按以下操作可以返回ID:
INSERT "表" ("MODEL") VALUES (115) Select SCOPE_IDENTITY()

主要问题是 RS OPEN 不知道怎么获取它的返回值。

kk_lee69 发表于 2018-4-15 11:25:00

回复 4# yhxhappy

你肯定沒做吧

SELECT MAX(ID)+1FROM XXXX
INSET INTO....................


寫成一行 不就是

SELECT MAX(ID)+1FROM XXXX      INSET INTO....................

你肯定沒實際測試你可以試看看不信那我也沒辦法了

kk_lee69 发表于 2018-4-15 11:30:56

本帖最后由 kk_lee69 于 2018-4-15 11:32 编辑

回复 4# yhxhappy

【我目的是想检查刚写入的数据是否写入成功。

比如我写入了一行 123456
为保险起见,再重新读取行数据看是否已存在。但有可能表上以前就写过相同的一行,返回结果不好判断。
所以想通过唯一的 ID 来判断是否成功。】

你的話 是有 瑕疵
你說 比如我寫入了一行 123456這表示 是資料內容吧而不是 ID
卻又說 可能以前就寫過相同的一行

如果是 這樣以前的 123456 跟現在的123456兩個ID 不會一樣的一樣你無法判斷以前是否寫過...

如果 你的 123456 本身指的就是ID那你又何必要寫入呢??

寫入前先判定ID是否存在就好阿

kk_lee69 发表于 2018-4-15 11:43:28

回复 1# yhxhappy

27 行 改為

$RS.Open(" SELECT MAX(ID)+1 FROM "&$Table &"INSERT " & $Table & " (" & $Field & ") VALUES (" & $ValueText & ") ")

yhxhappy 发表于 2018-4-15 12:11:37

回复 8# kk_lee69


    谢谢帮助,解决了我的问题。
页: [1]
查看完整版本: [已解决] MsSQL 如何在插入行时同时获取自增ID