2012-08-03 26 views
7

He creado una función en SQL, ahora necesito usar esa función en mi aplicación C#.¿Cómo puedo llamar a una función de SQL en C#?

He intentado utilizar algo como esto, pero parece que estoy haciendo mal, ya que estoy recibiendo:

Must declare the scalar value '@2064734117' 

... cuando doy 2064734117 como primer parámetro y 1 como el segundo parámetro . Aquí está el código que estoy hablando:

SqlConnection con = new SqlConnection(clsDb.connectionString); 
string query = string.Format("select Function1(@{0},@{1}) ", 
    int.Parse(e.CurrentRow.Cells["CodeMeli"].Value.ToString()),1); 
con.Open(); 
SqlCommand cmd = new SqlCommand(query,con); 
SqlDataAdapter READER = new SqlDataAdapter(); 
READER.SelectCommand = cmd; 
DataTable table = new DataTable(); 
READER.Fill(table); 
radGridView1.DataSource = table; 
con.Close(); 

Y mi función toma dos parámetros enteros y devuelve una tabla. Lo comprobé en Visual Studio y funcionó, pero no pude hacerlo funcionar en mi aplicación.

y esta es mi declaración de la función:

ALTER FUNCTION dbo.Function1 
(
/* 
@parameter1 int = 5, 
@parameter2 datatype 
*/ 
@ID int, 
@clsTypeID int 
) 
    RETURNS TABLE/* @table_variable TABLE (column1 datatype, column2 datatype) */ 
    AS 
     /*BEGIN */ 
    /* INSERT INTO @table_variable 
     SELECT ... FROM ... */ 
RETURN SELECT * FROM tblCLASS2 
     WHERE STNID = @ID AND CLASSTYPEID = @clsTypeID 
/*END */ 
/*GO*/ 
+1

Qué errores te va? También una opción es escribir un procedimiento almacenado que llame a su función y simplemente llamar al proceso a través de ado.net/c# – kd7

+0

Este código debería funcionar, ¿qué error está dando? Tenga en cuenta que esta función * no parece * una función, sino que se implementaría mejor en un 'procedimiento almacenado'. Sin embargo, debería funcionar de cualquier manera. –

+0

obtengo un "Debe declarar el valor escalar '@ 2064734117'". cuando doy 2064734117 como el primer parámetro y 1 como el segundo parámetro. – Breeze

Respuesta

11

Su SQL es un poco fuera, debería ser:

string query = string.Format("select * from dbo.Function1({0},{1});", int.Parse(e.CurrentRow.Cells["CodeMeli"].Value.ToString()),1); 

Es posible que desee utilizar SqlParameter-objetos para evitar las inyecciones SQL:

string query = "select * from dbo.Function1(@pa1,@par2);"; 
    cmd.Parameters.Add("@par1", SqlDbType.Int).Value = int.Parse(e.CurrentRow.Cells["CodeMeli"].Value.ToString()); 
    cmd.Parameters.Add("@par2", SqlDbType.Int).Value = 1; 
1

se puede hacer algo como esto:

 myConn.Open(); 

     //generating the new command for our database 
     SqlCommand cmd = new SqlCommand(); 
     cmd.CommandType = CommandType.Text; 
     cmd.CommandText = "SELECT OBJECTID_1, NDNT as theAddress, MIN(ABS(x - " + double.Parse(x.ToString()) + ") + ABS(y - " + double.Parse(y.ToString()) +")) from dbo.DWH_OUTPUT GROUP BY OBJECTID_1,NDNT HAVING (MIN(ABS(x - " + double.Parse(x.ToString()) + ") + ABS(y - " + double.Parse(y.ToString()) + ")) = (Select MIN(ABS(a.x - " + double.Parse(x.ToString()) + ") + ABS(a.y - " + double.Parse(y.ToString()) + ")) from dbo.DWH_OUTPUT a))"; 
     cmd.Connection = myConn; 

     //getting some more ado.net objects 
     SqlDataAdapter da = new SqlDataAdapter(); 
     DataSet ds = new DataSet(); 

     da.SelectCommand = cmd; 
     da.Fill(ds, @"Addresses"); 

     if (ds.Tables[0].Rows.Count > 0) 
     { 
      theAddress = ds.Tables[0].Rows[0][@"theAddress"] + @" (proximity address)"; 
     } 

     myConn.Close(); 

Nota cómo en este ejemplo, se establece CommandType del SqlCommand para CommandType.Text. Especifique sus parámetros de comando (es decir, la función de selección en su fragmento de código) y luego rellene el conjunto de datos con el método Fill. Luego puede extraer los valores de las filas como lo haría normalmente con ado.net estándar.

Si es necesario llamar a un procedimiento almacenado, echar un vistazo a esto:

How do I call a TSQL function from ado.net

3

A primera vista, lo primero que veo es que no se está especificando el objeto propietario/esquema ; eso es necesario para las funciones, por lo que debe ser select dbo.Function1(...

Segundo: vea lo que genera su llamada a string.Format; que está generando @1 y @n para n otro entero, pero que no es un nombre de parámetro válido. Que es muy útil, porque

Tercero: no agregó ningún parámetro

Cuarto: para una UDF de tabla (en lugar de una UDF escalar), debe select * from dbo.Function1(..., no sólo select dbo.Function1(...

Cuestiones relacionadas