2009-07-21 19 views
8

Necesito convertir una gran cantidad de consultas SQL en procedimientos almacenados. Tengo un código que actualiza unos 20 o 30 valores a la vez en un procedimiento Delphi. Puedo manejar la creación de procedimientos almacenados para hacer tal cosa. El problema es mi manera de pasar parámetros a los procedimientos almacenados es muy voluminoso como esto:Una mejor forma de pasar parámetros a un 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); 

Tampoco estoy seguro de si eso provoca una pérdida de memoria (es necesario para liberar dichos objetos TParameter?)

¿Alguien tiene una mejor manera de manejar una gran cantidad de parámetros? (No puedo usar una nueva biblioteca. Debo usar ADO, y el SQL que uso es MSSQL) (también, NO estoy usando ADO.net)

Respuesta

11

Esto no causa una pérdida de memoria. stored_procedure limpiará sus parámetros. Se puede confirmar esto con FastMM añadiendo lo siguiente a su .dpr:

ReportMemoryLeaksOnShutdown := True; 

En primer lugar, me gustaría deshacerse de la expresión "with". Puede provocar más problemas y un código menos legible.

Creé un método de ayuda que acepta un procedimiento almacenado, un nombre de parámetro y un valor de parámetro, lo que hará que su código sea más manejable.

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

Hay una :-) respuesta aceptada, pero quiero señalarle a manera más simple y más fácil de definir y utilizar los parámetros con una sola línea:

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

Es muy sencillo y flexible, porque se puede definir los parámetros de entrada y salida con la misma línea.

y desde Delphi ayuda:

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

Esto parece ser una respuesta mejor que la mía. –

+0

No sabía que existía. ¡Gracias por compartir! – robsoft

+0

Gracias Bruce & Rob, esa es la belleza de SO, he aprendido muchas cosas para Delphier aquí, y trato de compartir lo que sé con los demás :-) –

10

ADO creará los parámetros para usted, sólo tiene que llamar Actualizar en los parámetros del objeto:

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

Si algunos parámetros de salida, tendrá que establecerlos explícitamente:

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

Esto es bueno, pero solo funciona si el procedimiento está en la base de datos predeterminada de la conexión. Hay un error en ADO que destruye los parámetros si usa DifferentDatabase.Owner.ProcedureName – DiGi

+1

También he encontrado que .Refresh no siempre funciona, incluso dentro del mismo propietario de la base de datos. No encontré ningún patrón cuando funciona y cuando no funciona, pero cuando no aparece, aparece un error como "Parámetro" @SearchText "no encontrado."cuando uso .ParamByName. Esa misma llamada funciona el 99.9% del tiempo. Agregar parámetros manualmente parece evitar el problema. – Tony

0

Esta es la más corta que conozco:

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

Nota, es necesario asignar el stored_procedure.Connection y llame stored_procedure.Parameters.Refresh; antes de hacer esto

Cuestiones relacionadas