2009-07-21 17 views
8

Potrzebuję przekonwertować dużą liczbę zapytań SQL do procedur składowanych. Mam pewien kod, który aktualizuje około 20 lub 30 wartości jednocześnie w jednej procedurze Delphi. Potrafię sobie poradzić z tworzeniem procedur przechowywanych w celu zrobienia czegoś takiego. Problemem jest to mój sposób na przekazywanie parametrów do procedur składowanych jest bardzo nieporęczne tak:Lepszy sposób przekazywania parametrów do TADOStoredProc (Delphi)

with stored_procedure do...... 
    Param := Parameters.AddParameter; 
    Param.Name := '@SSN'; 
    Param.Value := edtSSN.text; 

    Param := Parameters.AddParameter; 
    Param.Name := '@FirstName'; 
    Param.Value := edtFirstName.Text; 

    Param := Parameters.AddParameter; 
    Param.Name := '@LastName'; 
    Param.Value := edtLastName.Text; 

    Param := Parameters.AddParameter; 
    Param.Name := '@UserRID'; 
    Param.Value:= GetRIDFromCombo(cbUser); 

ja też nie jestem pewien, czy to powoduje wyciek pamięci (nie jest to konieczne, aby uwolnić takich obiektów TParameter?)

Ktoś ma lepszy sposób obsługi dużej liczby parametrów? (Nie mogę użyć nowej biblioteki, muszę używać ADO, a SQL, którego używam, to MSSQL) (również, NIE używam ADO.net)

Odpowiedz

11

Nie powoduje to przecieku pamięci. stored_procedure wyczyści jej parametry. Można to potwierdzić z FastMM przez dodanie następujących do .dpr:

ReportMemoryLeaksOnShutdown := True; 

Po pierwsze, chciałbym pozbyć się „z” oświadczeniem. Może to prowadzić do większej liczby problemów i mniej czytelnego kodu.

Utworzyłem metodę pomocniczą, która akceptuje procedurę składowaną, nazwę parametru i wartość parametru, co uczyni twój kod łatwiejszym w zarządzaniu.

AddParam(stored_procedure, '@SSN', edtSSN.text); 
AddParam(stored_procedure, '@FirstName', edtFirstName.Text); 
AddParam(stored_procedure, '@LastName', edtLastName.Text); 
AddParam(stored_procedure, '@UserRID', GetRIDFromCombo(cbUser)); 
19

Jest akceptowaną odpowiedź :-), ale chcę wskazać na prostszy i łatwiejszy sposób definiować i wykorzystywać parametry z jednej linii:

stored_procedure.Parameters.CreateParameter('SSN',ftString,pdInput,30,edtSSN.text); 

to proste i elastyczne, ponieważ ciebie może definiować parametry wejściowe i wyjściowe za pomocą tej samej linii.

iz pomocą Delphi:

function CreateParameter(const Name: WideString; DataType: TDataType; 
    Direction: TParameterDirection; Size: Integer; 
    Value: OleVariant): TParameter; 
+2

To wydaje się być lepszą odpowiedź niż moje. –

+0

Nie wiedziałem, że istnieje. Dzięki za udostępnienie! – robsoft

+0

Dzięki Bruce & Rob, To piękno SO, nauczyłem się wielu rzeczy dla Delphiera i próbuję podzielić się tym, co wiem z innymi :-) –

10

ADO stworzy parametry dla Ciebie, wystarczy zadzwonić Refresh na parametry obiektu:

SP.Connection := SqlConnection; // must be done before setting procedure name 
sp.ProcedureName := 'MyStoredProc'; 
sp.Parameters.Refresh; // This will create the parameters for you as defined in SQL Server 
sp.Parameters.ParamByName('@SSN'').Value := SSN; // params now exist 

etc

jeśli parametry są dane wyjściowe, musisz je jawnie ustawić:

sp.Parameters.ParamByName('@ReturnValue').Direction := pdInputOutput; 
+1

To jest miłe, ale działa tylko wtedy, gdy procedura jest w domyślnej bazie danych połączenia. W ADO jest błąd, który niszczy parametry, jeśli używasz DifferentDatabase.Owner.ProcedureName – DiGi

+1

Zauważyłem również, że .Refresh nie zawsze działa, nawet w obrębie tej samej bazy danych. Nie znalazłem żadnego wzorca, kiedy to działa, a kiedy nie, ale kiedy nie pojawia się i błąd nie pojawia się "Parametr" @SearchText."kiedy używam .ParamByName, ta sama rozmowa działa przez 99,9% czasu, a ręczne dodawanie parametrów wydaje się ominąć problem. – Tony

0

Jest to najkrótsza wiem:

stored_procedure.Parameters.ParamByName('@SSN').Value := edtSSN.text; 

Uwaga, trzeba przypisać stored_procedure.Connection i nazywają stored_procedure.Parameters.Refresh; przed wykonaniem tej