在 Java 客户端中“即时”更改 derbyDB 架构

Posted

技术标签:

【中文标题】在 Java 客户端中“即时”更改 derbyDB 架构【英文标题】:Changing derbyDB schema 'on the fly' in java client 【发布时间】:2012-08-14 14:39:00 【问题描述】:

我的应用程序中嵌入了 derbyDB,我目前正在测试我的代码。

如果我发送以下 SQL 代码

set current schema  [newSchemaName];

然后我可以从 ij 设置架构和来自数据库的响应

show tables;

将仅报告先前标识的 newSchemaName 中存在的表(尽管这似乎并不总是有效!)

如果我从 java 代码中做类似的事情,然后执行一个

getCurrentConection.getSchema();

从上面返回的值从不建议在 SQL 中传递的 newSchemaName(尽管如果我使用准备好的语句,它会按预期返回 newSchemaName)。

这里有一些额外的背景信息...

我有默认数据库名称“derbyTest”并创建了 3 个其他模式。 行政 S1 S2 从逻辑上分离/隐藏用户不需要知道的信息

我需要在操作期间更改架构(例如:如果需要,管理员将更改架构以查看更多“微妙”信息)。

为此,我为 setSchema(String newSchemaName) 创建了一个方法,该方法会创建架构(如果尚不存在)然后连接到它。

但是运行代码sn-p之后

/**
*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之类的功能在客户端不工作,你需要用元数据来放屁)。

设置模式语句的情况是否相同。或者这仅适用于我即将测试的准备好的语句。

如果这样就引出了一个问题,为什么我只能从准备好的语句中更改架构?

想法和方法被广泛接受。

大卫

编辑: 准备好的语句用于更改架构。所以现在只剩下第二个问题了。为什么准备好的陈述和普通陈述之间的区别......我认为谷歌的时间?

编辑: 我不知道这是否会有所作为,但我在 Windows 平台上,使用标准 JDK (6),并且 eclipse indigo 在 eclipse 中运行 jUnit 测试。如果可能有助于排除故障,我也可以使用 opendJDK 在 Linux(ubuntu) 上进行测试。

【问题讨论】:

所以我刚刚找到了这个链接:allinterview.com/showanswers/102950.html 它解释了一个准备好的语句被预编译到数据库中。很好,但它们通常是为将要被多次调用的语句准备的(因为它们性能更好)。再一次,这很酷。但我不希望有人一直从模式跳到模式(尽管我的代码可能会这样做!)。所以时间方面可能是一个有争议的问题! 【参考方案1】:

我不确定你的问题是什么。

您可以在表引用中明确指定架构,如下所示:

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 语句中的所有表引用中明确指定架构,然后我会确定我什么时候使用的架构。

【讨论】:

确实,我正在明确设置我的架构。我提供的代码 sn-p 在一个名为 changeSchema(String sql) 的方法中。 this.sendSQL("set current schema" + sql) 行发送 SQL 命令来更改架构。然而,错误日志的输出显示我仍在使用原始模式,因此在此模式上的任何后续操作(即插入)都会失败,因为数据库正在查看错误的模式。但是,如果我使用准备好的语句,则更改将发送到数据库。为了清楚起见,我将更新我的问题。 进一步的测试表明,有时一组模式调用会改变模式,有时不会。这很奇怪。当我在 Eclipse 中使用调试视图时,我看到了这一点。有什么想法吗? 请理解:发出“SET SCHEMA”不是我明确设置架构的意思。我的意思是:用它们的模式名称限定所有表名。如果您使用的是“SET SCHEMA”,那么您必须确保在您准备好 SQL 语句之前调用它。而且由于 Derby 将准备好的语句缓存起来,不同的连接将无法使用这种技术使用不同的模式。 @Brayn re 'SET SCHEMA' 好吧,很公平。事实上,我已经修改了我的代码以在方法调用中包含一个“shemaName”字符串。但是,在我上面的代码中,我在处理指定的模式之前确实调用了一个单独的方法,它是发送似乎不会更改模式的“设置模式”SQL 命令。 ij 中的进一步测试也向我建议,这仅“偶尔”有效。我使用 DataBaseMetaData 或 Connection.getSchema() 调用进行测试,在我发送 SET SCHEMA sql 后,它们未能返回反映架构更改的值。您还需要哪些信息来解决问题? 也许 getCurrentConnection().getSchema() 行为不端,并返回缓存的模式值,该值未反映上一条语句的模式更改?

以上是关于在 Java 客户端中“即时”更改 derbyDB 架构的主要内容,如果未能解决你的问题,请参考以下文章

怎样使用openfire实现 Web即时通信

Veeam Backup 11 即时与快速恢复

Veeam Backup 11 即时与快速恢复

java学习之即时通信项目实战

如何在 SELECT 语句中即时更改编码?

Magento 2:如何在 Paypal Express 中即时更改付款方式