You are on page 1of 6

Ejecutando procedimientos almacenados parametrizados de SQL mediante el proveedor ODBC .NET y Visual C++ .

NET
En este artculo se describe paso a paso cmo llamar a un procedimiento almacenado parametrizado de Microsoft SQL Server mediante el proveedor administrado de Conectividad abierta de bases de datos (ODBC, Open Database Connectivity) .NET y Microsoft Visual C++ .NET. La ejecucin de un procedimiento almacenado parametrizado mediante el proveedor ODBC .NET es ligeramente distinta de la ejecucin del mismo procedimiento con el proveedor de datos OLE DB o SQL Server .NET. Por ejemplo, con el proveedor ODBC .NET es necesario usar la sintaxis de CALL de ODBC para llamar al procedimiento almacenado, en lugar de usar el nombre del procedimiento. Para obtener informacin adicional acerca de la sintaxis de CALL de ODBC, consulte la pgina "Procedure Calls" en la referencia para el programador de ODBC en MSDN Library.

Ejemplos de sintaxis de llamada


A continuacin se muestra un ejemplo de la sintaxis de CALL para un procedimiento almacenado real de la base de datos de ejemplo Northwind que espera un parmetro de entrada:

{CALL CustOrderHist (?)}


He aqu un ejemplo de la sintaxis de CALL para un procedimiento almacenado que espera un parmetro de entrada y devuelve un parmetro de salida y un valor de retorno. El primer marcador de posicin representa el valor de retorno:

{? = CALL Procedure1 (?, ?)


El proveedor administrado ODBC .NET, al igual que el proveedor de datos OLE DB .NET, procesa los parmetros segn su posicin ordinal (que comienza en cero) y no por su nombre.

Proyecto de prueba: parmetro de entrada nico


Si an no lo ha hecho, descargue e instale el proveedor administrado ODBC .NET. NOTA: puede descargar el proveedor administrado ODBC .NET del siguiente sitio Web de Microsoft: http://www.microsoft.com/data/ En Microsoft Visual Studio .NET, cree una nueva aplicacin de C++ administrado con Microsoft Visual C++. En el Explorador de soluciones, haga doble clic en el archivo de origen (.cpp). Quite el cdigo predeterminado del archivo de origen y pegue el cdigo siguiente:

#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> #using <system.xml.dll> using namespace System::Xml; #using <system.dll> using namespace System; #using <system.data.dll> using namespace System::Data; #using <Microsoft.Data.Odbc.dll> using namespace Microsoft::Data::Odbc;

// This is the entry point for this application

int _tmain(void) {

OdbcConnection *myCon = new OdbcConnection("Driver={Sql Server};server=mySQL;trusted_connection=yes;database=northwind;"); try{ myCon->Open(); OdbcCommand *myCmd = new OdbcCommand("{call CustOrderHist(?)}",myCon);

//The following does not work: //OdbcCommand *myCmd = new OdbcCommand("CustOrderHist",myCon); //myCmd->CommandType=CommandType::StoredProcedure;

myCmd->Parameters->Add("CustId",OdbcType::Char,5); myCmd->Parameters->Item[0]->Value=S"ALFKI"; OdbcDataReader *myReader = myCmd->ExecuteReader();

while (myReader->Read()) { for(Int32 i=0;i<myReader->FieldCount;i++) { Console::WriteLine("{0}:{1}",(myReader->GetName(i))->ToString(),(myReader->GetValue(i))->ToString()); } Console::WriteLine(); }

myReader->Close(); }

catch(OdbcException *myEx) { for (int i=0;i<myEx->Errors->Count;i++) { Console::WriteLine("Source:{0};Message={1}",myEx->Errors->Item[i]->Source,myEx->Errors->Item[i]->Message); } } myCon->Close(); return 0; }

Cambie la cadena de conexin como corresponda. Presione CTRL+F5 para compilar y ejecutar el proyecto. Resultado: Este cdigo llama al procedimiento almacenado CustOrderHist, pasa el identificador de cliente como nico parmetro de entrada y devuelve un conjunto de resultados. En la ventana de resultados debe ver la lista de productos ordenados por el cliente de Northwind ALFKI.

Proyecto de prueba: varios tipos de parmetros


El procedimiento almacenado siguiente acepta un identificador de cliente como parmetro de entrada y devuelve: Una lista con los pedidos realizados por el cliente.

El cargo promedio por pedido abonado por el cliente como parmetro de salida. El nmero de pedidos realizados por el cliente como valor de retorno.

En el Analizador de consultas, cree el procedimiento almacenado siguiente en la base de datos de ejemplo Northwind.

CREATE PROCEDURE MultiParamSP @CustID CHAR(5), @AvgFreight MONEY OUTPUT AS SELECT @AvgFreight = AVG(Freight) FROM Orders WHERE CustomerID = @CustID SELECT * FROM Orders WHERE CustomerID = @CustID RETURN @@ROWCOUNT

Repita los pasos 2 a 5 de la seccin "Parmetro de entrada nico" de este artculo, pero con el cdigo siguiente:
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> #using <system.xml.dll> using namespace System::Xml; #using <system.dll> using namespace System; #using <system.data.dll> using namespace System::Data; #using <Microsoft.Data.Odbc.dll> using namespace Microsoft::Data::Odbc;

// This is the entry point for this application int _tmain(void) { OdbcConnection *myCon = new OdbcConnection("Driver={Sql Server};server=mySQL;trusted_connection=yes;database=northwind;");

try{ myCon->Open(); OdbcCommand *myCmd = new OdbcCommand("{?=call MultiParamSP(?,?)}",myCon); myCmd->Parameters->Add("RetVal",OdbcType::Int); myCmd->Parameters->Item[0]->Direction=ParameterDirection::ReturnValue; myCmd->Parameters->Add("CustId",OdbcType::Char,5); myCmd->Parameters->Item[1]->Value=S"ALFKI"; myCmd->Parameters->Add("AvgFr",OdbcType::Double); myCmd->Parameters->Item[2]->Direction=ParameterDirection::Output; //The following does not work: //OdbcCommand *myCmd = new OdbcCommand("MultiParamSP",myCon); //myCmd->CommandType=CommandType::StoredProcedure;

OdbcDataReader *myReader = myCmd->ExecuteReader(); while (myReader->Read()) { Console::WriteLine(); for(Int32 i=0;i<myReader->FieldCount;i++) { Console::WriteLine("{0}:{1}",(myReader->GetName(i))->ToString(),(myReader->GetValue(i))->ToString()); } } myReader->Close(); Console::WriteLine("OutputParamVal={0};ReturnVal={1}",myCmd->Parameters->Item[2]->Value,myCmd>Parameters->Item[0]->Value); } catch(OdbcException *myEx) { for (int i=0;i<myEx->Errors->Count;i++) {

Console::WriteLine("Source:{0};Message={1}",myEx->Errors->Item[i]->Source,myEx->Errors->Item[i]->Message); } } catch(System::Exception *myEx) { Console::WriteLine("Source:{0};Message={1}",myEx->Source,myEx->Message); } myCon->Close(); return 0; }

Resultado: El cdigo llama al procedimiento almacenado MultiParamSP, creado en la seccin "Parmetro de entrada nico", pasa el identificador de cliente como nico parmetro de entrada y devuelve un conjunto de resultados, un parmetro de salida y un valor de retorno. En la ventana de resultados debe ver la lista de pedidos realizados por el cliente de Northwind ALFKI, el cargo promedio que el cliente pag por cada pedido y el nmero de pedidos.

Solucionar problemas
Con el proveedor administrado ODBC .NET no puede usar la sintaxis de ADO que normalmente se utiliza para llamar a los procedimientos almacenados; por lo general, slo se especifica el nombre del procedimiento como CommandText. Con el controlador de SQL Server, cuando un procedimiento almacenado devuelve un conjunto de resultados, los parmetros de salida y el valor de retorno no estn disponibles hasta que se ha tenido acceso al conjunto de resultados y se ha cerrado. Por ejemplo, si omite la lnea

dr.Close()
del segundo ejemplo de cdigo, no podr recuperar los valores del parmetro de salida ni el valor de retorno. El proveedor administrado ODBC .NET, al igual que el proveedor OLE DB .NET, procesa los parmetros segn su posicin ordinal (que comienza en cero) y no por su nombre. El proveedor administrado ODBC .NET no est incluido en Visual Studio .NET; es necesario descargarlo por separado.

REFERENCIAS
Para obtener informacin adicional, consulte la documentacin de referencia del proveedor de datos ODBC .NET incluida con este producto y la pgina "Procedure Calls" de la referencia del programador de MSDN Library: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcprocedure_calls.asp.

You might also like