我不斷收到一個例外,內容如下:
“列名無效,‘IBM’。”
錯誤發生在:"' @ticker '"即使@ticker在VALUES. 我懷疑錯誤可能發生在查詢的其他點,但我對 SQL/T-SQL 很陌生,所以我不確定如何找出在哪里。
private string InsertRecord(Indicator indicator)
{
try
{
if (!CheckIfColumnExists(indicator.GetType().Name))
{
AddColumn(indicator.GetType().Name, SqlDbType.Real);
}
const string query = @"
DECLARE @sql nvarchar(max) = '
INSERT INTO ' QUOTENAME(@tableName) '(
' QUOTENAME(@indicator) ', date, ticker)
VALUES(' @indicatorValue ', ' @date ', ' @ticker ')
';
EXEC sp_executesql @sql;
";
//checking if the record is already there
if (!CheckIfRecordExists(indicator))
{
using (SqlConnection conn = new SqlConnection(this.connectionstring))
{
conn.Open();
SqlCommand cmd = new SqlCommand(query , conn);
cmd.Parameters.AddWithValue("@tableName", tableName);
cmd.Parameters.AddWithValue("@indicator", indicator.GetType().Name);
cmd.Parameters.AddWithValue("@indicatorValue", indicator.Value.ToString());
cmd.Parameters.AddWithValue("@date", indicator.Date.ToString("yyyy-MM-dd"));
cmd.Parameters.AddWithValue("@ticker", indicator.Ticker);
var result = cmd.ExecuteNonQuery();
return "New Record Inserted";
}
}
else
{
return "Record Already Exists";
}
}
catch
{
return "Failure Inserting New Record";
}
}
編輯:我接受 CharlieFace 的回答,因為它通過 SQL 注入避免了違規行為,并解釋了 sp_executesql 的必要性。
uj5u.com熱心網友回復:
您應該一直傳入包含資料(而不是列名和表名)的引數sp_executesql
const string query = @"
DECLARE @sql nvarchar(max) = '
INSERT INTO ' QUOTENAME(@tableName) '(
' QUOTENAME(@indicator) ', date, ticker)
VALUES(@indicatorValue, @date, @ticker)
';
EXEC sp_executesql @sql,
N'@indicatorValue nvarchar(100), @date date, @ticker nvarchar(100)',
@indicatorValue,
@date,
@ticker;
";
您還應該將引數作為它們的實際值(日期、整數)而不是ToString. 還要顯式宣告引數型別和長度
// table and column name should be NVARCHAR(128)
cmd.Parameters.Add("@tableName", SqlDbType.NVarchar, 128).Value = tableName;
cmd.Parameters.Add("@indicator", SqlDbType.NVarchar, 128).Value = indicator.GetType().Name;
cmd.Parameters.Add("@indicatorValue", SqlDbType.NVarchar, 100).Value = indicator.Value;
cmd.Parameters.Add("@date", SqlDbType.Date).Value = indicator.Date;
cmd.Parameters.Add("@ticker", SqlDbType.NVarchar, 100).Value = indicator.Ticker;
uj5u.com熱心網友回復:
關注點
您不能使用引數來附加表名和列名的值。相反,需要字串連接,盡管這會導致開放的 SQL 注入攻擊(例如:Bobby Tables)。因此,請確保您已對或 字串連接部分進行了足夠的驗證。
tableName您不需要為
'查詢中的引數附加單引號。這將在根據引數型別SQLCommand附加要查詢的值時自動完成。SQLParameter我認為沒有必要使用
EXEC sp_executesql. 雖然您可以直接執行INSERT查詢。在 StackOverflow 社區中,通常會建議使用
SqlCommand.Add("@Name", SqlDbType).Value并指定引數型別而不是SqlCommand.AddWithValue(). 請參閱我們可以停止使用 AddWithValue() 了嗎?.
總之,你SqlCommand應該是:
string query = @"
INSERT INTO " tableName
"(" indicator.GetType().Name ", date, ticker)"
" VALUES (@indicatorValue, @date, @ticker)";
SqlCommand cmd = new SqlCommand(query , conn);
cmd.Parameters.Add("@indicatorValue", SqlDbType.NVarchar).Value = indicator.Value.ToString();
cmd.Parameters.Add("@date", SqlDbType.NVarchar).Value = indicator.Date.ToString("yyyy-MM-dd");
cmd.Parameters.Add("@ticker", SqlDbType.NVarchar).Value = indicator.Ticker;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/474588.html
