2012-11-28 52 views
3

我試圖編寫過程而不直接使用鎖定語句。在存儲過程中更新後選擇

SET TERM^; 
ALTER PROCEDURE PROC_GETSTATUS (
    IDTBL1 Integer) 
RETURNS (
    STATUS Varchar(255)) 
AS 
declare variable t int; 

BEGIN 

    t=gen_id(RPUSING,1); 
    update TBL1 a set a.STATUS=cast('USINGBY' as varchar(255))||cast(:t as varchar(255)) where a.STATUS='free' and a.ID=:IDTBL1 order by a.LASTUPDATED rows 1 to 1; 

    STATUS=cast('USINGBY' as varchar(255))||cast(:t as varchar(255)); 
    SUSPEND; 
    END^ 
SET TERM ;^


GRANT EXECUTE 
ON PROCEDURE PROC_GETSTATUS TO SYSDBA; 

當我從這個喜歡選擇通過查詢數據:

select * from TBL1 a where a.STATUS in (select b.STATUS from PROC_GETSTATUS(1)); 

返回null。但是這個選擇

select * from TBL1 a where a.STATUS like '%USINGBY%' 

在當前事務中返回更新的數據。如何通過在當前事務中選擇一個過程來重寫此查詢?

+0

什麼,當你刪除'SUSPEND'發生,這不是一個可選的存儲過程(或至少:它不應該是),可能現在由於「SUSPEND」而可以選擇的事實是造成這個問題的原因。 –

+0

當我刪除SUSPEND時,我不知道如何使用執行過程語句返回的數據。 (它不可選)。我嘗試在TBL1字段中包含(從TBL1 a中選擇*,其中a.STATUS = ...)並返回,但它也返回null。 –

回答

0

爲什麼不能返回更新記錄的id及其新狀態?

CREATE OR ALTER PROCEDURE PROC_GETSTATUS (
    IDTBL1 INTEGER) 
RETURNS (
    ID INTEGER, 
    STATUS VARCHAR(255)) 
AS 
BEGIN 
    FOR 
    SELECT FIRST 1 a.id 
    FROM tbl1 a 
    WHERE a.status='free' AND a.id=:IDTBL1 
    ORDER BY a.lastupdated 
    INTO :ID 
    DO BEGIN 
    STATUS = 'USINGBY' || gen_id(RPUSING,1); 
    UPDATE tbl1 a SET a.status = :STATUS 
     WHERE a.id = :ID; 
    SUSPEND; 
    END 
END 

然後在查詢中使用它:

SELECT a.*, p.status FROM tbl1 a LEFT JOIN proc_getstatus(1) p ON a.id = p.id 
+0

不,我需要更新之前選擇,因爲如果兩個不同的客戶端首先選擇相同的行,然後其中一個將被其他更新覆蓋。 –

+0

然後在一個事務中將它分爲兩​​個單獨的操作(更新和選擇)。 –

+0

SELECT不會在同一個語句中看到任何更改。 –