Using class queries to select all rows and return an array: unexpected behaviour
We have in DB two books, first is loaned because it has the Friend ID, and the other is in the shelf.
I execute a class query to get all loaned books:
Query BooksLoaned() As %SQLQuery
{
SELECT *
FROM Library.Book
WHERE Friend IS NOT NULL
}
Which I have tested throught the portal:
My task is to retrieve all the loaned books and return them in an array. Method code:
ClassMethod GetLoanedBooks() As %ArrayOfObjects
{
set booksRS = ##class(%ResultSet).%New("Library.Book,BooksLoaned")
set rsStatus = booksRS.Execute()
set i = 1
set ^books = ""
if rsStatus = $$$OK {
while booksRS.Next() {
set book = ##class(Library.Book).%New()
set book.Title = booksRS.Get("Title")
set book.Author = booksRS.Get("Author")
set book.Genre = booksRS.Get("Genre")
set dbFriend = ##class(Library.Person).%OpenId(booksRS.Get("Friend"))
set book.Friend = dbFriend
set ^books(i) = book
set i = i + 1
}
}else{
w !,"Error fetching books in GetoanedBooks()"
}
do booksRS.Close()
return ^books
}
The question is:
Why when I execute in the terminal:
set books = ##class(Library.Book).GetLoanedBooks()
zw books
It outputs:
And when I write:
zw ^books
I know ^books is a global variable, but I do not know why if I am currently returning the books array and setting it into the terminal, it doesn't have the loaned book inside.
Thanks for your help.
Any recommended lecture is appreciated!
🤯
First issue (empty books):
Second issue (12@Library.Book in value). 12@Library.Book is an OREF. As it's essentially a pointer it cannot be stored in a persistent way.
What do you want to achieve with your code?
Learning.InterSystems.com has hundrers of online courses. Check multimodel development with ObjectScript.
@Yone Moreno , I assume it's an exercise. In that case, do you mind to share your code in a public repo and people will understand what you are going to achieve and will PR the answer.
@Yone Moreno are you working on "Learning Path Exercise: Building a Server-Side Application with InterSystems IRIS"?
If so, it's helpful to use the "Show Answer" button.
Hello,
your method returns %ArrayOfObjects so you need to create and populate it within your code...
your code should look like (I have highlighted the relevant changes in code) :
set rsStatus = booksRS.Execute()
S books = ##class(%ArrayOfObjects).%New()
if rsStatus = $$$OK {
while booksRS.Next() {
set book = ##class(Library.Book).%New()
set book.Title = booksRS.Get("Title")
set book.Author = booksRS.Get("Author")
set book.Genre = booksRS.Get("Genre")
set dbFriend = ##class(Library.Person).%OpenId(booksRS.Get("Friend"))
set book.Friend = dbFriend
Set sc = books.SetAt(book,$Increment(i))
}
}else{
w !,"Error fetching books in GetoanedBooks()"
}
do booksRS.Close()
return books
I think
set booksRS = ##class(%ResultSet).%New("Library.Book,BooksLoaned")
should be
set booksRS = ##class(%ResultSet).%New("Library.Book:BooksLoaned")
Both syntax are good. the %New can handle "," or ":"