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.
Related
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
I'd like to provide a REST webservice for database actions. The SQL statements should be externalized in local files (not inside the code).
It would be nice to also define the parameter types inside the external files.
Normally a statement would be written as:
String sql = "SELECT * from user_table WHERE id=?";
PreparedStatement stm = c.prepareStatement(sql);
stm.setInt(1, 345);
//stm.setString(2, "username");
stm.executeUpdate();
Problem: if I'd just import the sql statement from file, I have to know the parameter types beforehand (and also the number of parameters). Thus have to more or less hardcode the statement fetching.
But I'd like to be able to replace the sql statement at runtime (and eg add or remove parameters) without having to touch the java code. So I could change the sql without having to restart the service.
Like (pseudocode):
<definition>
<sql id="getUsers">
<statement>SELECT * from user_table WHERE id=? and name=?</statement>
<param idx="1" type="Integer"/>
<param idx="2" type="String"/>
</sql>
</definition>
And then just feed the sql statement with parameters from a Map.
Question: is there any existing framework that provides such a mechanism for templating the sql in external files. And feed the sql statements with parameters from a HashMap (that might eg be received via POST dynamically from a webservice)?
Sidenote: the sql in the file must be native sql. I cannot make use of eg HSQL or similar.
Sidenote2: I'm not looking for an ORM, I know there is hibernate to map between database and java beans. But I'm not interested in mapping the sql result to beans. My focus is to have the ability to interchange the sql statements dynamically without having to recompile.
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.
I want to execute an sql-query over 2 databases using java
but have some problems finding out how to do it without writing everything by myself
maybe someone has an idea how to do it.
example:
database1
table1(names): id,Name,zip,something
database2
table2(towns): id,townname,zip
SELECT *
FROM database1.names, database2.towns
WHERE database1.names.zip = database2.towns.zip
the example works in mysql when i use phpMyAdmin and the User has rights on both databases
edit:
The question is: How do i get Java to execute such a query since i can only connect to one database(?)
or: How can I connect to 2 Databases executing an Sql Query that uses tables from both databases using java.
the way i execute sql commands in java looks like:
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/database?user=root&password=");
PreparedStatement pstmt = c.prepareStatement("Select * from something");
pstmt.executeQuery();
but i cant use that to get a Sql Query that uses tables from 2 databases?
Assuming that these databases are not visible from the same datasource, you have to use a mediation software to query on them, such as http://www.unityjdbc.com/doc/multiple/multiplequery.php.
It's not a trivial problem, since your "SQL" will have to deal with each datasource availability and transaction.
Some DB vendors provide some sort of dblinks (e.g. http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_5005.htm) that help you a little to deal with heterogeneous DBs.
So it would be nice if you narrow your question to what DBMSs you are interested.
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.