目前尚不完全清楚“监控和维修”对您意味着什么,但是:
您对数据库端有多少控制权?Cache 在使用数据类型类的 LogicalToODBC 方法从全局转换为 ODBC 时运行数据类型的代码。如果您将属性类型从 %String 更改为您自己的类 AppropriatelyNamedString,那么您可以覆盖该方法以自动截断。如果那是你想做的。可以使用 %Library.CompiledClass 类以编程方式更改所有 %String 属性类型。
也可以在 Cache 中运行代码来查找属性超过(有些理论上的)最大长度的记录。这显然需要全表扫描。甚至可以将该代码公开为存储过程。
同样,我不知道您到底想做什么,但这些是一些选择。他们可能确实需要比您更喜欢的缓存方面。
至于首先防止坏数据,没有通用的答案。缓存允许程序员直接写入全局变量,绕过任何对象或表定义。如果发生这种情况,则必须直接修复这样做的代码。
编辑:这是可能用于检测不良数据的代码。如果您正在做一些有趣的事情,它可能不起作用,但它对我有用。这有点难看,因为我不想把它分解成方法或标签。这意味着从命令提示符运行,因此可能必须根据您的目的对其进行修改。
{
S ClassQuery=##CLASS(%ResultSet).%New("%Dictionary.ClassDefinition:SubclassOf")
I 'ClassQuery.Execute("%Library.Persistent") b q
While ClassQuery.Next(.sc) {
If $$$ISERR(sc) b Quit
S ClassName=ClassQuery.Data("Name")
I $E(ClassName)="%" continue
S OneClassQuery=##CLASS(%ResultSet).%New(ClassName_":Extent")
I '$IsObject(OneClassQuery) continue //may not exist
try {
I 'OneClassQuery.Execute() D OneClassQuery.Close() continue
}
catch
{
D OneClassQuery.Close()
continue
}
S PropertyQuery=##CLASS(%ResultSet).%New("%Dictionary.PropertyDefinition:Summary")
K Properties
s sc=PropertyQuery.Execute(ClassName) I 'sc D PropertyQuery.Close() continue
While PropertyQuery.Next()
{
s PropertyName=$G(PropertyQuery.Data("Name"))
S PropertyDefinition=""
S PropertyDefinition=##CLASS(%Dictionary.PropertyDefinition).%OpenId(ClassName_"||"_PropertyName)
I '$IsObject(PropertyDefinition) continue
I PropertyDefinition.Private continue
I PropertyDefinition.SqlFieldName=""
{
S Properties(PropertyName)=PropertyName
}
else
{
I PropertyName'="" S Properties(PropertyDefinition.SqlFieldName)=PropertyName
}
}
D PropertyQuery.Close()
I '$D(Properties) continue
While OneClassQuery.Next(.sc2) {
B:'sc2
S ID=OneClassQuery.Data("ID")
Set OneRowQuery=##class(%ResultSet).%New("%DynamicQuery:SQL")
S sc=OneRowQuery.Prepare("Select * FROM "_ClassName_" WHERE ID=?") continue:'sc
S sc=OneRowQuery.Execute(ID) continue:'sc
I 'OneRowQuery.Next() D OneRowQuery.Close() continue
S PropertyName=""
F S PropertyName=$O(Properties(PropertyName)) Q:PropertyName="" d
. S PropertyValue=$G(OneRowQuery.Data(PropertyName))
. I PropertyValue'="" D
.. S PropertyIsValid=$ZOBJClassMETHOD(ClassName,Properties(PropertyName)_"IsValid",PropertyValue)
.. I 'PropertyIsValid W !,ClassName,":",ID,":",PropertyName," has invalid value of "_PropertyValue
.. //I PropertyIsValid W !,ClassName,":",ID,":",PropertyName," has VALID value of "_PropertyValue
D OneRowQuery.Close()
}
D OneClassQuery.Close()
}
D ClassQuery.Close()
}