質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

3回答

16718閲覧

PreparedStatementで実際に実行されるSQL文を取得したい

kir27

総合スコア13

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

2クリップ

投稿2019/10/12 02:48

編集2019/10/12 04:33

前提・実現したいこと

JavaのPreparedStatementを使用し、OracleDBに対してselect文を実行しています。
その際、setTimestampでSQL原文の?を置換してからexecuteQuery()しているのですが、
実際にDBで実行される(?が置換後)SQL文をコンソールに表示ができません。
上手くコンソールに出力できる方法はありますか?
SQL原文と?の置換する値を別々に取得するしかないのでしょうか?

できればJavaのソースコード内でコンソールに出力させるようにしたいです。
ソースのイメージは以下のようなものです。(実際のSQLはもっと複雑なものになります)

コード

Connection con; // 各種値を設定
ResultSet rs;
String SQL = "select * from TEST_TIME_TABLE where TEST_DATE = ?"
PreparedStatement pst;

// DB接続の各処理を実施

pst = con.prepareStatement(SQL , ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );

pst.setTimestamp(1, "2019-01-01 01:01:01"); // ?を日時情報に置換

rs = pst.executeQuery();

System.out.println("executeSQL:" + ??????); // ここでコンソールに出力させたい

補足情報

Java1.6 Oracle11g

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

文字列として生のSQLを取得することは難しいですが、log4jdbcを使うと簡単にログファイルやコンソールに生のSQLを出力でき、当方でも使っています。mavenプロジェクトにすると設定が楽です。

pom.xml:

xml

1 <dependency> 2 <groupId>org.apache.logging.log4j</groupId> 3 <artifactId>log4j-slf4j-impl</artifactId> 4 <version>${log4j.version}</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.logging.log4j</groupId> 8 <artifactId>log4j-core</artifactId> 9 <version>${log4j.version}</version> 10 </dependency> 11 12 <!-- https://mvnrepository.com/artifact/com.googlecode.log4jdbc/log4jdbc --> 13 <dependency> 14 <groupId>com.googlecode.log4jdbc</groupId> 15 <artifactId>log4jdbc</artifactId> 16 <version>1.2</version> 17 </dependency>

log4j2.xml

XML

1 <Loggers> 2 <Root level="trace"> 3 <AppenderRef ref="console" level="info"/> 4 <AppenderRef ref="file" level="info" /> 5 </Root> 6 7 <!-- log4jdbcによるJDBC自動ログ出力の設定 --> 8 <!-- log4jdbcの詳細設定は log4jdbc.properties --> 9 10 <!-- コネクションの確立/切断 --> 11 <logger name="jdbc.connection" additivity="false" level="off" /> 12 <!-- ResultSet に関する呼び出しを除く全ての JDBC の呼び出し --> 13 <logger name="jdbc.audit" additivity="false" level="off" /> 14 <!-- ResultSet に関する呼び出し --> 15 <logger name="jdbc.resultset" additivity="false" level="off" /> 16 <!-- SQL が実行される直前 --> 17 <logger name="jdbc.sqltiming" additivity="false" level="off" /> 18 <!-- 実行される SQL --> 19 <logger name="jdbc.sqlonly" additivity="true" level="info" /> 20 <!-- log4jdbc 自身のデバッグメッセージ --> 21 <logger name="jdbc.debug" additivity="false" level="off" /> 22 </Loggers>

Java

1 Class.forName("net.sf.log4jdbc.DriverSpy"); 2 connection = DriverManager.getConnection("jdbc:log4jdbc:oracle:thin:@localhost:1521", user, password); 3PreparedStatement select = null; 4 5 // 例: 6 select = connection.prepareStatement( 7 "select nvl(INSTRUCTOR_NAME, NAME) from ON_THE_JOB j" 8 + " left join INSTRUCTOR i on j.INDICATED_BY = i.INSTRUCTOR_ID" 9 + " left join FRESH_PERSON f on j.MODIFIED_BY = f.EMP_CODE" 10 + " where PHASE_NO = ? and EXERCISE_NO = ? and TARGET_NO = ? and TEAM = ? and j.LDF = 0" 11 + " and (INDICATED_BY is not null or MODIFIED_BY is not null)" 12 ); 13 14 select.setInt(1, target.getPhaseNo()); 15 select.setInt(2, target.getExerciseNo()); 16 select.setInt(3, target.getTargetNo()); 17 select.setString(4, target.getTeam()); 18 ResultSet rs = select.executeQuery();

ログ出力例:

2019-10-12 15:42:22.445 | [http-nio-8090-exec-2] | INFO | jdbc.sqlonly | select nvl(INSTRUCTOR_NAME, NAME) from ON_THE_JOB j left join INSTRUCTOR i on j.INDICATED_BY

= i.INSTRUCTOR_ID left join FRESH_PERSON f on j.MODIFIED_BY = f.EMP_CODE where PHASE_NO = 4
and EXERCISE_NO = 0 and TARGET_NO = 16 and TEAM = 'A' and j.LDF = 0 and (INDICATED_BY is not
null or MODIFIED_BY is not null)

投稿2019/10/12 06:55

naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

以下のような記事がありました.
Oracle については書かれていませんが, お試しになっては如何でしょうか.

JDBCでPreparedStatementを利用する際、実際に発行するクエリ文字列を取得する方法

サンプルコードを見れば分かる通り、基本的にjava.util.PreparedStatement#toString()を実行することで、プレースホルダ置換後のクエリ文字列を取得できます。ただし、MySQLの場合は、取得できる文字列に参照情報も含まれる為、純粋にクエリ文字列だけ欲しい場合はcom.mysql.jdbc.PreparedStatement#asSql()を実行する必要があります。

投稿2019/10/12 04:24

編集2019/10/12 04:25
jimbe

総合スコア12648

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kir27

2019/10/12 04:45

ありがとうございます 参考に試してみます
guest

0

質問にCREATE TABLE を追記してください。

コンソールに出力の方法は知りませんが、

DATEは Oracle11.2 SQL 予約語 ですから、テーブル名や列名などには使わないでください。

SQLが実行される時、

SQL

1select * from TEST_TIME_TABLE where DATE型列 = TO_DATE('2019-01-01 01:01:01', 'YYYY-MM-DD HH24:MI:SS') ;

とならないとエラーになるか、パフォーマンスが落ちるかと?

投稿2019/10/12 03:19

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kir27

2019/10/12 04:38

指摘ありがとうございます。 SQLは例として挙げていましたが良くないものでした。 完全なものではないですがコードを一部修正しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問