2012-08-03 85 views
7

Tôi đã tạo một hàm trong SQL, bây giờ tôi cần sử dụng hàm đó trong ứng dụng C# của tôi.Làm cách nào để gọi hàm SQL trong C#?

tôi đã cố gắng sử dụng một cái gì đó như thế này, nhưng có vẻ như tôi đang làm sai vì tôi nhận được:

Must declare the scalar value '@2064734117' 

... khi tôi đưa ra 2064734117 như tham số đầu tiên và 1 như tham số thứ hai . Đây là mã tôi đang nói về:

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

Và hàm của tôi lấy hai tham số nguyên và trả về bảng. Tôi đã kiểm tra nó trong Visual Studio và nó đã làm việc, nhưng tôi không thể làm cho nó hoạt động trong ứng dụng của tôi.

Và đây là khai báo hàm của tôi:

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

Bạn gặp phải lỗi gì? Ngoài ra, một tùy chọn là viết một thủ tục lưu trữ gọi hàm của bạn và chỉ cần gọi proc qua ado.net/c# – kd7

+0

Mã này sẽ hoạt động, lỗi nào được cung cấp? Lưu ý rằng hàm này không * giống như * một hàm, nó sẽ được triển khai tốt hơn trong một 'thủ tục lưu sẵn'. Tuy nhiên, nó sẽ hoạt động theo một trong hai cách. –

+0

tôi nhận được thông báo "Phải khai báo giá trị vô hướng '@ 2064734117'". khi tôi đưa 2064734117 làm tham số đầu tiên và 1 làm tham số thứ hai. – Breeze

Trả lời

11

SQL của bạn là một chút tắt, nó phải là:

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

Bạn có thể muốn sử dụng các đối tượng SqlParameter để ngăn chặn tiêm 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

Bạn có thể làm một cái gì đó như thế này:

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

Lưu ý cách trong ví dụ này, bạn thiết lập CommandType của SqlCommand để CommandType.Text. Chỉ định các tham số lệnh của bạn (tức là hàm chọn trong đoạn mã của bạn), sau đó điền tập dữ liệu với phương thức Fill. Sau đó, bạn có thể lấy ra các giá trị từ các hàng như bạn thông thường sẽ với tiêu chuẩn ado.net.

Nếu bạn cần phải gọi một proc lưu trữ, có một cái nhìn lúc này:

How do I call a TSQL function from ado.net

3

Trong nháy mắt, điều đầu tiên tôi có thể thấy là bạn không chỉ định đối tượng chủ sở hữu/schema ; đó là bắt buộc đối với các hàm, do đó, cần là select dbo.Function1(...

Thứ hai: hãy xem cuộc gọi của bạn là gì string.Format tạo; tạo ra @1@n cho n một số nguyên khác, nhưng không phải là tên thông số hợp lệ. Đó là tiện dụng, vì

Thứ ba: bạn không thêm bất kỳ thông số

Thứ tư: cho một UDF bảng (chứ không phải là một UDF vô hướng), bạn phải select * from dbo.Function1(..., không chỉ select dbo.Function1(...

Các vấn đề liên quan