Método de consulta em uma classe %Persistent usando como parâmetro
Olá a todos,
Estou me perguntando se é possível obter os valores de si mesmo para executar uma consulta.
Eu quero criar uma consulta para encontrar um valor em uma classe %Persistent, mas cada uma usa valores diferentes.
Class Kurro.MyClass Extends %Persistent
{
/// Key of process
Property KeyProcess As %String(MAXLEN = "");
/// Specialist
Property CodeSpecialist As %String;
/// Provider
Property CodeProvider As %String;
/// Center
Property CodeCenter As %String;
/// Date
Property Date As %TimeStamp;
/// IdList
Property IdList As %String;
/// IdProcess
Property IdProcess As %String;
/// Duration
Property Duration As %String;
Query GetInfo(pObject AS Kurro.MyClass) As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String")
{
SELECT IdList, IdProcess, Duration
FROM Kurro.MyClass
WHERE KeyProcess = :pObject.KeyProcess
AND CodeSpecialist = :pObject.CodeSpecialist
AND CodeProvider = :pObject.CodeProvider
AND CodeCenter = :pObject.CodeCenter
AND Date = :pObject.Date
}
}Então eu chamo desta forma:
set obj=##class(Kurro.MyClass).%New()
set obj.KeyProcess="1033004-1#"
set obj.CodeSpecialist = "surgery"
set obj.CodeProvider = "PR002"
set obj.CodeCenter = "CENTER-01"
set obj.Date = $ZDATETIME($ZDATETIMEH("2021-04-30 15:45:00",3,1),3,1)
set result = obj.GetInfoFunc(obj)Mas eu tenho o seguinte erro
% Message = "ERROR # 5002: Error de cache: <OBJECT DISPATCH> zGetInfoFunc + 5 ^ Kurro.MyClass1 * Propriedade 'KeyProcess' na classe 'Kurro.MyClass' deve ser MultiDimensional"
É estranho, porque essa propriedade é um parâmetro %String simples.
Em seguida, tentei obter valores para si mesmo e chamar usando a mesma instância
Query GetInfo() As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String")
{
SELECT IdList, IdProcess, Duration
FROM Kurro.MyClass
WHERE KeyProcess = KeyProcess
AND CodeSpecialist = CodeSpecialist
AND CodeProvider = CodeProvider
AND CodeCenter = CodeCenter
AND Date = Date
}e chamá-lo usando
set result = obj.GetInfoFunc()
Mas não funciona
% Message = "ERROR # 5002: Erro de cache: <PARAMETER> z GetInfo + 1 ^ Kurro.MyClass.1"
é possível obter os valores do objeto para usar como parâmetro da consulta?
Atenciosamente,
Kurro
Comments
Abaixo uma sequência de respostas marcadas como "Accepted answer" no post original
Talvez passando o ID do objeto em algo parecido com isso:
Query GetInfo(refId As %String) As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String")
{
SELECT list.IdList, list.IdProcess, list.Duration
FROM Kurro.MyClass list
JOIN Kurro.MyClass ref on ref.ID = :refId
AND ref.KeyProcess = list.KeyProcess
AND ref.CodeSpecialist = list.CodeSpecialist
AND ref.CodeProvider = list.CodeProvider
AND ref.CodeCenter = list.CodeCenter
AND ref.Date = list.Date
}resposta por @Timothy Leavitt
É uma boa ideia, mas eu não tem o ID da linha.
Minha ideia era usar o objeto como um parâmetro e passar um monte de valores, e a query leria estes valores, ao invés de passá-los uma a um nos parâmetros.
Eu mudei minha query com todos os parâmetros que eu preciso para executá-la
Query GetInfo(pKeyProcess As %String, pCodeSpecialist As %String, pCodeProvider As %String, pCodeCenter As %String, pDate as %TimeStamp) As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String")
{
SELECT IdList, IdProcess, Duration
FROM Kurro.MyClass
WHERE KeyProcess = :pKeyProcess
AND CodeSpecialist = :pCodeSpecialist
AND CodeProvider = :pCodeProvider
AND CodeCenter = :pCodeCenter
AND Date = :pDate
}Funciona, mas ainda preciso passar todos os parâmetros. Eu queria criar uma classe para passar todos os parâmetros, tipo um método em c#, e tentar usa-lo.
Valeu galera.
resposta por @Kurro Lopez
É um assunto interessante.
#2) Seu segundo exemplo não vai funcionar, porque não está passando um parâmetro de chamada.
#1) Não está previsto o uso de propriedades de objetos como variáveis de host em SQL
O código dá erro no método Execute gerado.
$GET para propriedades de objeto não está implementado. É definido pela classe e está sempre lá.
Mas é necessário e faz sentido para propriedades multidimensionais!
Isto é válido para ObjectScript e não está relacionado a SQL.
Mas, escrevendo o código na mão, você pode usar $g(NOTHING,pObject.KeyProcess)
O gerador simplesmente não faz isso.
Workaround #1: Mexer diretamente no código gerado. Não recomendado.
Workaround #2: Mova suas propriedades com uma função auxiliar para variáveis locais e ajuste sua query a essas variáveis
example helper (with obj or id):
{
if '$isObject(pObject) set obj=##class(Kurro.MyClass).%OpenId(pObject)
else set obj=pObject
set %Kurro("kp")=obj.KeyProcess
,%Kurro("sp")= obj.CodeSpecialist
,%Kurro("pr")= obj.CodeProvider
,%Kurro("cs")= obj.CodeCenter
,%Kurro("dt")= obj.Date
quit 1
}
Query exemplo:
{
SELECT IdList, IdProcess, Duration
FROM Kurro.MyClass
WHERE KeyProcess = :%Kurro("kp")
AND CodeSpecialist = :%Kurro("sp")
AND CodeProvider = :%Kurro("pr")
AND CodeCenter = :%Kurro("cs")
AND "Date" = :%Kurro("dt")
AND FILLP(:objid) = 1
}
Funciona como esperado.
resposta by @Robert Cemper
Você está implicitamente utilizando o método %Library.SqlQuery:Func(), no qual, como corretamente @Robert Cemper apontou, $get() é usado.
Você pode fazer dessa outra maneira:
Query GetInfo(pObject AS Kurro.MyClass) As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String") [ SqlProc ]
{
SELECT IdList, IdProcess, Duration
FROM Kurro.MyClass
WHERE KeyProcess = :pObject.KeyProcess
AND CodeSpecialist = :pObject.CodeSpecialist
AND CodeProvider = :pObject.CodeProvider
AND CodeCenter = :pObject.CodeCenter
AND "Date" = :pObject.Date
}
set obj=##class(Kurro.MyClass).%New()
set obj.KeyProcess="1033004-1#"
set obj.CodeSpecialist = "surgery"
set obj.CodeProvider = "PR002"
set obj.CodeCenter = "CENTER-01"
set obj.Date = $ZDATETIME($ZDATETIMEH("2021-04-30 15:45:00",3,1),3,1)
set st=##class(%SQL.Statement).%New()
set sc=st.%PrepareClassQuery("Kurro.MyClass","GetInfo")
if $$$ISERR(sc) {write "%PrepareClassQuery failed:" do $System.Status.DisplayError(sc) quit}
set result=st.%Execute(obj)
do result.%Display()
resposta por @Vitaliy Serdtsev