【问题标题】:C# Alter Table and Add a column programmatically ASP.Net & SQL ServerC# Alter Table 并以编程方式添加列 ASP.Net & SQL Server
【发布时间】:2013-12-21 13:20:54
【问题描述】:

我一直在尝试在 ASP.NET 中以编程方式添加列来修改 SQL Server 中的表。

请看以下代码:

 string suppliernotxt = supplieridlist[1].ToString();
 //SqlCommand cmd2 = new SqlCommand("ALTER TABLE [ProductNormalDB] ADD suppliernotxt nvarchar(20) NULL", con);
 SqlCommand cmd2 = new SqlCommand("ALTER TABLE ProductNormalDB ADD @supplierlist nvarchar(20) NULL", con);
 cmd2.Parameters.AddWithValue("@supplierlist", suppliernotxt);
 //cmd2.Parameters.AddWithValue("@supplierlist", suppliernotxt.ToString());
 //cmd2.Parameters["@supplierlist"].Value = supplieridlist[x];
 cmd2.ExecuteNonQuery();

supplieridlist 是一个数组,它获取所有列名以添加到 SQL Server 数据库中。由于某种原因,参数化方法不起作用并显示以下错误:

“@supplierlist”附近的语法不正确。

基本思想是让用户从复选框中选择供应商的名称,根据选择的供应商数量,数组将为 ex 创建供应商名称。如果我们选择了 3 个供应商,则数组将保存 "Supplier1""Supplier2""Supplier3",然后 SqlCommand 应该会更改表并添加新列。

【问题讨论】:

  • 你应该标准化你的数据库。例如,您可以创建一个多对多表 AsocProductSupplier,其中包含以下列:ProductIDSupplierID

标签: c# asp.net sql-server


【解决方案1】:

您不能使用参数来表示列的名称。
参数只能用于表示 WHERE 子句或 INSERT 或 UPDATE 语句的值。

您可以对查询文本使用字符串连接,将字符串值传递给存储过程或使用某种形式的动态 sql。

请谨慎使用这些方法,因为如果您不对传递给代码的值保持绝对控制,您将面临 Sql Injection。

添加作为动态 SQL 执行的示例,但仍然容易受到 SQL 注入的攻击

string suppliernotxt = supplieridlist[1].ToString();
string execSQL = "DECLARE @sup nvarchar(15); " + 
                 "SET @sup = '" + suppliernotxt + "'; " +
                 "EXEC ('ALTER TABLE ProductNormalDB  ADD ' + @sup + ' nvarchar(20) NULL')"
SqlCommand cmd2 = new SqlCommand(execSQL, con);
cmd2.ExecuteNonQuery();    

如您所见,即使使用动态 SQL,也无法阻止通过 suppliernotxt 变量传递的 SQL 注入攻击

编辑 正如@RBarryYoung 下面的 cmets 中所解释的,对于这种动态 sql 的情况,对 SQL 注入问题的一个很好的改进可能是使用 QUOTENAME function 来获取一个 Unicode 字符串输入字符串周围所需的分隔符

string execSQL = "DECLARE @sup nvarchar(15); " + 
                 "SET @sup = QUOTENAME('" + suppliernotxt + "'); " +
                 "EXEC ('ALTER TABLE ProductNormalDB  ADD ' + @sup + ' nvarchar(20) NULL')"

【讨论】:

  • 我建议在@sup 变量到address the Injection threat 上使用T-SQL QUOTENAME(..) 函数。不能保证(参数化的方式,它适用的地方),但它是下一个最好的事情,这是 MS 针对这种情况推荐的。
  • @RBarryYoung 感谢您的观察。我不知道这种解决方法。那么您建议:"SET @sup = QUOTENAME('" + suppliernotxt + "'); " 还是直接在 ALTER TABLE 语句中?
  • 第一个,在SET 语句中。
  • 恕我直言,SQL 注入修复的优先顺序,1)参数化,总是,2)Whitelisting 参数,当你必须使用动态 SQL 时,3)QUOTENAME 当白名单不能用于参数(如本例所示)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 2022-01-25
  • 1970-01-01
  • 2020-07-09
  • 2018-10-05
  • 2013-11-04
  • 1970-01-01
相关资源
最近更新 更多