Question
· Jul 18, 2017

ODBC to Cache with Dynamic Table Names

Hello! So, my knowledge on the Cache database is extremely limited, and I was hoping I could find some assistance here. I'm connecting to the DB via ODBC. The table(s) I'm interested in are named as such nameYYYYMMDD. So each day, a new table is created with logs. We'd like to grab these records each day, for the previous day's logs. 

My question is, since the table name changes every day, how can I go about automating this? Can I craft a variable that is the table name plus some date functions and use that? Failing that, it might be possible to create a new table and copy the data over, but I don't really know where to start with this database system.

At this point, any help would be beneficial and appreciated. Thanks!

 

EDIT: It's worth noting that I can query a known table just fine, and because the query is through an application, I don't have the ability to do anything outside of SQL on the requesting side.

Discussion (2)0
Log in or sign up to continue

If you have access to Caché database you can create custom query that accepts date as an argument and based on that returns specific table. It can be used via ODBC like this:

SELECT * FROM Package.Class.MyQuery(DATE)

or

Call Package.Class.MyQuery(DATE)

Here's a sample query that returns Ids from a table or a class and has an argument - class name (or table name):

Class Utils.CustomQuery2
{

/// Return ids from a table or a class
Query GetTable(Table) As %Query(CONTAINID = 1, ROWSPEC = "Id:%String") [ SqlProc ]
{
}

ClassMethod GetTableExecute(ByRef qHandle As %Binary, Table) As %Status
{
    #Dim Status As %Status = $$$OK

    If ##class(%Dictionary.ClassDefinition).%ExistsId(Table) {
        // Got a class, we need to calculate a table name and quote it
        #define ClassSQLTable(%c)    ($$$comClassKeyGet(%c,$$$cCLASSsqlschemaname)_"."_$$$comClassKeyGet(%c,$$$cCLASSsqltablename))
        Set Table = ##class(%CSP.UI.Portal.SQL.Home).Quoter2($$$ClassSQLTable(Table))
    }
    

    Set qHandle = ##class(%SQL.Statement).%ExecDirect(,"SELECT ID FROM " _ Table)
    If qHandle.%SQLCODE'=0 {
        Set Status = $$$ERROR($$$SQLError, qHandle.%SQLCODE, qHandle.%Message)
    }
    Quit Status
}

ClassMethod GetTableFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status
{
    If qHandle.%Next() {
        // Same as in ROWSPEC
        Set Row = $Lb(qHandle.ID)
    } Else {
        /// No more data
        Set AtEnd = 1
        Set Row = ""
    }
    Quit $$$OK
}

ClassMethod GetTableClose(ByRef qHandle As %Binary) As %Status
{
    Kill qHandle
    Quit $$$OK
}

}

Call samples from ODBC:

SELECT * FROM Utils.CustomQuery2_GetTable('Cube.Cube.Fact')
Call Utils.CustomQuery2_GetTable('Cube_Cube.Fact')

Code on GitHub.

Can you add more information as what is the exact problem you're facing?

If you're accessing the database through ODBC you can craft the query with any name you need to. With that said, your option of having a variable with the name + a date should work as long as this variable is within your application (client). 

If what you want is for the database to handle the variable and the logic to assemble the table name then you need to go with a stored procedure as mentioned by Eduard.