次のコードでエラーが発生します ( MessageBox.Show()
catch ブロックの から取得します)。
「PopulateBla() の例外: ファイル共有違反があります。別のプロセスがファイルを使用している可能性があります [,,,,,,]
コード
using (SqlCeCommand cmd = new SqlCeCommand(SQL_GET_VENDOR_ITEMS, new SqlCeConnection(SQLCE_CONN_STR)))
{
cmd.Parameters.Add("@VendorID", SqlDbType.NVarChar, 10).Value = vendorId;
cmd.Parameters.Add("@VendorItemID", SqlDbType.NVarChar, 19).Value = vendorItemId;
try
{
cmd.Connection.Open();
using (SqlCeDataReader SQLCEReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (SQLCEReader.Read())
{
itemID = SQLCEReader.GetString(ITEMID_INDEX);
packSize = SQLCEReader.GetString(PACKSIZE_INDEX);
recordFound = true;
}
}
}
catch (SqlCeException err)
{
MessageBox.Show(string.Format("Exception in PopulateControlsIfVendorItemsFound: {0}\r\n", err.Message));//TODO: Remove
}
finally
{
if (cmd.Connection.State == ConnectionState.Open)
{
cmd.Connection.Close();
}
}
}
SQL_GET_VENDOR_ITEMS
私のクエリ文字列です。
ここでどのようなファイル共有の問題が発生している可能性がありますか?
アップデート
これは、以下の ctacke が推奨するそのようなリファクタリングを困難にする種類のコードです。
public void setINVQueryItemGroup( string ID )
{
try
{
dynSQL += " INNER JOIN td_item_group ON t_inv.id = td_item_group.id AND t_inv.pack_size = td_item_group.pack_size WHERE td_item_group.item_group_id = '" + ID + "'";
}
catch( Exception ex )
{
CCR.ExceptionHandler( ex, "InvFile.setINVQueryDept" );
}
}
SQL ステートメントは別のメソッドを使用して追加され、グローバル変数 (dynSQL) を変更しながら、SQL インジェクションを許可する可能性があります (ID がどこにどのように割り当てられるかによって異なります)。それでも十分でない場合、スローされた例外は、それが別のメソッドで発生したことを示しているため、疲れたバグハンターを誤解させる可能性があります (間違いなく、不注意なコピー アンド ペースト操作の犠牲者です)。
これは「コーディングホラー」に値する。わずか数行のコードで無視できるベスト プラクティスはいくつありますか?
別の例を次に示します。
string dynSQL = "SELECT * FROM purgatory WHERE vendor_item = '" + VendorItem + "' ";
if (vendor_id != "")
{
dynSQL += "AND vendor_id = '" + vendor_id + "' ";
}
args を "?" に置き換えることで実行できますが、割り当てるパラメーターを決定するコードは、Joe Garagiola の平均的なクリートよりも 42 倍醜いものになります。