在firebird存储过程中使用update但数据不会更改

时间:2011-09-22 03:19:10

标签: stored-procedures firebird

我有以下存储过程。我在代码中发现了一个导致数据错误的错误。我写了这个程序来修复数据。

CREATE OR ALTER PROCEDURE RESET_DISABLED_COUNT 
returns (
    person integer,
    game integer,
    disabled integer,
    cnt integer)
as
begin
  for select gr.person_id, gr.game_id, gr.disableds
  from game_roster gr
  into :person, :game, :disabled
  do begin
    select count(gr.id)
    from game_roster gr
    where gr.disabled_by_id = :person and gr.game_id = :game
    into cnt;

    if (cnt <> disabled) then begin
        update game_roster gr set gr.disableds = :cnt where (gr.person_id = :person) and (gr.game_id = :game);
    end
  end
end

然后我从IBExpert运行该过程并提交。但是,当我在表上运行查询时,它显示旧数据仍然存在。我错过了什么?

3 个答案:

答案 0 :(得分:1)

1) Cnt 已禁用变量是否包含NULL?如果是,请更改

的条件
if (:cnt IS DISTINCT FROM :disabled) then ...

2)确保在SP运行后提交事务。

3)确保您选择数据的交易不是 SNAPSHOT 交易。如果是这样,请在运行SELECT查询之前提交并重新打开它。

4)重新检查程序的逻辑。

5)您是否在IBExpert的调试器中运行程序?

答案 1 :(得分:1)

如果您使用的是C#和ado,这个代码段会很方便。 Firebird 1.5上的Works文件usp UPDATE_stuff是一个典型的更新或插入类型的proc,你认为MSSQL是理所当然的。这将允许您使用存储过程并实际保存数据并节省数周的浪费时间。 Config.DB4FB.Open只是一个嵌套类,用可选的连接字符串打开一个新的FbConnection,如果你使用的是firebird,你需要抽象掉所有的悲伤:)

FbTransaction FTransaction=null;
using (FbConnection conn = Config.DB4FB.Open(ConnectionString))
{
    FbTransactionOptions options = new FbTransactionOptions();
    options.TransactionBehavior = FbTransactionBehavior.NoWait;
    FTransaction = conn.BeginTransaction(options);
    FbCommand cmd = conn.CreateCommand();
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "UPDATE_stuff";
    cmd.Parameters.AddWithValue("KEY", key);
    cmd.Transaction = FTransaction;
    FbDataReader reader = cmd.ExecuteReader()
            while (reader.Read()){}
    FTransaction.Commit();
}

答案 2 :(得分:0)

您需要返回您设置的4个输出变量吗?

如果你不需要返回值,这是同样的事情,“应该”工作

CREATE PROCEDURE RESET_DISABLED_COUNT
AS
declare person integer;
declare game integer;
declare disabled integer;
declare cnt integer;

begin
  for select gr.person_id, gr.game_id, gr.disableds
  from game_roster gr
  into :person, :game, :disabled
  do begin 
    select count(gr.id)
    from game_roster gr
    where gr.disabled_by_id = :person and gr.game_id = :game
    into cnt;
    if (cnt <> disabled) then begin
        update game_roster gr set gr.disableds = :cnt where (gr.person_id = :person) and (gr.game_id = :game);
    end
  end
end