簡體   English   中英

從插入語句返回(自身)生成的值(無id,無返回)

[英]Return (self) generated value from insert statement (no id, no returning)

抱歉,如果問題標題具有誤導性或不夠准確,但我看不到如何用一句話問。

假設我們有一個表,其中PK是一個字符串(數字從'100,000'到'999,999',逗號僅用於可讀性)。 也可以說,PK不是順序使用的。

現在,我想使用java.sql在表中插入新行,並向用戶顯示插入行的PK。 由於默認情況下不生成PK(例如,沒有PK的插入值不起作用,因此在給定環境中無法使用諸如generate_keys之類的東西),我已經看到了兩種不同的方法:

在兩個不同的語句中,首先找到一個可能的下一個鍵,然后嘗試插入(並期望另一個事務在兩個語句之間的時間中使用相同的鍵)-重試直到成功是否有效,或者是否有任何SQL技巧可以通過事務執行-設置/鎖定在這里有幫助嗎? 我如何在java.sql中實現呢?

對我來說,這是一個令人失望的解決方案,因為它具有不確定性(也許您可以說服我相反),所以我搜索了另一個:

用嵌套的select語句插入,以查找下一個可能的PK。 在我自己生成PK的同時查找其他答案,我使用該語句接近了一個可行的解決方案(省略了從字符串到整數的轉換):

INSERT INTO mytable (pk,othercolumns)
VALUES(
(SELECT MIN(empty_numbers.empty_number) 
  FROM (SELECT t1.pk + 1 as empty_number 
    FROM mytable t1

    LEFT OUTER JOIN mytable t2
    ON t1.pk + 1  = t2.pk

    WHERE t2.pk IS NULL
    AND t1.pk > 100000)
  as empty_numbers),
 othervalues);

與我的第一種方法類似,它的工作原理很吸引人,並且(afaik)提供了更可預測和更穩定的解決方案,但是:如何從該語句中檢索生成的PK? 我讀過沒有辦法直接返回插入的行(或任何列),並且我發現的大多數google結果都指向返回生成的鍵-即使我的鍵是生成的,也不是由DBMS生成的直接,但根據我的陳述。

注意,開發中使用的DBMS是MSSQL 2008,生產系統當前是AS / 400上的DB2(不知道哪個版本),因此我必須遵守SQL標准。 我不能以任何方式更改數據庫結構(例如,使用生成的鍵,我不確定存儲過程)。

DB2 for i允許生成鍵,存儲過程,用戶定義的函數-SQL Server幾乎可以做的所有事情。 確切的實現有所不同,但是那是手冊的目的:-)詢問您的管理員他們正在運行的IBM i版本,然后查閱信息中心以獲取詳細信息。

約束因素是您不能更改數據庫設計;它不能更改數據庫設計。 您似乎在嘗試在插入現有鍵空間中的“空洞”時進行插入的多個進程中陷入困境。 這是一個很難克服的難題。 因為您不能更改數據庫設計,所以除了允許和處理PK沖突之外,沒有其他事情要做。 沒有SQL技巧會有所幫助-SQL方法是讓數據庫生成PK,而不是應用程序。

如果允許某些更改,則有幾種建議。 所有人都有需要解決的問題,但是由於應用程序設計,在這一點上這是不可避免的。

  1. 創建所有INSERT客戶端用來檢索下一個可用PK的UDF。 使用“可用數字”表並在發布時將其刪除。
  2. 預插入所有可用數字。 強制客戶端執行UPDATE。 使它們在FETCH ... FOR UPDATE位置(其余數據=未填充)。 這將鎖定行,避免沖突,並使PK立即可用。
  3. 保持數據庫和其他使用該表的應用程序的狀態不變,但是INSERT流程將從為您使用而預留的一組鍵中提取。 將下一個可用數字保留在SQL SEQUENCE或IBM i數據區域中。 這僅在鍵空間中有一個尚未使用的非常大的孔時才有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM