0

列に格納されている値だけでなく、テーブル名、列名などを置き換えたいので、これを試しました。

    // Can get any string value based on any string key with this function
    public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) {
        String qry = "SELECT :ColOfInterest FROM :TableToQuery WHERE :KeyValColumn = :KeyVal";
        OracleCommand cmd = new OracleCommand(qry, con);
        cmd.CommandType = CommandType.Text;
        OracleParameter opColOfInterest = cmd.Parameters.Add("ColOfInterest", OracleDbType.Varchar2,
          AColumnToReturn, ParameterDirection.Input);
        OracleParameter opTableToQuery = cmd.Parameters.Add("TableToQuery", OracleDbType.Varchar2,
          ATable, ParameterDirection.Input);
        OracleParameter opKeyValColumn = cmd.Parameters.Add("KeyValColumn", OracleDbType.Varchar2,
          AColumnToQuery, ParameterDirection.Input);
        OracleParameter opKeyVal = cmd.Parameters.Add("KeyVal", OracleDbType.Varchar2,
          AKeyVal, ParameterDirection.Input);
        return cmd.ExecuteScalar().ToString();
    }

...しかし、取得します。"ORA-00903 invalid table name"

だから、私はC#の方法でやってみました:

    public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) {
        String qry = String.Format("SELECT {0} FROM {1} WHERE {2} = {3}", AColumnToReturn, ATable, AColumnToQuery, AKeyVal);
        OracleCommand cmd = new OracleCommand(qry, con);
        cmd.CommandType = CommandType.Text;
        return cmd.ExecuteScalar().ToString();
    }

...しかし、それも失敗しました、実際には、"ORA-00904 "WHYAMINOTQUOTINGTHEDOT"."EXE": invalid identifier"

私は間違った木を吠えていますか、それとも単に猫をフィリングするために間違った方法を使用していますか?

昔は、文字列を。(Delphi)のようなもので囲むことにより、DBエンジンに渡すのに安全な文字列を作成できましたQueryStr()。に類似したヘルパー関数はありC#/Oracleますか?

4

1 に答える 1

4

Oracleでは、パラメータを使用してテーブル名と列名を置き換えることはできません。データベースの観点からパラメータ化されたクエリを使用する主な利点の1つは、Oracleがクエリを1回解析し(特にクエリプランを生成)、さまざまなパラメータ値を使用して何度も実行できることです。テーブルまたは列が変更された場合、クエリの新しいハード解析が必要になるため、バインド変数としての資格がなくなります。

解決しようとしている問題についてもう少し説明していただけますか?任意のテーブルの任意の列をクエリできるコードを記述したいのは珍しいようです。これは、通常、同じ基本的な種類のデータを格納するさまざまなテーブルがあることを意味します。この場合、通常はより適切です。データモデルの正規化を再検討することで提供されます。SQLインジェクションの観点から、特定のテーブル名または列名をデータベースに安全に渡すことができるかどうかを判断する場合は、DBMS_ASSERTパッケージALL_TAB_COLUMNSを使用できますが、その時点では、指定されたテーブル名と列名をクエリするだけでよい場合があります。データベースAColumnToReturnに実際に列があるかどうかを確認AColumnToQueryATableます。

于 2012-03-27T22:24:41.077 に答える