Load samples package automatically.
This is a query generator that replaces the %Library.SQLQuery, giving more control over SQL code.
To enable, change your query:
Query filter(Name As %String = “”, Age As %Integer = “”) As %SQLQuery
to
Query filter(Name As %String = “”, Age As %Integer = “”) As PXW.LIB.SQL.Query
This will enable ObjectScript conditions to be embedded in SQL code.
This project:
Make sure you have git and Docker desktop installed.
Clone/git pull the repo into any local directory
$ git clone https://github.com/pxw-paul/pxw-lib-sql.git
Open the terminal in this directory and call the command to build and run InterSystems IRIS in container:
Note: Users running containers on a Linux CLI, should use “docker compose” instead of “docker-compose”
See Install the Compose plugin
$ docker-compose up -d
To open IRIS Terminal do:
$ docker-compose exec iris iris session iris -U IRISAPP
IRISAPP>
It is often necessary to build an SQL string that is different based on the parameters passed in.
For example, we might have a search string built that is based on Name OR Age OR Both.
ClassMethod SimpleFilterString(SearchName As %String = "", MinAge As %Integer = "") as %String
{
Set sep=""
Set sql="SELECT ID, Name, Age, SSN FROM %ALLINDEX PXW_sample.Person WHERE "
If SearchName'="" {
Set sql=sql_"Name %STARTSWITH '"_SearchName_"'",sep=" AND "
}
If MinAge'="" Set sql=sql_sep_"Age>="_MinAge
Quit sql
}
Here the focus is on the ObjectScript and the SQL that’s generated is hard to see.
Using this query generator, the above code could be written as a query where the focus is on the SQL and the extra logic becomes embedded as comments.
Query SimpleFilterPXW(SearchName As %String = "", MinAge As %Integer = "") As PXW.LIB.SQL.Query [ SqlProc ]
{
SELECT ID, Name, Age, SSN FROM %ALLINDEX PXW_sample.Person
WHERE 1=1
--IF SearchName'=""
AND Name %STARTSWITH :SearchName
--ENDIF
--IF MinAge'=""
AND Age >= :MinAge
--ENDIF
}
The “logic” parts, controlling the final, sql are comments, so the editor (Studio and VS Code) will ignore them. The overall SQL must be valid or the editor may get confused.
The IF,ELSEIF,ELSE,ENDIF commands must be immediately after the start of the comment.
--IF will work, -- IF will not work.
/*IF will work, /* IF will not work.
The part after the IF is counted as object script code and simply dumped into the compiled code. This means that refering to the parameters here you do not need the colon (MinAge not :MinAge).
The above example is trivial, and actually writing this as a pure SQL query you can create the same effect with the same index usage. If the logic was more complicated this starts to gain an advantage as it will only compile what is needed and is more likely to use the indices correctly.
The repository contains two sample classes to demonstrate the functionality. The table is populated with 10000 rows of random data automatically.
You can test its working using SQL call or ObjectScript function.
IRISAPP>:sql SQL Command Line Shell ----------------------------------------------------
The command prefix is currently set to: <<nothing>>.
Enter <command>, 'q' to quit, '?' for help.
[SQL]IRISAPP>>call PXW_sample.PersonQueries_SimpleFilterPXW('Tesla',94)
9. call PXW_sample.PersonQueries_SimpleFilterPXW('Tesla',94)Dumping result #1
ID Name Age SSN
6388 Tesla,Sally B. 98 838-48-5845
7812 Tesla,James F. 99 875-64-7340
9273 Tesla,David K. 94 489-97-1975
9315 Tesla,Dan F. 94 948-94-6350
9871 Tesla,Ashley H. 98 535-23-7307
5 Rows(s) Affected
IRISAPP>s rs=##class(PXW.sample.PersonQueries).SimpleFilterPXWFunc("Tesla",94)
IRISAPP>d rs.%Display()
ID Name Age SSN
6388 Tesla,Sally B. 98 838-48-5845
7812 Tesla,James F. 99 875-64-7340
9273 Tesla,David K. 94 489-97-1975
9315 Tesla,Dan F. 94 948-94-6350
9871 Tesla,Ashley H. 98 535-23-7307
5 Rows(s) Affected
The PersonQueries class also contains a more complex example, using nested IFs, that you can look at and play with.
There are no unit tests yet.
This is based on the standard template, so contains all the github, vscode and docker settings to get going.
The classes needed to use the new query template are:
This is that class that replaces %Library.SQLQuery on Queries.
This class is used by PXW.LIB.SQL.Query when generating the code
This is something that may help when creating queries. The macros in here were an idea I had to make a complex query.
The directory PXW/sample contains two cls files with the code for example classes.
The two classes are: a small Person object that can be used for testing. A set of Queries showing different ways to create the same results.
I hope you will agree that the PXW way looks nicer.
There is no check on the query to make sure the IF/ENDIF counts match. If there is something wrong it will most likely show a compile error on a seemingly random line of the INT code.
The original code for this was developed a few years ago on an older version of Cache, and extended the %Library.SQLQuery class. When upgrading to Iris the %SQLQuery class changed and no longer worked with this extension. To resolve this the old Cache code was copied in to the PXW version. This may not be the best solution and perhaps it should be reworked to extend from the new %SQLQuery.