次のコードを実行すると、「スカラー変数 "@objString" を宣言する必要があります」というエラーが表示されます。動的 SQL ステートメントをパラメーター化できませんか? これを書くより良い方法はありますか?私はそれを機能させましたが、名前とユーザーIDを動的に挿入する必要がありました。これは、その情報がエンドユーザーのWebページから渡されるため、明らかにセキュリティの問題です。SQL インジェクションの問題を回避するために、これら 2 つの値をパラメーター化したいと考えています。
private void setValue(Object obj, String name)
{
SqlConnection sqlConnection = SQLConnections.GetPortalConnection();
String sqlStatement = String.Empty;
string[] parameterNames;
string[] parameters;
switch (obj.GetType().ToString())
{
case "System.String":
string objString = obj.ToString();
sqlStatement = @"
declare @name nvarchar(" + name.Length + @");
declare @sql nvarchar(4000);
SET @name = '" + name + @"';
SET @sql = 'UPDATE [myoc4Data].[dbo].[users] SET ' + @name + ' = @objString WHERE [UserID] = @userID;'
exec sp_executesql @sql;";
string[] parameterNames = { "@objString", "@userID" };
string[] parameters = { objString, this.userID };
break;
default:
throw new Exception("Person.Portal.UserProfile.setValue: object type not found");
}
SQLConnections.ExecuteNonQuery(sqlStatement, parameterNames, parameters, sqlConnection);
sqlConnection.Close();
}
...
public static void ExecuteNonQuery(String sqlStatement, string[] parameterNames, object[] parameters, SqlConnection sqlConnection)
{
// Parameterized query
try
{
SqlCommand sqlCommand = sqlConnection.CreateCommand();
sqlCommand = new SqlCommand(sqlStatement, sqlConnection);
for (int x = 0; x < parameters.Length; x++)
{
switch (Type.GetTypeCode(parameters[x].GetType()))
{
case TypeCode.DateTime:
sqlCommand.Parameters.Add(parameterNames[x], SqlDbType.DateTime).Value = ((DateTime)parameters[x]).Year < 1753 ? DBNull.Value : parameters[x];
continue;
}
sqlCommand.Parameters.Add(new SqlParameter(parameterNames[x], parameters[x]));
}
sqlCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new System.ArgumentException("Exception: Person: SQLConnections: Could not execute SQL statement: " + ex.Message);
}
}