我已经发布了这个问题,因为我遇到了“LIKE”语句的问题,但现在我意识到参数化语句存在问题。这是我的代码:
例如我写的时候:
sqlCmd = new SqlCommand(@"SELECT @cusId,@cusName FROM " + form1.getTable() + " WHERE @cusId LIKE @filter", connection);
sqlCmd.Parameters.AddWithValue("cusId", form1.cusId.Text);
sqlCmd.Parameters.AddWithValue("cusName", form1.cusName.Text);
sqlCmd.Parameters.AddWithValue("filter", form1.filterType().Trim() + "%");
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText, connection);
sqlDatAdapter.Fill(datTable);
form1.setDataGrid = datTable;
不知怎的,我总是得到
"Must declare the scalar variable @..."
填写数据表时每个变量的。我已经尝试了
sqlCmd.ExecuteNonQuery();
它似乎在这种情况下工作(当我更新数据库时它工作正常)但我需要将值绑定到我的DataGridView。
编辑:即使我只是尝试写下这样的东西:
... WHERE cusId.Text = @cusId
我得到了同样的错误
答案 0 :(得分:1)
如上所述,您没有正确使用参数。你的SqlCommand应该是这样的:
SqlCommand sqlcmd = new SqlCommand(@"SELECT cusId,cusName FROM " + form1.getTable() + " WHERE cusId LIKE @filter", connection);
请注意您尝试选择的列不是参数(因此不要包含'@'符号)。
添加参数时,需要添加“@”符号。像这样:
sqlCmd.Parameters.AddWithValue("@cusId", form1.cusId.Text);
答案 1 :(得分:0)
您无法参数化您的表名和列名。您只能 参数化您的值。
如果确实想要动态获取您的表名和列名,可以使用dynamic SQL,但这不是一个好主意。
动态获取列名的最佳方法是为列名创建强大的验证或为其创建黑名单。
使用ExecuteNonQuery
不会影响任何内容,因为只是执行查询,不会返回任何数据。还可以使用using
statement来处置您的连接,命令和适配器。
这是一个例子;
string str = string.Format("SELECT {0}, {1} FROM {2} WHERE {0} LIKE @filter",
form1.cusId.Text,
form1.cusName.Text,
form1.getTable());
sqlCmd = new SqlCommand(str, connection);
sqlCmd.Parameters.AddWithValue("@filter", form1.filterType().Trim() + "%");
sqlDatAdapter = new SqlDataAdapter(sqlCmd);
sqlDatAdapter.Fill(datTable);
但是我必须再说一遍,当你尝试将它们放在你的程序之外时,你确实需要强大的验证或列表名称的黑名单。
我在此示例中使用了AddWithValue
,但此方法might be dangerous in some cases。使用.Add()
重载来隐式指定它的db类型和参数大小会更好。
答案 2 :(得分:0)
终于解决了!我试过了:
using (sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText, connection))
{
sqlDatAdapter.SelectCommand.Parameters.Add("@filter", SqlDbType.Int, 25).Value = CusIdEnter;
sqlDatAdapter.Fill(datTable);
form1.setDataGrid = datTable;
}
现在它有效!必须将参数绑定到适配器