IBM Maximo (Oracle SQL) Where Clause, defining a variable for reuse - sql

I write many Maximo Where Clauses (which use Oracle SQL), and save them as public queries.
I encourage others to edit/customize the work I share with them.
But when my query uses the same string throughout it many times, it's tedious to make sure all instances are replaced. It's not like there's a built-in find-replace tool or anything.
Is there a way to define a custom string variable at the beginning, and reuse that variable many times thoughout the where clause?

No, you can't do that. But what you could do is make a relationship from your parent object to a system property / maxpropvalue child object where propname = 'company.app.varname. Then, you can use the System Properties app to change the value of the variable for all references. And you can make a reference to it in your query using standard :relationshiptomaxpropvalue.propvalue syntax.
HTH.

Related

Using list as a positional parameter in JPA query

I want to know if it's possible to pass in a list as a parameter in native queries.
When search up online, an article in Baeldung has exactly what I want to do:
Collection-Valued Positional Parameters usage
I did the exact same thing, except that in the article, they used "createQuery" and I used "createNativeQuery". Not sure if this is the reason why mine is not working.
CreateQuery means JPQL was passed in which is parsed and modified into SQL, which allows it to break the collection parameter into its components to pass each into the SQL statement. CreateNativeQuery uses your SQL which isn't modified, and JDBC doesn't understand collections so requires parameters broken up into individual arguments in the SQL. You have to do it yourself and dynamically build the SQL based on the number of parameters in the collection.
There are other questions with solutions that touch on other options, such as using SQL within criteria or JPQL queries that can let you get the best of both.

Scope of SqlDataConnection variable with SQL Type Provider

Using the SQL type provider in FSharp.Data with MSFT SQL Server, I declare the type:
type dbSchema = FSharp.Data.TypeProviders.SqlDataConnection<"Data Source=DESKTOP-5\SQLEXPRESS;Initial Catalog=Data;Integrated Security=True;MultipleActiveResultSets=True;">
outside of any module, along with most of my other types (following a suggestion to declare types outside of modules to avoid nested classes). I really wouldn't know, but assume that it's so far so good.
Where I'm wondering how to arrange things is in using the type, with eg:
use db = dbSchema.GetDataContext()
db.DataContext.ExecuteCommand(sqlCreateTableStmt a b c)
My upload process goes through lists of lists and functions calling functions. And I don't know what the pros and cons are of where to declare use db. It could be re-done locally in each function, or "globally" outside any module, or in the first, top-level function and passed along from function to function as a parameter. Or some combination.
Hopefully that's enough of a question to be worthwhile. Right now I have a use declaration in each function. Not passing it ever. In some places one function declares use db and calls another function that declares use db again. I don't know if there's overhead in making or managing these connections. Or whatever else to worry about.
Thanks in advance.

Execute some arbitrary sql in the current transaction in JPA 2.0

I am new to JPA 2.0/EclipseLink/Glassfish/JEE6, and have kind of a basic question.
I have a DAO in which most of the entities are mapped directly to columns using JPA annotations, so I use the EntityManager, and it works great with no issues.
However there are some tables in which I am constructing the SQL statements myself b/c they use oracle-specific functions (spatial), and I want very fine-grained control of the SQL. So I am building it with string concatenation. I would like to be able to enroll my SQL executions in the current transaction, if there is one already underway.
So naturally I don't want to go directly to the DriverManager and create my own connection, I was looking for some kind of EntityManager.executeArbitrarySQL(String) function that would find the current connection and make my SQL part of the current transaction. Am I off my rocker?
One can use the EntityManager.createNativeQuery() methods to execute native SQL queries within the context of the same EntityManager that you are using. There are two three different types of these methods, and they differ in the arguments provided.
The first, createNativeQuery(String sqlString, Class resultClass) expects you to provide the Class object representing the type of the values that will be returned by the query. This is to be used in case you are returning a set of values that can be mapped to the class of another entity definiton in your persistence unit.
The second createNativeQuery(String sqlString, String resultSetMapping) expects you to provide the name of the result set mapping. The result set mapping ought to be defined using the #SqlResultSetMapping annotation.
The last createNativeQuery(String sqlString) is apparently meant to be used in scenarios where no result set will be returned, i.e. in execution of INSERT, UPDATE and DELETE statements.
You can also define native queries using the #NamedNativeQuery annotation or the named-native-query element in your persistence.xml file, but these are better suited for scenarios where you know the structure of the query during development. You can however, create multiple such named native queries to represent all varieties of the SQL statement you intend to execute, and then execute different ones at runtime based on the user inputs. Annotated native queries are executed using the EntityManager.createNamedQuery() methods. One will need to use positional parameters (defined using the ? placeholder) to supply values to the native queries at runtime.

Best Way to Handle SQL Parameters?

I essentially have a database layer that is totally isolated from any business logic. This means that whenever I get ready to commit some business data to a database, I have to pass all of the business properties into the data method's parameter. For example:
Public Function Commit(foo as object) as Boolean
This works fine, but when I get into commits and updates that take dozens of parameters, it can be a lot of typing. Not to mention that two of my methods--update and create--take the same parameters since they essentially do the same thing. What I'm wondering is, what would be an optimal solution for passing these parameters so that I don't have to change the parameters in both methods every time something changes as well as reduce my typing :) I've thought of a few possible solutions. One would be to move all the sql parameters to the class level of the data class and then store them in some sort of array that I set in the business layer. Any help would be useful!
So essentially you want to pass in a List of Parameters?
Why not redo your Commit function and have it accept a List of Parameter objects?
If your on SQL 2008 you can use merge to replace insert / update juggling. Sometimes called upsert.
You could create a struct to hold the parameter values.
Thanks for the responses, but I think I've figured out a better way for what I'm doing. It's similar to using the upsert, but what I do is have one method called Commit that looks for the given primary key. If the record is found in the database, then I execute an update command. If not, I do an insert command. Since the parameters are the same, you don't have to worry about changing them any.
For your problem I guess Iterator design pattern is the best solution. Pass in an Interface implementation say ICommitableValues you can pass in a key pair enumeration value like this. Keys are the column names and values are the column commitable values. A property is even dedicated as to return the table name in which to insert these value and or store procedures etc.
To save typing you can use declarative programming syntax (Attributes) to declare the commitable properties and a main class in middleware can use reflection to extract the values of these commitable properties and prepare a ICommitableEnumeration implementation from it.

NHibernate: Return A Constant In HQL

I need to return a constant from an HQL query in NHIbernate
SELECT new NDI.SomeQueryItem(user, account, " + someNumber + ")
FROM NDI.SomeObject object
I am trying for something like above. I've tried this:
SELECT new NDI.SomeQueryItem(user, account, :someNumber)
FROM NDI.SomeObject object
And then later:
.SetParameter("someNumber", 1).List<SomeQueryItem>();
But in the first case I get a 'Undefined alias or unknown mapping 1'. Which makes some sense since it probably thinks the 1 is an alias.
For the second I get a 'Undefined alias or unknown mapping :someNumber' which again makes some sense if it never set the parameter.
I have to believe there's some way to do this.
Please feel free to continue to believe there is some way to do this - but with HQL there isn't!
Why would you want to anyway? If you want to update the value this property to the value you specify, then do so after you've loaded the objects. Alternatively, if your result set doesn't quite match to your objects, you could alway use a SQL query (which you can still do via an NHibernate session). But the purpose of NHibernate is to map what's in your database onto objects, so specifying a manual override like this is quite rightly not allowed.
It sounds like there is a (small?) disconnect between your domain objects and your database model. What about creating a small "DTO" object to bridge this gap?
Have your query return a list of SomeQueryItemDTO (or whatever you want to call it) which, due to the naming, you know is not a true part of your domain. Then have some function to process the list and build a list of true SomeQueryItem objects by incorporating the data that is extraneous to the database.
If you're already using the Repository Pattern, this should be easier since all the ugly details are hidden inside of your repository.