SQL Server查询问题

时间:2011-12-20 06:46:30

标签: sql sql-server sql-server-2008

我试图在事务中实现类似下面的sql语句。任何人都可以建议我如何做到这一点?最重要的是,不应该有任何脏读或写。谢谢!

UPDATE items SET assigned = 1 
WHERE 
    SELECT TOP 1 @item_no = item_no
    FROM items
    WHERE item_code = @item_code 
    AND store_id = @store_id

UPDATE parts SET issued = 1 
WHERE 
    SELECT TOP 1 @part_no = part_no 
    FROM parts
    WHERE part_id = part_id 

INSERT INTO issued_hardware (@item_no, @part_no, DateTime.now, @username);

4 个答案:

答案 0 :(得分:2)

您只需启用适当的隔离级别,并将查询封装在BEGIN TRAN identifierCOMMIT TRAN identifier中。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRAN T1;
UPDATE items SET assigned = 1 
WHERE 
    SELECT TOP 1 @item_no = item_no
    FROM items
    WHERE item_code = @item_code 
    AND store_id = @store_id;

UPDATE parts SET issued = 1 
WHERE 
    SELECT TOP 1 @part_no = part_no 
    FROM parts
    WHERE part_id = part_id;

INSERT INTO issued_hardware (@item_no, @part_no, DateTime.now, @username);
COMMIT TRAN T1;

答案 1 :(得分:1)

问题不明确,但我会尽力回答。

您只是尝试在

之间构建查询
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN

your query here

COMMIT

并且不要忘记使用圆括号或其他内容构建子查询 - 因为您的查询在语法上不正确

特别是 - 如果你想从你的transaciton中的其他transactioned数据脏读 - 使用表与(nolock)postfix

答案 2 :(得分:0)

请提供更多详情。你使用什么编程语言?连接数据库的组件是什么?您是在MS Visual Studio中编写应用程序吗?

或者您只是尝试在单个事务中在脚本中执行所有这些操作?

乍一看,我建议将上面的所有代码放入存储的MSSQL过程中,并从应用程序的代码中调用该过程。这样,您可以提交或还原整个事务,并将逻辑保存在数据库中的一个位置。此外,在SQL中修改过程并在之后保留比在需要重新编译的应用程序中更容易。

答案 3 :(得分:0)

正如其他人所提到的,您使用事务及其隔离状态来控制Dirty Reads。我建议不要这样做,因为这意味着你可以读取一个可能失败的未提交的事务,这可能导致难以追查的竞争条件。

此外,由于您正在进行更多的数据修改,因此您应该明确地回滚您的事务。最后你的SQL需要修复。利用输出子句可能是一个好主意。

BEGIN TRANSACTION;

BEGIN TRY


     DECLARE @Item table (item_no int )
     DECLARE @part table (part_no int)

     UPDATE TOP 1 ITEMS 
     SET assigned = 1
     WHERE   
            item_code = @item_code 
            AND store_id = @store_id
     OUTPUT
            inserted.item_no 
     INTO @Item 

     UPDATE TOP 1 parts 
     SET issued = 1
     OUTPUT
            inserted.part_no
     INTO @part


     INSERT INTO issued_hardware 
     SELECT item_no, GetDate(), @UserName
     FROM @item, @part;





END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO