如何使用StringBuilder编写存储过程?

时间:2017-02-25 06:38:49

标签: c# asp.net sql-server stored-procedures

我使用字符串构建器编写了以下代码。

StringBuilder query = new StringBuilder("select distinct tc.bracode as [Branch Code] ,tc.braname as [Branch Name], tc.collname as [College Name],tu.uniname as University from tblcollegelist tc inner join tbluniversity tu on tc.uniid=tu.uniid where ( ");

for (int i = 0; i < uni.Count; i++)
{
    query.Append("tu.uniname='" + uni[i] + "'");

    if (i < uni.Count - 1)
    {
        query.Append(" or ");
    }
}

query.Append(" ) ");
query.Append(" and ");
query.Append(" ( ");

for (int i = 0; i < branch.Count; i++)
{
    query.Append("tc.braname='" + branch[i] + "'");

    if (i < branch.Count - 1)
    {
       query.Append(" or ");
    }
}

query.Append(" ) ");
query.Append("group by tc.bracode ,tc.braname , tc.collname,tu.uniname");

string sqlquery = query.ToString();

cmd = new SqlCommand(sqlquery, con);

dr = cmd.ExecuteReader();

dt.Load(dr);

dataGridView1.DataSource = dt;

我们可以使用C#中的参数将多个值传递给存储过程吗? 例如: - 从表格中选择*(&#39; India&#39;&#39; USA&#39;&#39; UK&#39;)

此处国家/地区有三个值,如何将这三个值传递给存储过程?

1 个答案:

答案 0 :(得分:0)

您的问题的解决方案不是那么直接,您共享的查询需要进行优化。 首先,您应该使用or子句,而不是使用IN来比较单个列的多个值。使用IN的示例查询如下所示。

SELECT column1, column2 FROM Table1 WHERE column2 IN ('val1','val2','val3')

column2与列表中提供的任何值匹配时,这将返回结果。

要通过存储过程实现此目的,您需要使用名为Table-valued Parameter的功能。

首先,应在数据库中创建一种类型的表,如下所示。

CREATE TYPE dbo.ValueList
AS TABLE
(
    strValue NVARCHAR(50)
);

然后存储过程应该具有此表类型的参数,以便您可以使用它来传递来自IN子句的值。

以下是一个简单的存储过程,它使用表类型作为参数。

CREATE PROCEDURE dbo.SelectToken
    @List AS dbo.ValueList READONLY
AS
BEGIN
    SET NOCOUNT ON;

    SELECT * From Token  WHERE UserId IN (SELECT strValue FROM  @List)
END
GO

此处@List是先前创建的ValueList类型的参数。选择查询使用子查询来检索@List中传递给IN的值。

以下是C#代码,它通过传递Table-Valued参数来调用此存储过程。

public static List<string> GetTokensForUsers(List<string> userIds)
{

   //Prepare table structure to be passed to the command as parameter.
   DataTable tvp = new DataTable();
   var dc = new DataColumn("strValue", typeof(string));
   tvp.Columns.Add(dc);

   //Add values to the table which will be used in the stored proc.
   foreach (var userId in userIds)
   {
       var dr = tvp.NewRow();
       dr["strValue"] = userId;
       tvp.Rows.Add(dr);
   }

   var tokens = new List<string>();

   using (var conn = new SqlConnection("Data Source=MyServer;Initial Catalog=MyDb;user id=username;password=pwd"))
   {
       SqlCommand cmd = new SqlCommand("dbo.SelectToken", conn);
       cmd.CommandType = CommandType.StoredProcedure;
       //Pass table as parametr to the command.
       SqlParameter tvparam = cmd.Parameters.AddWithValue("@List", tvp);
       //Setting Type of the parameter.
       tvparam.SqlDbType = SqlDbType.Structured;
       conn.Open();

       var reader = cmd.ExecuteReader();

       while (reader.Read())
       {
           tokens.Add(reader.GetString(1));
       }

   }
   return tokens;
}

我提供了带有示例用例和代码的解决方案。它可能不适合您的要求,但这可以为您提供有关如何解决问题的指示。