我有以下存储过程。我在代码中发现了一个导致数据错误的错误。我写了这个程序来修复数据。
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运行该过程并提交。但是,当我在表上运行查询时,它显示旧数据仍然存在。我错过了什么?
答案 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