2 Stimmen

Update in einer Firebird Stored Procedure verwenden, aber Daten ändern sich nicht

Ich habe die folgende gespeicherte Prozedur. Ich habe einen Fehler in meinem Code gefunden, der zu fehlerhaften Daten geführt hat. Ich habe diese Prozedur geschrieben, um die Daten zu korrigieren.

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

Ich führe dann die Prozedur von IBExpert aus und übertrage sie. Wenn ich jedoch eine Abfrage in der Tabelle ausführe, zeigt sie, dass die alten Daten noch vorhanden sind. Was übersehe ich?

1voto

Andrej Kirejeŭ Punkte 5231

1) Dose Cnt y Behinderte Variablen NULLs enthalten? Wenn ja, ändern Sie die Bedingung für

if (:cnt IS DISTINCT FROM :disabled) then ...

2) Stellen Sie sicher, dass Sie übergeben. Transaktion nach SP-Lauf.

3) Stellen Sie sicher, dass die Transaktion, für die Sie Daten auswählen, nicht SNAPSHOT Transaktion. Wenn dies der Fall ist, bestätigen Sie die Transaktion und öffnen Sie sie erneut, bevor Sie die SELECT-Abfrage ausführen.

4) Überprüfen Sie die Logik Ihres Verfahrens.

5) Führen Sie Ihre Prozedur in IBExpert's Debugger aus?

1voto

doug Punkte 11

Wenn Sie C# und ado verwenden, ist dieses Snippet sehr nützlich. Unter Firebird 1.5 war der usp UPDATE_stuff ein typischer Update- oder Insert-Typ, den Sie bei MSSQL als selbstverständlich ansehen. Dies ermöglicht es Ihnen, eine Stored Procedure zu verwenden und die Daten tatsächlich zu speichern und wochenlange Zeitverschwendung zu vermeiden. Config.DB4FB.Open ist nur eine verschachtelte Klasse, die eine neue FbConnection mit einem optionalen Verbindungsstring öffnet, denn wenn Sie Firebird verwenden, müssen Sie den ganzen Kummer abstrahieren:)

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();
}

0voto

thegaffney Punkte 340

Müssen Sie die 4 von Ihnen festgelegten Ausgangsvariablen zurückgeben?

Wenn Sie die Rückgabewerte NICHT benötigen, ist dies dasselbe und "sollte" funktionieren

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X