1

このクエリの実行中にエラーが発生しました。列のテキストには一重引用符を含むテキストも含まれている可能性があるためです。エラーなしでこのクエリを使用するにはどうすればよいですか 私のコードは

public bool updateCMStable(int id, string columnName, string columnText)
{
    try
    {
        string sql = "UPDATE  CMStable SET " + columnName + 
                      "='" + columnText + "' WHERE cmsID=" + id;
        int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,
                                          CommandType.Text,
                                          sql);
        if (i > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ee)
    {
        throw ee;
    }
} 
4

6 に答える 6

5

SQL を文字列で構築する代わりに、パラメーター化されたクエリを使用する必要があります。現在のコードは、一重引用符の問題を除けば、SQL インジェクションに対して脆弱です。

パラメーター化できない動的な列名を使用しようとしているという制限がありますが、動的 SQL をより安全な方法で使用することはできます。

このテーマを包括的に扱うには、Erland SommarskogによるThe Curse and Blessings of Dynamic SQL を読むことをお勧めします。

于 2012-07-07T10:39:12.483 に答える
0

エラーは

「文字列またはバイナリデータは切り捨てられます。ステートメントは終了しました。」

このエラーの主な原因は、値を保存しようとしている列の長さが短いことです。列がvarchar(100)型であり、105文字の文字列を保存しようとすると、このエラーが発生します。

于 2012-07-07T10:54:47.070 に答える
0

LinqToSqlを使用します。お願いします.......上記のようにコードを書くことが良い考えではない理由はたくさんあります-セキュリティ、デザイン、健全性...。

Google LinqToSqlと「リポジトリパターン」は、保守可能で有用なデータインタラクションを作成するための基本的な出発点です。

于 2012-07-07T10:54:51.233 に答える
0

コードを修正するには、追加の一重引用符ですべての一重引用符をエスケープします。 ただし、私は Oded に同意します... パラメータ化されたクエリ、またはストアド プロシージャを使用する必要があります。

public bool updateCMStable(int id, string columnName, string columnText) 
{ 
   if(!string.IsNullOrEmpty))
   {
       switch(columnName)
       {
           // TODO: change 50 & 100 to the real sizes of your columns, 
           // and obviously the column names too...
           case "column1":
               if(columnText.Length > 50)
                   columnText = columnText.SubString(0, 50);
               break;
           case "column2":
               if(columnText.Length > 100)
                   columnText = columnText.SubString(0, 100);
               break;
           etc... 
        }
    }
    // replace single quote with double single quotes
    columnText = columnText.Replace("'", "''");
    string sql = string.Format("UPDATE CMStable SET {0} = '{1}' WHERE cmsID={2}", 
        columnName, 
        columnText, 
        id); 
    int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString, CommandType.Text, sql); 
    return (i > 0); 
}

コードに追加の修正を加えました。

  1. true | を返す場合は、if ステートメントの結果を返すだけです。間違い
  2. 単純に catch ブロックで例外をスローする場合は、例外をキャッチする必要はありません
  3. 例外をキャッチする場合は、意味のあることを行い、再スローするか、throw単独で使用するか、スタック トレースをリセットします。使用しないでくださいthrow ee
  4. + 型の連結を文字列.Format に置き換えて読みにくくなった場合。

編集:

渡されるデータの長さが指定された列の長さよりも長いため、投稿したエラーが発生しています。動的 SQL を使用しているため、これを回避する唯一の方法は、case ステートメントを使用することです。各フィールドのサイズは異なる場合もあれば、そうでない場合もありますが、エラーを回避するには、文字列を切り詰める必要があります。すべてのフィールド サイズが同じ場合、case ステートメントは必要ありません。

于 2012-07-07T10:44:21.743 に答える
0
public bool updateCMStable(int id, string columnName, string columnText)
            {
                 try
                {
string sql = "UPDATE  CMStable SET '"+columnName+"' = '"+columnText+"' where cmdID='"+id+"'";
int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,CommandType.Text,sql);
        if (i > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ee)
    {
        throw ee;
    }
} 
于 2013-11-27T17:27:14.587 に答える
0

これを試して:

public bool updateCMStable(int id, string columnName, string columnText)
{
    try
    {
        columnText=columnText.Replace("'","''")
        string sql = "UPDATE  CMStable SET " + columnName + 
                      "='" + columnText + "' WHERE cmsID=" + id;
        int i = SqlHelper.ExecuteNonQuery(Connection.ConnectionString,
                                          CommandType.Text,
                                          sql);
        if (i > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ee)
    {
        throw ee;
    }
} 
于 2012-07-19T11:07:57.673 に答える