我使用INSERT ... SELECT语法从表中选择现有行,然后插入另一个表。除了每行的现有数据外,我还需要添加BillingID和TimeStamp。因为这些字段位于SQL语句的SELECT部分,所以我无法对它们进行参数化。我使用SQL函数NOW()解决了TimeStamp问题,但是我仍然留下了BillingID,我已通过sting concatenation添加到查询中,如下所示:
static void UpdateMonthlyData(int BillingID, DateTime HistoryDate, int CompanyID)
{
String conString = ConfigurationManager.ConnectionStrings["xxx"].ConnectionString;
MySqlConnection connection = new MySqlConnection(conString);
String command = "INSERT INTO MonthlyData SELECT " + BillingID + ", d.*, NOW() "
+ "FROM CurrentData d WHERE d.CompanyID = @CompanyID AND d.HistoryDate = @HistoryDate";
MySqlCommand cmd = new MySqlCommand(command, connection);
cmd.Parameters.Add(new MySqlParameter("@CompanyID", CompanyID));
cmd.Parameters.Add(new MySqlParameter("@HistoryDate", HistoryDate));
cmd.CommandType = CommandType.Text;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
我不关心SQL注入,因为这是一个控制台应用程序,它是按自动计划运行的,并且没有任何用户交互。 (BillingID是自动生成的)。尽管如此,我不喜欢使用连接字符串,因为它们不是很易读。有更优雅的方式吗?
编辑:
总而言之,我认为既然你不能这样做:
SELECT @field FROM @table
我假设在SQL语句的SELECT部分中不允许使用参数。但是因为我在select语句中指定了一个值而不是选择一个列,因为@cdhowie指出我可以在那里使用一个参数。本质上我翻译的查询是这样的:
SELECT 25 FROM table_name, not SELECT field FROM table_name
所以现在感谢@cdhowie我明白参数可以是文字值可以是
的任何地方答案 0 :(得分:3)
查询参数在文字值的任何位置都有效,假设查询参数的类型正确(例如... LIMIT @Foo
只要绑定一个整数就可以工作 - 或者SQL服务器可以成功转换为整数 - 到Foo参数)。假设您正在使用的SQL方言中没有特别的怪癖。
换句话说,您没有理由不能使用查询参数传递BillingID
。
答案 1 :(得分:2)
您可以对任何无法通过参数化添加的安全字段使用String.Format:
String command = String.Format("INSERT INTO MonthlyData SELECT {0}, d.*, NOW() FROM CurrentData d WHERE d.CompanyID = @CompanyID AND d.HistoryDate = @HistoryDate", BillingID);
答案 2 :(得分:2)
您可以使用.Net string.format
示例:
string query = string.format{"insert into MonthlyData select {0} from CurrentData",
BillingId);
您可以使用更干净的代码更多地参数化您的查询。
祝你好运