1

アプリに埋め込まれた derbyDB があり、現在コードをテストしています。

次のSQLコードを送信すると

set current schema  [newSchemaName];

ij から、スキーマと DB からの応答を設定できます

show tables;

以前に識別された newSchemaName に存在するテーブルのみを報告します (ただし、これは常に機能するとは限りません!)

Javaコードから同様のことを行ってから、

getCurrentConection.getSchema();

上記から返された値は、SQL で渡された newSchemaName を決して提案しません (ただし、準備されたステートメントを使用すると、期待どおりに newSchemaName が返されます)。

ここにいくつかの追加の背景情報があります...

デフォルトのデータベース名は「derbyTest」で、他に 3 つのスキーマを作成します。管理者 S1 S2 は、ユーザーが知る必要のない情報をユーザーから論理的に分離/非表示にします

操作中にスキーマを変更する必要があります (例: 管理者は、より「デリケートな」情報を表示する必要がある場合、スキーマを変更します)。

これを行うために、setSchema(String newSchemaName) のメソッドを作成しました。このメソッドは、スキーマを作成し (まだ存在しない場合)、それに接続します。

ただし、コードスニペットを実行した後

/**
*method to change to a given schema
*@param newSchemaName the new schema to change to
/
public void SetSchema(String newSchemaName){

String sql = newSchemaName.toUpperCase();//make sure the newSchemaName is in upper case.

ResultSet rs;
        try
        {
            rs = this.sendQry("select schemaName from sys.sysschemas where schemaname = '" + sql + "'");//does this schema exist in the DB
        if (rs.next()) 
        {//the schema already exists
                //send some messages to the user about the change of schema
            errLog.setDevError(1, "derbyDB schema" +sql +" already exists ");
            errLog.add(2, "connecting to " + sql);
                //next line create the SQL for changing to the newSchemaName supplied
            this.sendSQL("set current schema " + sql);//connect to the schema
                //log a message to display the current schema in the DB
                //this next log never shows a change to the newSchemaName unless
                //I use a prepared statement in my java code.
            errLog.add(1, "current DB schema is " + getCurrentConection.getSchema();
    }
        else{//the schema does not exist
        //send a message to the user and output log
        errLog.setDevError(1, "derbyDB schema" +sql +" does not exist ");
        //code to send message asking if user wants to create the new schema....
        }

}//end try
        catch{
//catch errors


}
}//end method

スキーマを設定するためのドキュメントhttp://db.apache.org/derby/docs/dev/ref/rrefsqlj32268.htmlを見ると、SQL は正しく、ij から直接実行するとコードが機能します。

私は、ij とクライアント側の間にいくつかの違いがあることを知っています (describe などの関数はクライアントでは機能しません。代わりに、メタデータでおならをする必要があります)。

set schema ステートメントの場合も同じですか。それとも、これは私がテストしようとしている準備済みステートメントからのみ機能しますか。

もしそうなら、なぜスキーマを準備済みステートメントからしか変更できないのかという疑問が生じますか?

感想やコメントは大歓迎です。

デビッド

編集: 準備されたステートメントは、スキーマを変更するために機能します。したがって、今残っているのは 2 番目の質問だけです。準備されたステートメントと通常のステートメントの違いはなぜ... Googleの時間だと思いますか?

編集:それが違いを生むかどうかはわかりませんが、私は標準のJDK(6)を使用してWindowsプラットフォームを使用しており、Eclipse内でjUnitテストを実行しているEclipse indigoです。トラブルシューティングに役立つ場合は、opendJDK を使用して Linux (ubuntu) でテストすることもできます。

4

1 に答える 1

0

あなたの質問が何であるかわかりません。

次のように、テーブル参照でスキーマを明示的に指定できます。

SELECT * FROM S1.TABLE_NAME

また

UPDATE S2.TABLE_NAME SET COL1=VALUE1

または、必要に応じて、次のように言ってテーブル参照からスキーマ名を省略できます。

SELECT * FROM TABLE_NAME

また

UPDATE TABLE_NAME SET COL1=VALUE1

その場合、SET SCHEMA ステートメントを発行するか、ログイン時のユーザー名と一致する既存のデフォルト スキーマを使用して、これらのステートメントの暗黙的なスキーマを確立する必要があります。

準備されたステートメントと準備されていないステートメントに関するあなたの質問は、明示的なスキーマを指定しない場合、ステートメントが準備されるときにデフォルトのスキーマ名が確立されるという事実に関係していると思います。

それが私であり、使用しているスキーマを気にかけている場合、すべての SQL ステートメントのすべてのテーブル参照でスキーマを明示的に指定し、いつどのスキーマを使用していたかを確認します。

于 2012-08-15T02:24:21.797 に答える