I'm not sure for how much this is efficient, but you can use XSLT to do the transformation.

Class CMT.XmlToCsv [ Abstract ]

ClassMethod transform(
    infile As %String,
    outfile As %String) As %Status
    Set tXSL=##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1)_"||XmlToCsv").Data
    Set tSC=##class(%XML.XSLT.CompiledStyleSheet).CreateFromStream(tXSL,.tCompiledStyleSheet)
    If $$$ISERR(tSC) Quit tSC
    quit ##class(%XML.XSLT.Transformer).TransformFileWithCompiledXSL(infile,tCompiledStyleSheet,outfile)

XData XmlToCsv
<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:variable name="separator" select="','" />
    <xsl:variable name="newline" select="'&#10;'" />

    <xsl:template match="/">
        <xsl:value-of select="$newline" />
        <xsl:for-each select="//Details">
            <xsl:value-of select="Col1" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="Col2" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="Col3" />
            <xsl:value-of select="$newline" />


And then call it from terminal:

set p=##class(CMT.XmlToCsv).transform("c:\temp\input.xml","c:\temp\output.txt") 
zw p

I took XSLT from https://stackoverflow.com/a/46176699/82675

Return statement is

do %sqlcontext.AddResultSet(rs)

When you call this stored procedure it returns resultset

For example:

call CMT.ExternalUsersSearch('%in%',,,'Title')

If you call this stored procedure via ODBC / JDBC you need to add ReturnResultsets to the method definition:

CASE statement expects expression after THEN. DESC or ASC are not expressions. That's why you are getting syntax error.

So you need to supply some expression, ordering by which would mean reverse ordering by FirstName.

I don't know how to do this.

I would do sorting on the client or use dynamic SQL to create the query. As below for example.

Important! Nowhere I concatenate parameters of the stored procedure with the query to avoid SQL injections. Only SortingField is concatenated after checking that it has approved value.

ClassMethod Search(
    Name As %String = "",
    SSN As %String = "",
    Title As %String = "",
    SortingField As %String = "",
    StartIndex As %String = "") As %Integer [ SqlName = ExternalUsersSearch, SqlProc ]
 set query = "select Name, Title, SSN from Sample.Employee WHERE 1=1 "
 kill args

 if Name'="" {
     set args($I(args)) = Name
     set query = query _ "AND Name like ? "

 if SSN'="" {
     set args($I(args)) = SSN
     set query = query _ "AND SSN like ? "

 if Title'="" {
     set args($I(args)) = Title
     set query = query _ "AND Title like ? "

 set AllowedFieldsToOrderBy = $LB("Name", "SSN", "Title")
 if $ListFind(AllowedFieldsToOrderBy, SortingField) {
    set query = query _ " ORDER BY " _ SortingField

    if StartIndex = 1 {
        set query = query _ " DESC"
    } else {
        set query = query _ " ASC"

 set rs = ##class(%SQL.Statement).%ExecDirect(,query,args...)

 #dim %sqlcontext As %SQLProcContext
 if rs.%SQLCODE >=0 {
     do %sqlcontext.AddResultSet(rs)
 } else { // pass errors to the caller
     set %sqlcontext.%SQLCODE = rs.%SQLCODE
     set %sqlcontext.%Message = rs.%Message
 quit 1

Not possible to do this in Query. You need to use dynamic SQL.

Symbol ":" is used to indicate host variables. Host variables are treated as expressions, not as identifiers.

During query compilation host variables are replaced with placeholders.

Consider query:

SELECT FirstName, MiddleName, LastName, Email, UserType 
FROM DB.ExternalUsers
WHERE FirstName like :objSearch.FirstName
ORDER BY :objSearch.SortingField

This query is compiled as:

SELECT FirstName, MiddleName, LastName, Email, UserType 
FROM DB.ExternalUsers
WHERE FirstName like ?

Then during runtime you supply values as follows:
objSearch.FirstName = 'A%'
objSearch.SortingField = 'FirstName'

And query is executed as follows:

SELECT FirstName, MiddleName, LastName, Email, UserType 
FROM DB.ExternalUsers
WHERE FirstName like 'A%'
ORDER BY 'FirstName'

Notice 'FirstName' is in quotes in ORDER BY. So you sort by literal string. That is doing nothing.

What you can do is to use expression like:

 Order by CASE :objSearch.SortingField
          WHEN 'FirstName' THEN FirstName
          WHEN 'MiddleName' THEN MiddleName

Although such generic queries makes SQL Query Analyzer unable to reason what plan is better to use for this query.

Name the file login.csp

And inside it check for Error:ErrorCode request parameter:

My login page:</br>
<form method='post'>
Name: <input name="CacheUserName"/><br/>
Password: <input type='password' name="CachePassword"/><br/>
<input type='submit'/>

Set tMsg = $Get(%request.Data("Error:ErrorCode",1))
    If ((tMsg'="")&&($SYSTEM.Status.GetErrorCodes(tMsg)'[$$$ERRORCODE($$$RequireAuthentication))) {
        write "Auth failed!"

You can use $system.OBJ.Export to export LUT document to file:

ENSDEMO>w $system.OBJ.Export("AlertTable.LUT","c:\temp\qq.lut")

Exporting to XML started on 08/30/2019 12:03:14
Exporting type : AlertTable.LUT
Export finished successfully.
ENSDEMO>w $system.OBJ.Load("c:\temp\qq.lut")

Load started on 08/30/2019 12:03:26
Loading file c:\temp\qq.lut as xml
Imported document: AlertTable.LUT
Load finished successfully.