根据字符串值搜索int列

537*_*037 22 c# sql t-sql sql-server sql-server-2014

View_Booking在sql server 2014中有一个View :

bkID    bkSlot    bkStatus
----    ------    --------
2       Lunch     1
4       Lunch     1
6       Dinner    0
7       Lunch     1
Run Code Online (Sandbox Code Playgroud)

在c#中,我使用了gridview并将其bkStatus转换为字符串,如:

<asp:Label ID="lblStatus" Text='<%# (Eval("bkStatus")+"" == "1") ? "Booked" : "Pending" %>'
    ... ></asp:Label>

bkID    bkSlot    bkStatus
----    ------    --------
2       Lunch     Booked
4       Lunch     Booked
6       Dinner    Pending
7       Lunch     Booked
Run Code Online (Sandbox Code Playgroud)

现在我正在使用此查询搜索View:

SELECT * FROM View_Booking 
WHERE CAST(bkID AS NVARCHAR(MAX)) LIKE '%" + keyword + "%' 
OR bkSlot LIKE '%"+keyword+"%' 
OR bkStatus LIKE << ? >>
Run Code Online (Sandbox Code Playgroud)

但是不知道如何搜索bkStatus哪个作为字符串从c#传递,而它是sql中的int

Had*_*adi 12

一些建议

您提供的查询需要优化:

  1. 首先,使用CAST(bkID AS NVARCHAR(MAX))会影响查询的性能,因为它不会使用任何索引,也会强制转换NVARCHAR(MAX)会降低性能.

  2. bkStatus是一个数字列,因此您必须使用=运算符并与数值进行比较,(0 or 1 or ...)所提供的文本值也在asp不在数据库中的标记中定义,因此它们用于应用程序级别而不是数据级别.

  3. 如果你正在使用CAST(bkID AS NVARCHAR(MAX))以搜索bkid包含特定数字列(例如:搜索1- >结果1,10,11,...) ,然后尝试强制转换为特定的大小(例如:CAST(bkID as NVARCHAR(10))

  4. 建议使用参数化查询以获得更好的性能并防止Sql注入攻击.看看@ un-lucky答案

  5. 您可以使用字典对象来存储与关键字相关的ID值

注意:使用CAST和Like将不使用任何索引,此示例基于您的要求(我尝试将我提供的建议与其他建议结合起来)

var dicStatus = new Dictionary<int, string> { 
    { 0, "Pending" }, 
    { 1, "Booked"  },
    { 2, "Cancelled" }
    // ...
};

string querySql = " SELECT * FROM View_Booking" +
                  " WHERE CAST(bkID AS NVARCHAR(10)) LIKE @bkID" + 
                  " OR bkSlot LIKE @bkSlot" +
                  " OR bkStatus = @status";
using (SqlConnection dbConn = new SqlConnection(connectionString))
{
    dbConn.Open();
    using (SqlCommand sqlCommand = new SqlCommand(querySql, dbConn))
    {
        sqlCommand.Parameters.Add("@bkID", SqlDbType.VarChar).value ="%" + keyword + "%";
        sqlCommand.Parameters.Add("@bkSlot", SqlDbType.VarChar).value ="%" + keyword + "%";
        sqlCommand.Parameters.Add("@status", SqlDbType.Int).value = dicStatus.FirstOrDefault(x => x.Value == keyword).Key;
        sqlCommand.ExecuteNonQuery();
     }
}
Run Code Online (Sandbox Code Playgroud)

此外,如果BkID是整数列,则最好使用

sqlCommand.Parameters.Add("@bkID", SqlDbType.Int).value = (Int)keyword ;
Run Code Online (Sandbox Code Playgroud)

参考和有用的链接


suj*_*lil 7

因此,您需要一个搜索框,用户可以在其中搜索bkID,bkSlot或者bkStatus,如果搜索文本是,Booked或者Pending我们必须添加过滤器,bkStatus该过滤器将是数据库中的整数字段.对?我在这里要提到的更多的事情是使用using以及查询的参数化以实现更智能和更安全的执行方式.所以我想建议如下构建和执行查询:

int statusCode = -1;
if(keyword.ToLower() == "booked")
   statusCode = 1;
else if(keyword.ToLower() == "pending")
   statusCode = 0;
string querySql = " SELECT * FROM View_Booking" +
                  " WHERE CAST(bkID AS NVARCHAR(MAX)) LIKE @bkID" + 
                  " OR bkSlot LIKE @bkSlot" +
                  " OR bkStatus = @status";
using (SqlConnection dbConn = new SqlConnection("connectionString here"))
{
    dbConn.Open();
    using (SqlCommand sqlCommand = new SqlCommand(querySql, dbConn))
    {
        sqlCommand.Parameters.Add("@bkID", SqlDbType.VarChar).value ="%" + keyword + "%";
        sqlCommand.Parameters.Add("@bkSlot", SqlDbType.VarChar).value ="%" + keyword + "%";
        sqlCommand.Parameters.Add("@status", SqlDbType.int).value = statusCode;
        sqlCommand.ExecuteNonQuery();
     }
}
Run Code Online (Sandbox Code Playgroud)

请注意以下事项:

  • 如果你想以包括bkStatus过滤器book,Pend等等.然后,你必须使用相应的更改条件.Contains().StartsWith()替代的.ToLower()
  • 初始化statusCode -1以避免bkStatus基于所有其他值的过滤器