2016-05-23 13 views
2

Oracle SQLに基づいて、C#で簡単なログイン+登録フォームを作成します。私はOracleのManagedDataAccessクライアント(NuGetから)を使用しています。C#+ OracleSQL - CommandTextでパラメータを使用できません

私はこのようにそれを使用しようとしました:

OracleCommand query = db.CreateCommand(); 
query.CommandText = string.Format("insert into @tablename values(null, '@login', '@pwd', 0, null)"); 
query.Parameters.Add("@tablename", ConfigurationManager.AppSettings.Get("usersTableName")); 
query.Parameters.Add(name: "@login", val: login); 
query.Parameters.Add(name: "@pwd", val: HashPassword(pwd)); 
bool isCreated = (query.ExecuteReader().RecordsAffected > 0 ? true : false); 
query.Dispose(); 
return isCreated; 

^ところで、おそらくそのブール値を作るための別の方法があるはずです。おそらくそれはintそれ自体でboolにキャストします。

構造が非常に簡単です:

"USERS" 
(
"ID" NUMBER(10,0), 
"USERNAME" VARCHAR2(16 BYTE), 
"PASSWORD" VARCHAR2(64 BYTE), 
"IS_LOGGED" NUMBER(1,0), 
"IP" VARCHAR2(15 BYTE) 
) 

コードが失敗したこと。 '@'、コロンなどで試してみました。私がそれを動作させたとしても、 "@login"ユーザ名のレコードが追加されました。文字通り私がパラメータの名前で書いたもの。私が使用した場合

string q = string.Format("insert into {0} values(null, '{1}', '{2}', 0, null)", 
ConfigurationManager.AppSettings.Get("usersTableName"), login, HashPassword(pwd)); 

:また、それは、コードがこのように働い

...(それはそれはしかし、「@tablename」として名を送信し、おそらくです)ORA-00903エラー「無効なテーブル名」と言いますこの文字列は、クエリのCommandTextとして、うまくいきました。私はそれをこのように保つのは嫌いです。特にSQLインジェクションのためです。

私はC#についてはまったく初心者です。そのような短いコードではおそらく多くの間違いを犯しました。

+1

「@login」と「@pwd」速い答えのための – BugFinder

+0

@BugFinderのおかげラウンド引用符を削除することができます!残念ながら、それは必要なように動作しませんでした。今私はORA-00936エラーがある - それは表現がない。 @ loginと@ pwdは文字列なので、私は引用符を保持します。 – Shuji

+0

はい、しかし、パラメータはあなたのためにそれを並べ替える必要があります! https://msdn.microsoft.com/en-us/library/system.data.oracleclient.oraclecommand.parameters(v=vs.110).aspxは、あなたが使用すべきであることを示唆しています:not @ ...おそらくthatsの答え – BugFinder

答えて

0

テーブル名とカラム名をパラメータとして使用することはできません。これは、Oracle SQLパーサがクエリを解析して実行計画を作成することを防止するためです。 クエリテキストに '@tablename'パラメータを使用しました。このパラメータを削除し、たとえば 'usersTableName'で置き換える必要があります。 パラメータ指定子として@を使用することは、Oracleを含むDBMSの.NET環境(C#を含む)でバインドパラメータを定義する正しい方法です。 Oracleでは ':'を使用することも正しいですが、

詳細情報:パフォーマンスを改善し、SQLインジェクションを回避するための推奨されるバインド・パラメータを使用して

。パフォーマンスの向上は、Oracleによる実行計画のキャッシュの結果であり、パラメータはSQL文の構造を変更できません。

0

Oracle SQLでは、表の名前をバインドできません。代わりに、このような何かを(そして、このようにSQLを構築するときに、SQLインジェクションを意識することを忘れないでください)

  OracleCommand query = db.CreateCommand(); 
     query.CommandText = string.Format("insert into " + 
      ConfigurationManager.AppSettings.Get("usersTableName") + 
      " values(null, :login, :pwd, 0, null)"); 
     query.Parameters.Add(":login", login); 
     query.Parameters.Add(":pwd", HashPassword(pwd)); 
     bool isCreated = (query.ExecuteReader().RecordsAffected > 0 ? true : false); 
関連する問題