自定义过程无法收集类参数的属性;为什么呢?

时间:2015-04-27 08:50:40

标签: intersystems-cache objectscript

好的,首先,我是Caché的新手,所以代码可能很差,但是......

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

我可以毫无困难地转储方法等,但是有一件事让我感到厌烦......出于某种原因,我无法从类EXTENTQUERYSPEC转储参数Samples.Person的属性(名称空间:{{ 1}})。

该课程在Studio中如下所示:

SAMPLES

以下是程序的代码:

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

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

// etc etc
} 

Java代码:

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
}

现在,对于前面提到的类/参数对,标记为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

我原本期望后者具有Studio ...

中提到的值

那么,为什么会这样呢?我的手术有点破了吗?

2 个答案:

答案 0 :(得分:2)

首先,您应检查是否为className和paramName,全名以及正确的情况发送了正确的值。为什么选择存储过程,何时可以使用select?您可以在系统管理门户中调用您的过程以查看可能的错误。

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)")

答案 1 :(得分:0)

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

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

但该程序似乎并不同意这一说法。

我关闭了该文件所在的工作室,选择不修改“更改”,再次重新执行该程序,并且它有效...

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