2013-05-24 8 views
5

私はファイルとフォルダからデータを収集し、SQLデータベースにアップロードする非常に簡単なスクリプトを作成しました。私は自分の問題がparameterized sqlの問題に関連していると信じていますが、どうやって、なぜか分かりません。ExecuteNonQuery()を使用しているPowershellスクリプトで例外が発生しました "不正な構文が 's'の近くにあります。

私は私は何をする必要があることになっていくつかの文字を防ぐために、SQL文字列を再フォーマットであることを考える。

すべてのヘルプ高く評価しました。あなたが挿入しようとしているものは何でもデータ

INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES ('ATI Te 
chnologies','61.16 MB','39','05/24/2013 21:05:56') 
ATI Technologies   61.16 MB           39 
1 
INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES ('ATIToo 
l','0.00 MB','30','05/24/2013 21:05:56') 
ATITool      0.00 MB           30 
1 
INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES ('Auran' 
,'7,496.04 MB','28','05/24/2013 21:05:56') 
Auran      7,496.04 MB          28 
Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near 
's'. 
Unclosed quotation mark after the character string ')'." 
At line:143 char:25 
+       $Command.ExecuteNonQuery() 
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+ CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
+ FullyQualifiedErrorId : SqlException 
+1

あなたの商品アイテムの中には、名前に一重引用符(アポストロフィ)があります。 –

+0

さて、それは速かった。 ロジャーは間違いなく、時には余分なアポストロフィーがありました。出力が逆転しているためにエラーが表示されませんでした。 私はこの問題を解決するためにreplaceを使用しました。 $ x = $ x.Replace( "'"、 "") 私は心配するはずの文字はありますか?または私の弦をきれいにするためのより良い方法は? 今のところこれが機能します。 –

+1

文字の置き換えはこれまでのところしか得られませんが、欠落している奇妙なエッジケースは常に*あります。あなたが見つけたリンクと私の答えが示すようにparamterizedクエリを使用してください。 – alroc

答えて

6

:ここ

コードです:ここでは
$Command = New-Object System.Data.SQLClient.SQLCommand 
$Command.Connection = $dbConnection 
$Command.CommandText = "INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES ('$i','$items','$temp','$currentDate')" 

$Command.ExecuteNonQuery() 

"INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES ('$i','$items','$temp','$currentDate')" 

が出力されます(私はテストとして、それを使用してSQLコマンド文字列を押し出します) "Auran"レコードの後に​​単一引用符/アポストロフィがある文字列連結を使用してクエリを構築する場合、これは という巨大なリスクであり、SQLインジェクション攻撃を開始します。

作成している文字列をSSMSまたはSQL構文の強調表示が可能な他のツールに貼り付けると、その文字列が表示されます。

あなたがコーディングホラーで見つけた投稿は、正しいアドバイス/答えを与えます - パラメータ化されたクエリを使用すると、これはなくなります。パフォーマンスとセキュリティ上の理由から、最近ではSQL文の文字列連結が推奨されていません。ソースコードとして読みやすくすることは言うまでもありません。

$Command = New-Object System.Data.SQLClient.SQLCommand 
$Command.Connection = $dbConnection 
$Command.CommandText = "INSERT INTO FileSizeTable (FileName,FileSize,FileNameLength,Date) VALUES (@name,@size,@length,@dt)"; 
$Command.Parameters.Add("@name", $i); 
$Command.Parameters.Add("@size", $items); 
$Command.Parameters.Add("@length", $temp); 
$Command.Parameters.Add("@dt", $currentdate); 
$Command.ExecuteNonQuery(); 
+0

は$ Command.CommandTextはまだそのコードブロックにあることを意味しますか? –

+0

スクリプトに関するその他の情報がない場合は、はい。これをループ内で実行している場合は、ループの外に移動し、ここで 'Parameters.Add()'を使用する代わりに、ループの外側に空のパラメータを追加し、その内部に値を設定します。 – alroc

+0

それは多くの意味があります、援助に感謝します。あなたが提供したコードを使用すると、次の例外が発生します。 "変数名 '@ name'は既に宣言されています。"チェックしたところ、@nameのインスタンスが他になく、@ fnameに変更すると同じ結果が得られます。それ以上の援助を感謝します。 –

関連する問題