質問

列名を参照して、Oracleデータベースと通信するアプリケーションでクエリを注文しようとしています。バインド変数を使用して、クエリの順序を動的に変更できるようにします。

私が抱えている問題は、データベースが列ごとの順序を無視しているように見えることです。

バインド変数を介してデータベース列を参照する特定の方法があるかどうか、またはそれが可能かどうか、誰もが知っていますか?

e.g私のクエリは

SELECT * FROM PERSON ORDER BY :1

:1 PERSON.NAME にバインドされます) クエリは結果をアルファベット順に返していません。データベースがこれを次のように解釈しているのではないかと心配です:-

SELECT * FROM PERSON ORDER BY 'PERSON.NAME' 

これは明らかに動作しません。

どんな提案でも大歓迎です。

役に立ちましたか?

解決

いいえ。テーブル名または列名にバインド変数を使用することはできません。

この情報は、実行計画を作成するために必要です。注文するものがわからない場合、たとえば、どのインデックスを使用するかを判断することは不可能です。

バインド変数の代わりに、プログラムで列名を作成するときに、SQLステートメントに列名を直接挿入する必要があります。 SQLインジェクションに対して予防策を講じていると仮定すると、それに対するマイナス面はありません。

更新:フープをジャンプしたい場合は、おそらく次のようなことができます

order by decode(?, 'colA', colA, 'colB', colB)

しかし、それは馬鹿げています。そして遅い。しないでください。

他のヒント

JDBCを使用している場合。コードをバインド変数なしで何かに書き換えることができます。このようにして、順序を動的に変更することもできます。例:

    String query = "SELECT * FROM PERS ";
    if (condition1){
      query = query+ " order by name ";
    // insert more if/else or case statements
    } else {
      query = query+ " order by other_column ";
    }
    Statement select = conn.createStatement();
    ResultSet result = select.executeQuery(query);

または

    String columnName = getColumnName(input);
    Statement select = conn.createStatement();
    ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName);

ResultSet result = select.executeQuery(" SELECT * FROM PERS ORDER BY" + columnName);

は常にデータベースに対する新しいステートメントになります。つまり、既に説明したティロのように、「再注文」することは不可能です。すでにバインド、計算、準備、解析されたステートメント。この結果セットをアプリケーションで繰り返し使用し、時間の経過とともに変化する唯一のものがプレゼンテーションの順序である場合は、クライアントコードでセットを順序付けてみてください。それ以外の場合、動的SQLは問題ありませんが、フットプリントが大きくなります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top