从行中选择一列并将该列更新为另一个值

时间:2015-09-02 19:35:20

标签: sql-server tsql stored-procedures

我正在尝试编写一个存储过程来读取表的特定行中的列,然后使用新值更新该列。原点。退回。

我希望它能锁定其他人的行,直到我完成。这个过程是什么?

我有类似

的东西
CREATE PROCEDURE [dbo].[aptc_Prt_NextDocumentNumberGet] 
    (@_iFormatConfigID INT, @_oNextDocumentNumber FLOAT OUTPUT)
AS
BEGIN
    DECLARE @FrameworkConfig XML

    SET @_oNextDocumentNumber = - 1

    DECLARE @NewNextDocumentID FLOAT

    SELECT  
        @_oNextDocumentNumber = FrameworkConfig.value('(/Parameters/Parameter[@Name="NextDocNo.NextDocumentNumber"])[1]', 'float')
    FROM 
        [ttcPrtFormatConfig] WITH (ROWLOCK)
    WHERE 
        FormatConfigID = @_iFormatConfigID

    -- Select the Next Doc num out of the xml field
    -- increment appropriate control and set output
    IF @_iFormatConfigID IS NOT NULL
    BEGIN
        -- set what will be the "next" doc number after we add this current txn
        IF (ABS(@_oNextDocumentNumber - 99999999999999999) < 0.0001)
        BEGIN
            SELECT @NewNextDocumentID = 1
        END
        ELSE
        BEGIN
            SELECT @NewNextDocumentID = @_oNextDocumentNumber + 1
        END

        UPDATE [ttcPrtFormatConfig]
        WITH (ROWLOCK)

        SET FrameworkConfig.modify('
            replace value of 
                (/Parameters/Parameter[@Name="NextDocNo.NextDocumentNumber"]/text())[1] 
                 with sql:variable("@NewNextDocumentID")')
        WHERE FormatConfigID = @_iFormatConfigID
    END
END

1 个答案:

答案 0 :(得分:1)

这可以让你接近你想要的。

DECLARE @MyValue    INT

--You need a transaction so that the scope of your lock is well defined
BEGIN TRANSACTION
BEGIN TRY

    --Get the value you are interested in, This select will lock the row so other people will not even be able to read it until you are finished!!!!!
    SELECT      @MyValue = MyValue
    FROM        MyTable WITH (UPDLOCK HOLDLOCK) 
    WHERE       MyValue = SomeValue

    --Do your checks and updates.  You can take as long as you like as you are the only person who can do a read or update of this data.
    IF 
    BEGIN
        UPDATE MyTable
    END

--Make sure you commit or rollback! this will release the lock
END TRY
BEGIN CATCH

    --Oh no bad stuff! give up and put it back to how it was
    PRINT ERROR_MESSAGE() + N' Your message here'

    --Check there is a transaction that we can rollback
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END

    --You may want to return some error state and not throw!
    THROW;
    --RETURN -1 --(for example)

END CATCH;

--yay it all worked and your lock will be released
COMMIT

--Do what you like with the old value
RETURN @MyValue