简体   繁体   English

在FROM子句中使用带有参数的存储过程中使用LIKE和%

[英]Using LIKE and % in a stored procedure with parameter in FROM clause

I am creating a web page to host a database. 我正在创建一个托管数据库的网页。

I want this web page to have a search box feature that can update a GridView in visual studio 2017 for tables in SSMS 2014. 我希望这个网页有一个搜索框功能,可以在Visual Studio 2017中为SSMS 2014中的表更新GridView。

I want this GrideView to be dynamic in that a end user could select a table, a column, and then specify a "searchString" to apply to the data in the column. 我希望这个GrideView是动态的,因为最终用户可以选择一个表,一列,然后指定一个“searchString”来应用于列中的数据。

The web page looks like this: 网页看起来像这样:

On to the code. 关于代码。

On the search button click event I want the values in each of the three text boxes to be passed into a stored procedure. 在搜索按钮单击事件上,我希望将三个文本框中的每个文本框中的值传递到存储过程。

Here is the current code for the button click event. 这是按钮点击事件的当前代码。

protected void btnSearch_Click(object sender, EventArgs e)
{
    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["CID1ConnectionString"].ConnectionString))
    {
        SqlDataAdapter searchAdapter = new SqlDataAdapter("Search", con);
        searchAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
        searchAdapter.SelectCommand.Parameters.AddWithValue("@TableName", TableSearchBox.Text.Trim());   // passing text in first text box in
        searchAdapter.SelectCommand.Parameters.AddWithValue("@columnSpecifier", ColumnSearchBox.Text.Trim());   // passing text in second text box in
        searchAdapter.SelectCommand.Parameters.AddWithValue("@searchString", searchStringBox.Text.Trim());   // passing text in third text box in

        DataTable temptable = new DataTable(); //table to have data that satisfies searchString copied to
        searchAdapter.Fill(temptable); //filling table from adapter

        tableDisplay.DataSource = temptable;
        //tableDisplay.Columns[0].Visible = false;
        tableDisplay.DataBind();//bind step
    }
}

Here is my current stored procedure: 这是我当前的存储过程:

ALTER PROCEDURE dbo.Search 
    (@tableName NVARCHAR(50),
     @columnSpecifier NVARCHAR(50),
     @searchString NVARCHAR(50)) 
AS 
     EXEC('SELECT * FROM ' + @tableName + ' WHERE ' + @columnSpecifier + ' LIKE '' + @searchString + %''')

Which is supposed to achieve a query similar to this if the end user populated the first text box with "Basic_Info", the second text box with "Name", and the final text box with "M". 如果最终用户使用“Basic_Info”填充第一个文本框,使用“Name”填充第二个文本框,并使用“M”填充最终文本框,则应该实现与此类似的查询。

SELECT Name 
FROM Basic_Info 
WHERE Name LIKE 'M%'

It appears since I am using a dynamic table name in the FROM clause I need to use dynamic SQL. 因为我在FROM子句中使用动态表名,所以我需要使用动态SQL。 I have put my query in an EXEC block and surrounded my SQL syntax with single quotes ('). 我已将查询放在EXEC块中,并用单引号(')包围我的SQL语法。 These single quotes appear to make using the % operator in my LIKE clause impossible but maybe I'm just not seeing it. 这些单引号似乎在我的LIKE子句中使用%运算符是不可能的,但也许我只是没有看到它。

Is there a way of achieving this functionality? 有没有办法实现这个功能? Should I back up and do this another way? 我应该备份并以另一种方式执行此操作吗? I have read that this might cause SQL injection which sounds like something to be avoided. 我已经读过这可能会导致SQL注入听起来像是要避免的事情。 Any advice is appreciated even about this post and its format. 任何建议甚至赞赏这篇文章及其格式。 This is my first question on stack overflow! 这是我关于堆栈溢出的第一个问题!

EDIT: Turns out the stored procedure and parameter use is unnecessary. 编辑:结果存储过程和参数使用是不必要的。 My final button click event looks like this and just gets the textbox text value to fill out the query. 我的最终按钮单击事件看起来像这样,只是获取文本框文本值来填写查询。

        protected void btnSearch_Click(object sender, EventArgs e)
    {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["CID1ConnectionString"].ConnectionString))
            {
            DataTable temptable = new DataTable(); //table to have data that satisfies searchString copied to
            SqlDataAdapter searchAdapter = new SqlDataAdapter("SELECT * FROM " + TableSearchBox.Text.Trim() + " WHERE " + ColumnSearchBox.Text.Trim() + " LIKE '"  + searchStringBox.Text.Trim() + "%'", con);
            searchAdapter.Fill(temptable); //filling table from adapter
            tableDisplay.DataSource = temptable;
            tableDisplay.DataBind();//bind step
            }
    }

Here's a parameterized dynamic SQL example, using QUOTENAME for identifiers: 这是一个参数化的动态SQL示例,使用QUOTENAME作为标识符:

CREATE PROCEDURE dbo.Search
    @tableName sysname,
    @columnSpecifier sysname,
    @searchString nvarchar(50)
AS
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT * FROM ' + QUOTENAME(@tableName) + N' WHERE ' + QUOTENAME(@columnSpecifier) + N' LIKE @searchString + ''%'';';
EXEC sp_executesql
      @SQL
    , N'@searchString nvarchar(50)'
    , @searchString = @searchString;
GO

I suggest one generally avoid AddWithValue because it infers the SQL database type from the provided .NET type. 我建议通常避免使用AddWithValue,因为它从提供的.NET类型推断出SQL数据库类型。 Although this isn't a concern here because you are using a stored procedure and System.String maps to SQL Server nvarchar , it is best to specify the desired SqlDbType and length (or precision and scale) explicitly. 虽然这不是一个问题,因为您正在使用存储过程并且System.String映射到SQL Server nvarchar ,但最好明确指定所需的SqlDbType和长度(或精度和比例)。 Below is one method to do that. 以下是一种方法。

searchAdapter.SelectCommand.Parameters.Add("@TableName", SqlDbType.NVarChar, 128).Value = TableSearchBox.Text.Trim());   // passing text in first text box in
searchAdapter.SelectCommand.Parameters.Add("@columnSpecifier", SqlDbType.NVarChar, 128).Value = ColumnSearchBox.Text.Trim());   // passing text in second text box in
searchAdapter.SelectCommand.Parameters.Add("@searchString", SqlDbType.NVarChar, 50).Value = searchStringBox.Text.Trim());   // passing text in third text box in

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM