2013-05-11 39 views
5

を追加するとき、私はこのように私のテーブルを作成したSQL ServerのSQL Serverの無効な列名の文字列値

に新たなんだ:

CREATE TABLE Accidents (
    Id INT NOT NULL PRIMARY KEY IDENTITY, 
    GUID VARCHAR(100), 
    Latitude VARCHAR(100), 
    Longitude VARCHAR(100), 
    PhotoName VARCHAR(100)   
    ) 

と私はデータを挿入するためのWebサービスを作成しましたそのテーブルには次のように表示されます:

SqlConnection con = new SqlConnection(@"workstation id=DatabaseSample.mssql.somee.com;packet size=4096;user id=???;pwd=???;data source=DatabaseSample.mssql.somee.com;persist security info=False;initial catalog=DatabaseSample"); 

    public string addAccidentToDatabase(string GUID, string imageBase64String, string latitude, string longitude, string photoName) 
    { 
     SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES (" 
      + GUID + "," + latitude + "," + longitude + "," + photoName + ")", con); 

     try 
     { 
      con.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
     catch (Exception e) 
     { 
      return e.Message; 
     } 
     finally 
     { 
      con.Close(); 
     } 

     return "succeeded"; 
    } 

すべてのものは、無料のホスティングサーバーにホストされています。

私はVS2010からWebサービスをテストし、すべてのパラメータに数値を渡すと、新しい行がテーブルに正常に追加されます。しかし、私は、例えばサービスに少なくとも1つの文字列、「A」を渡すとき、私はこの結果を得る:

<string xmlns="http://tempuri.org/">Invalid column name 'a'.</string> 

と行が追加されません。なぜ彼は "a"を列名とみなしたのだろうか?誰でも助けることができますか?

+4

なぜ賛成投票ですか?私はちょうど尋ねている: –

+4

+1は、愚かなdownvoteを打ち消す。みんな、これは人々が質問できる場所だと思った?ダウンフォート警察は、通常、月曜日の朝まで出てこない。 –

+1

[間違ったデータタイプを選択すると習慣が悪い](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/12/bad-habits-to-kick-using-the-wrong-data- type.aspx) - あなたは常に最も適切なデータ型を使用する必要があります。したがって、 'GUID'列は' UNIQUEIDENTIFIER'型でなければならず、 'Longitude'や' Latitude'などの数値は 'DECIMAL(16,4)'なのでしょうか?** not ** 'varchar(100) '! –

答えて

7

なぜ彼は "a"を列名とみなしたのだろうか?

これは見難いことではありません。ソフトウェアを開発して展開してはならない。それをテストする必要があります。実行中のコードをクラスメソッドに抽出し、それをあなたのサービスから呼び出します。開発時には、単体テストやコマンドラインプログラムなどからテストしたいメソッドを呼び出します。

問題:クエリで文字列(または必要に応じてvarchars)を引用符で囲まないでください。たとえば、クエリー文字列をコンソールに出力しただけの場合は、これを見たことがあります。

しかし、正直言ってそれはあなたの問題の中では最少です。あなたはSQLを手作業で行うべきではありません。少なくともパラメータ化されたクエリを使用する。

"INSERT INTO Accidents (GUID, Latitude, Longitude, PhotoName) 
       VALUES (@GUID, @Latitude, @Longitude, @PhotoName)" 

とパラメータバインド:だからあなたのクエリが可能ましょう

cmd.Parameters.AddWithValue("@GUID", GUID); 
... 
+0

あなたはそうです。私はこれを覚えておくべきです。 –

+3

OPが見るのが難しくない場合は、その質問に尋ねられた疑いがあります。偉大な答えが、少し謙虚に。 –

2

あなたは、文字列の前後に引用符を必要とします。値を直接代入するだけなので、SQLはそれらを列として解析しようとしています。

SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName)  
     VALUES ('" + GUID + "','" + latitude + "','" + longitude + "','" + photoName + "')", con); 

ただし、このコードは非常に安全ではありません。 SQLインジェクションは非常に困難です。代わりにパラメータ照会を使用してみてください。

+0

問題を解決していただきありがとうございます。 –

2

GUIDの値がaで始まると推測しています。もしそれが3で始まっていれば、あなたはおそらくもっと面白いものを手に入れます。

文字列として渡すので、引用符でエスケープしないので、エラーが発生します。

SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES (" 
      + "\"" + GUID + "\"," + latitude + "," + longitude + ",\"" + photoName + "\")", con); 

いくつかのポイント:

  1. あなたは本当にこの方法でクエリを構築することは避けてください。ストアドプロシージャまたはパラメータ化クエリを使用します。

  2. なぜ​​をvarchar()として保存していますか?非常にいいGuidデータ型があります。

  3. データ型の後には列名を付けないでください。 、

+0

ポイントをありがとう。 –

1

あなたは文字列に単一引用符を必要とするが

値しかし、私はstrightlyあなたがSQL Parameters here

+0

リンクをありがとう。私はもっ​​と注意する必要があります。 –

4

の使用例をしてください見つけることができます任意のSQLInjections攻撃

を避けるためにSQLParametersを使用することをお勧めいたしますコードをこれに置き換えてください。

SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) " + 
           "VALUES (@guid, @lat, @long, @photo)", con); 
cmd.Parameters.AddWithValue("@guid", GUID); 
cmd.Parameters.AddWithValue("@lat", latitude); 
cmd.Parameters.AddWithValue("@long", longitude); 
cmd.Parameters.AddWithValue("@photo", photoName); 

なぜですか?文字列の中に一重引用符が含まれているとします。
クエリは構文エラーで失敗します。しかし、文字列に止まらないでください。日付と小数はどうですか?データベースのグローバリゼーション設定に合った方法でそれらの書式を設定する必要があります。異なる設定で次の顧客に失敗するだけです。パラメータがあなたのためにこれを解決します。

最悪。仮定そのPhotoNameための入力ボックスで、悪意のあるユーザーが、このような何か:

大きな、大きな問題だ
p1.jpg'); DROP TABLE ACCIDENTS; -- 

- それはSql Injectionと呼ばれ、はい、パラメータはこれを防ぐことができます。機密情報があるデータベースにこのコードを書かないことを本当に願っています。