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

我正在创建一个托管数据库的网页。

我希望这个网页有一个搜索框function,可以在Visual Studio 2017中为SSMS 2014中的表格更新GridView。

我希望这个GrideView是动态的,因为最终用户可以选择一个表,一列,然后指定一个“searchString”来应用于列中的数据。

网页看起来像这样:

关于代码。

在搜索按钮单击事件上,我希望将三个文本框中的每个文本框中的值传递到存储过程。

这是按钮点击事件的当前代码。

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 } } 

这是我当前的存储过程:

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

如果最终用户使用“Basic_Info”填充第一个文本框,使用“Name”填充第二个文本框,并使用“M”填充最终文本框,则应该实现与此类似的查询。

 SELECT Name FROM Basic_Info WHERE Name LIKE 'M%' 

因为我在FROM子句中使用动态表名,所以我需要使用动态SQL。 我已将查询放在EXEC块中,并用单引号(’)包围我的SQL语法。 这些单引号似乎在我的LIKE子句中使用%运算符是不可能的,但也许我只是没有看到它。

有没有办法实现这个function? 我应该备份并以另一种方式执行此操作吗? 我已经读过这可能会导致SQL注入听起来像是要避免的事情。 任何建议甚至赞赏这篇文章及其格式。 这是我关于堆栈溢出的第一个问题!

编辑:结果存储过程和参数使用是不必要的。 我的最终按钮单击事件看起来像这样,只是获取文本框文本值来填写查询。

  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 } } 

这是一个参数化的动态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 

我建议通常避免使用AddWithValue,因为它从提供的.NET类型推断出SQL数据库类型。 虽然这不是一个问题,因为您正在使用存储过程并且System.String映射到SQL Server nvarchar ,但最好明确指定所需的SqlDbType和长度(或精度和比例)。 以下是一种方法。

 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