Is it possible to soft code sql statements? - java

I was told that it is possible to soft code SQL queries instead of hard coding them. Just like we parse JSON responses in Java, we can do that through an external file like below:
abc:[
{
sql:"selecct count(*) from some_database",
count:"100"
}]
Is it possible? How I can do that? Links or articles would be appreciated. I am using Hibernate. How can I run a SQL query through external file in Hibernate?

If you're using Java, try using MyBatis.
SQL statements are placed in a resource XML file and code references the queries by name. This allows you to edit the XML when details of the schema change, possibly without modifying the code that consumes them.

Yes.
for instance in a resource bundle:
ResourceBundle bundle = ResourceBundle.getBundle();
PreparedStatement psmt = connection.prepareStatement(bundle.getString("users.query"));
....
Or any other string for that matter.

Store the SQL statements in variables, or return them from a function if you want to dynamically add variables to the SQL statements themselves.
Wherever you normally put an SQL query as a string, just put the variable, or function call instead.

Related

Building CosmosDB Query strings with escaping

I want to build a cosmosdb sql query, because I'm using a rest interface, which accepts SQL querys (don't ask why, I can't change that :( )...
Now I want to build that query with some parameters, which affects the WHERE clause.
I think it is a good idea to escape these parameters, to prevent sql injection.
But I just found these way to build a query:
var param = new SqlParameter();
param.add("#test", "here some string to inject");
var query = new SqlQuerySpec("SELECT #test FROM table", param);
Now I could do sql calls to the cosmos's without sql injection. But I don't want this. I just want to get the query string.
But I need the full query from "query". But there seems to be just the method query.getQueryText(). But this just returns the string "SELECT #test FROM table".
Do know a workaround for me? Or maybe just a good package I can use to to my own string escapes.
T
I found the information that this escalation stuff doesn't happen on client site. It happens in the dbms. So I need a rest interface, where I can pass the parameters.
Azure Cosmos DB SQL Like, prepared statements

Get results as CSV from postgresql using hibernate

I execute a query which should return the results as a CSV to the STDOUT.
When I execute my query in the pgAdmin I successfully get results.
However when I execute the same query using hibernate I gets the following exception:
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not extract ResultSet
I mustn't show the tables structure but I know that the sql is fine(I've copied the entire content of "sql" then I execute it in pgAdmin); The query looks like:
String sql = "COPY (" + sqlQuery + ") TO STDOUT WITH CSV";
Then I execute it as the following:
Query query = getEntityManager().createNativeQuery(sql);
Object result = query.getSingleResult(); // I also tried the other get results method...(`getFirstresult()` has returned 0)
In any related questions I have found, I saw that the OP put the csv into a file instead of stdout.
Is it possible to return csv result using hibernate?
Thanks in advance!
AFAIK, COPY is not supported natively by PostgreSQL JDBC driver (last tested on postgresql-9.4.1208.jre7). Thus, Hibernate can not run the command.
If you really need to use COPY you should consider a CopyManager: how to copy a data from file to PostgreSQL using JDBC?
But personally, I would advocate you change your approach. Loading data with COPY looks like a kind of a hack to me.
You can have this done with univocity-parsers using two lines of code. You just need to get a resultset from your query and do this:
CsvRoutines routines = new CsvRoutines();
routines.write(resultset, new File("/path/to/output.csv"), "UTF-8");
The write() method takes care of everything. The resultset is closed by the routine automatically.

What is the SQL equivalent of CallableStatement?

I have some code I'm trying to fix and a function is used within a CallableStatement but it seems that said function is called in a particular instance where a Schema of the Database becomes the entire 'see-able' database for the function.
Let me explain :
My database (in PostgreSQL) has multiple projects (schemas) such as i2b2test_project or i2b2test_project2. Each of these projects has an architecture of multiple tables, such as visit_dimension, patient_dimension, etc..
Now, if I want to reference the visit_dimension table from a i2b2test_project, I need to use i2b2test_project.visit_dimension, as any logical SQL syntax would suggest.
The problem is that, in the code (which I'll include below), a CallableStatement is used to execute a function (plain old load-table-from-temp-table function). This function references the architecture mentioned above as if only one project exists, as the database. In other words, instead of referencing i2b2test_project.visit_dimension, it only references visit_dimension.
I haven't found a way to execute a function in some sort of 'separated instance' of the database and as a result, the function can not be used in a plain SQL statement inside a DB terminal, errors such as visit_dimension table does not exist etc..
So I ask : Does the call statement (which indeed seems to reference the schema) allow for such a 'separated instance' of the database ? And is there a way to do so with a plain SQL statement ?
Code :
CallableStatement callStmt = conn.prepareCall("{call "
+ this.getDbSchemaName()
+ "INSERT_ENCOUNTERVISIT_FROMTEMP(?,?,?)}");
callStmt.setString(1, tempTableName);
callStmt.setInt(2, uploadId);
callStmt.registerOutParameter(3, java.sql.Types.VARCHAR);
callStmt.execute();

How to pass SQL query as a context variable in Talend Open Studio job

I am creating a job to pull data from a database to CSV file using talend open studio. There are 100 of tables, the data types and no of columns differ in the tables, I want to pull the data from database tables with a single job and customizable SQL query. I know how to create and use context variables.
If I understood you correctly you should be using tMap's reload at each row -option and defining table names in Excel sheet or in tFixedFlowInput.
tMap settings
Whole job and results
SQL Script:
"SELECT TOP(1) Name, Code from mdm." + (String)globalMap.get("row4.table")
I used Microsoft SQL Server for example but same script works as well with MySQL.
You can simply use a context-variable which you set via the --context_param argument in a tWhicheverDatabaseInput. E.g. define a context variable "my_sql" which you can set in the commandline as
my_job.sh --context_param my_sql="select a,b,c from a_test_table"
and then use context.my_sql as the SQL in you database input component.
However, as garpitmzn already mentioned, you will need dynamic schemas to actually work with this unknown structure in Talend. This feature only exists in the enterprise version.
If the enterprise version is available to you, simply declare a single column of type "Dynamic", which you can pass through the rest of your flow.
Declare a local context say query as type string.
Prepare a context file with variable query: query=select name from employee
Excecute the query: toraclecomponent use context.query
Query is throwing some error when you have where conditions with string type.
Need to investigate more on that. Otherwise it works.

How to externalize an insert file SQL query

In my application, I want to externalize SQL query (in .properties files for example). But sometimes I had to insert the entire content of a text file into a CLOB column.
This is the code I use now:
String requete = "the content of the file in xml";
PreparedStatement prepareStatement = con.prepareStatement("INSERT INTO \"TABLE\".\"_XML\" (ID, BLOC_XML) VALUES ('1',?)");
prepareStatement.setCharacterStream(1, new StringReader(requete), requete.length());
I really need to decouple the SQL logic from the application business logic. Any suggestions to tackle this problem.
Thanks.
It's not a good idea to externalize the SQL queries. Imagine that someone would change the .properties file to something like
drop table really_important_stuff;
Furthermore, as a developer I would prefer to have the SQL queries as close to the source code as possible. So that I do not need to look them up in some other resource.
It's simple to gain control of the complexity using DAO pattern for example.

Categories

Resources