0

好的,首先,我是 Caché 的菜鸟,所以代码可能会很差,但是......

我需要能够在 Java 中查询 Caché 数据库,以便从 Studio 中重建源文件。

我可以毫无问题地转储方法等,但是有一件事让我无法理解……出于某种原因,我无法EXTENTQUERYSPEC从类Samples.Person(命名空间:)中转储参数的属性SAMPLES

该课程在 Studio 中如下所示:

Class Sample.Person Extends (%Persistent, %Populate, %XML.Adaptor)
{

Parameter EXTENTQUERYSPEC = "Name,SSN,Home.City,Home.State";

// etc etc
} 

这是程序的代码:

CREATE PROCEDURE CacheQc.getParamDesc(
    IN className VARCHAR(50),
    IN methodName VARCHAR(50),
    OUT description VARCHAR(8192),
    OUT type VARCHAR(50),
    OUT defaultValue VARCHAR(1024)
) RETURNS NUMBER LANGUAGE COS {
    set ref = className _ "||" _ methodName
    set row = ##class(%Dictionary.ParameterDefinition).%OpenId(ref)

    if (row = "") {
        quit 1
    }

    set description = row.Description
    set type = row.Type
    set defaultValue = row.Default

    quit 0
}

和Java代码:

private void getParamDetail(final String className, final String paramName)
    throws SQLException
{
    final String call
        = "{ ? = call CacheQc.getParamDesc(?, ?, ?, ?, ?) }";

    try (
        final CallableStatement statement = connection.prepareCall(call);
    ) {
        statement.registerOutParameter(1, Types.INTEGER);

        statement.setString(2, className);
        statement.setString(3, paramName);

        statement.registerOutParameter(4, Types.VARCHAR);
        statement.registerOutParameter(5, Types.VARCHAR);
        statement.registerOutParameter(6, Types.VARCHAR);

        statement.executeUpdate();

        final int ret = statement.getInt(1);

        // HERE
        if (ret != 0)
            throw new SQLException("failed to read parameter");

        System.out.println("    description: " + statement.getString(4));
        System.out.println("    type       : " + statement.getString(5));
        System.out.println("    default    : " + statement.getString(6));
    }
}

现在,对于前面提到的类/参数对,标记的条件// HERE总是被触发,因此抛出异常......如果我评论整行,那么我看到所有三个OUT参数都是空的,甚至defaultValue

我本来希望后者具有 Studio 中提到的价值......

那么,为什么会发生这种情况?我的程序是否有些损坏?

4

2 回答 2

2

首先,您应该检查您是否为 className 和 paramName、全名以及正确的大小写和发送正确的值。为什么选择存储程序,什么时候可以使用select?您可以在 System Management Portal 中调用您的程序以查看可能的错误。

select description, type,_Default "Default" from %Dictionary.ParameterDefinition where id='Sample.Person||EXTENTQUERYSPEC'

你的例子,对我很有效。

package javaapplication3;

import com.intersys.jdbc.CacheDataSource;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;

public class JavaApplication3 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws SQLException {

        CacheDataSource ds = new CacheDataSource();
        ds.setURL("jdbc:Cache://127.0.0.1:56775/Samples");
        ds.setUser("_system");
        ds.setPassword("SYS");
        Connection dbconnection = ds.getConnection();

        String call = "{ ? = call CacheQc.getParamDesc(?, ?, ?, ?, ?)}";
        CallableStatement statement = dbconnection.prepareCall(call);
        statement.registerOutParameter(1, Types.INTEGER);

        statement.setString(2, "Sample.Person");
        statement.setString(3, "EXTENTQUERYSPEC");

        statement.registerOutParameter(4, Types.VARCHAR);
        statement.registerOutParameter(5, Types.VARCHAR);
        statement.registerOutParameter(6, Types.VARCHAR);

        statement.executeUpdate();

        int ret = statement.getInt(1);

        System.out.println("ret = " + ret);

        System.out.println("     description: " + statement.getString(4));
        System.out.println("     type       : " + statement.getString(5));
        System.out.println("     default    : " + statement.getString(6));

    }

}

最终结果

ret = 0
     description: null
     type       : null
     default    : Name,SSN,Home.City,Home.State

UPD:尝试更改您的程序代码并添加一些调试,如这里

Class CacheQc.procgetParamDesc Extends %Library.RegisteredObject [ ClassType = "", DdlAllowed, Owner = {UnknownUser}, Not ProcedureBlock ]
{

ClassMethod getParamDesc(className As %Library.String(MAXLEN=50), methodName As %Library.String(MAXLEN=50), Output description As %Library.String(MAXLEN=8192), Output type As %Library.String(MAXLEN=50), Output defaultValue As %Library.String(MAXLEN=1024)) As %Library.Numeric(SCALE=0) [ SqlName = getParamDesc, SqlProc ]
{
    set ref = className _ "||" _ methodName
    set row = ##class(%Dictionary.ParameterDefinition).%OpenId(ref)
    set ^debug($i(^debug))=$lb(ref,row,$system.Status.GetErrorText($g(%objlasterror)))
    if (row = "") {
        quit 1
    }
    set description = row.Description
    set type = row.Type
    set defaultValue = row.Default
    quit 0
}

}

经过java的一些测试,检查zw ^debug

SAMPLES>zw ^debug
^debug=4
^debug(3)=$lb("Sample.Person||EXTENTQUERYSPEC","31@%Dictionary.ParameterDefinition","ERROR #00: (no error description)")
于 2015-04-27T09:57:32.130 回答
0

嗯,呃,我发现了问题......谈论愚蠢。

碰巧我在 Studio 中打开了 Samples.Person 类,并对它进行了“修改”;并在之后将其删除。因此该文件是“新的”...

但程序似乎与此说法不符。

我关闭了该文件所在的工作室,选择不修改“更改”,再次重新运行该过程,它工作......

奇怪的是,即使使用我的“假修改”,SQL 查询也能正常工作。我想这是一些缓存问题的问题......

于 2015-04-27T10:33:07.547 回答