Talend - Read a SQL from .txt and pass variables to it - sql

I need to read an Excel file and excecute a different SQL Query (Oracle) for each row of the Excel, depending on the value that a column ("tipo") of the table has. Also, I need to pass variables to the SQL query that comes from others columns of the same excel.
I have accomplished this with a tjava, creating a string that generates de query.. somthing like this (simplified):
String var1 = input_row.var1;
String var2 = input_row.var2;
String sql_query = ""
if (tipo.toString().equals(String.valueOf("Option1"))) {
query_ev = "select " + var1 + " as variable1, " + var2 + " as var 2 from dual";}
if (tipo.toString().equals(String.valueOf("Option2"))) {
query_ev = "select " + var1+ " from dual";}
context.sql = sql_query;
Nevertheless, my "problem" is that my queries are long, and this method only allows me to put them in the tjava whithout line breaks, so its very difficult to edit them since they remain a "one-row-query" in the tjava.
Is there a way to accomplish the same but having the queries formatted ?
for example, for Option1 having this
select " + var1 + " as variable1, " + var2 + " as var 2
from dual
where
...
I appreciate any clue.

Try this:
query_ev = "select "
" + var1 + " as variable1, " + var2 + " as var 2 "+
from dual";
I am without Java right now to verify but I think this approach could help formatting. Just check that you have enough spaces - don't do this
"as var 2"+"from dual"
which would result in SQL like
"as var 2from dual"

Related

How to create a dynamic query using collection-valued named parameters?

As the title suggests, i'm currently trying to add parts to the JPQL-query using collection-valued named parameters (:queryLst).
Function call:
List<PanelSet> psetLst = setRepository.getMaxZchnrGroupByLeftEight(p.getCustomerNumber(), p.getDrawingNumber(), queryLst);
queryLst:
// Is used to store values from scanned and convert them into parts of a query
ArrayList<String> queryLst = new ArrayList<>();
for (int i = 0; i < size1; i++) {
scanEdvRev = scanned.get(i).toString();
queryLst.set(i, "and left(a.drawingnumber, 8) != left('" + scanEdvRev + "', 8)");
}
SetRepository:
public interface SetRepository extends CrudRepository<PanelSet, Integer> {
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber (:queryLst) "
+ "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("queryLst") ArrayList<String> queryLst);
}
When i run the project i get the following exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 159 [select distinct max(a.drawingNumber) from com.asetronics.qis2.model.PanelSet a where a.customerNumber = :customerNumber and a.drawingNumber != :drawingNumber (:queryLst) group by left(a.drawingNumber, 8)]
I'm unsure whether my approach to this problem is the correct way of doing this and whether this exception is caused by a simple syntax error or by my usage of collection-valued named parameters.
I've followed this guide trying to solve the problem.
EDIT: I'm basically trying to add each String from ArrayList<String> queryLst to the parametrized query inside setRepository.
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber (:queryLst) "
+ "group by left(a.drawingNumber, 8)")
If successful, the query behind the function
List<PanelSet> getMaxZchnrGroupByLeftEight(#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("queryLst") ArrayList<String> queryLst);
should look like this:
queryStr = "select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = " + customerNumber + ""
+ "and a.drawingNumber != " + drawingNumber + "";
for (String s : queryLst) {
queryStr = queryStr + s;
}
queryStr = queryStr + " group by left(a.drawingNumber, 8)";
I hope this clarifies what i'm trying to do with queryLst.
It can't be done using your approach of passing in a list of query chunks.
The closest you'll get is by adding every possible condition to the query and provide values for all those conditions in a way that allows conditions to be ignored, typically by providing a null.
You code might look like this:
#Query("select distinct max(a.drawingNumber) from PanelSet a "
+ "where a.customerNumber = :customerNumber "
+ "and a.drawingNumber != :drawingNumber "
+ "and a.myTextColumn = coalesce(:myTextColumn, a.myTextColumn) "
+ "and a.myIntegerColumn = coalesce(:myIntegerColumn, a.myIntegerColumn) "
// etc for all possible runtime conditions
+ "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(
#Param("customerNumber") String customerNumber,
#Param("drawingNumber") String drawingNumber,
#Param("myTextColumn") String myTextColumn,
#Param("myIntegerColumn") Integer myIntegerColumn);
Passing null for myTextColumn or myIntegerColumn will allow that column to be any value (except null).
You'll have to find SQL that works for the type of conditions you have and the data type of the columns involved and whether nulls are allowed.
If passing nulls doesn't work, use a special value, perhaps blank for text columns and some "impossible" date like 2999-01-01 fir date columns etc and code the condition like:
and (a.myCol = :myCol or :myCol = '2999-01-01')

Do you know how to fix this UPDATE issue?

When this code runs, I get an UPDATE writing error. Does anybody know what the problem is, and how to fix it?
This is the code:
string sql2 = "UPDATE ezuser";
sql2 += " SET fname = '" + Request.Form["fname"]+ "'";
sql2 += " , lname = '" + Request.Form["lname"] + "'";
sql2 += " , fav = '" + Request.Form["fav"] + "'";
sql2 += " , pw = '" + Request.Form["pw"] + "'";
sql2 += " , order = '" + Request.Form["order"] + "'";
sql2 += " WHERE email = '" + Request.Form["email"] + "'";
MyAdoHelper.DoQuery(fileName, sql2);
Eventhough the question doesnt tell me much about the datatypes of columns, the only thing I could suspect here is the order column, which might be of integer datatype and you might be passing string to that.
Additional note: your code looks very much vulnerable to sql injections. Please take a look into that as well.
At least in SQL Server, order is a reserved keyword and needs to properly quoted if used literally as a column name. Like so:
sql2 += " , [order] = '" + Request.Form["order"] + "'";
As sabhari already mentioned, you need to learn about SQL Injection and how to properly guard against that. Research parametrized statements for the programming language you are using.

Oracle SQL Select Query Not Working in VB.NET Works Fine in SQL +

When my query executes within my VB application I am receiving the following error:
ORA-00942: table or view does not exist
All table names in my query are spelt correctly, and do in fact exist.
If I dump the query from my VB.net app and then run the query manually in Oracle SQL Plus it executes just fine.
In both cases I am logged in with the exact same credentials and have selected the same database. For my connection within visual basic I am using OleDb.
From within my visual basic application I also ran a query to dump all tables which the user has access to using
select table_name from all_tables
And the table names which I am querying show up.
Any idea what would be causing this?
SELECT
RSS.STEP_STATUS_DATE,
RSS.VALUE_RECORDED
FROM
ITR,
REPORT R,
INSTRUCTION I,
INSTRUCTION_STEP INS,
REPORT_STEP RS,
REPORT_STEP_STATUS RSS
WHERE
ITR.ITR_NO = '1' AND
I.INSTRUCTION_ID = '12345' AND
INS.STEP_NO = '2' AND
R.INSTRUCTION_ID = I.INSTRUCTION_ID AND
RS.REPORT_ID = R.REPORT_ID AND
RS.INSTRUCTION_STEP_ID = INS.INSTRUCTION_STEP_ID AND
RSS.REPORT_STEP_ID = RS.REPORT_STEP_ID AND
RSS.MEASUREMENT_NAME = 'ESN'
My visual basic code is as follows:
strQuery = "SELECT RSS.STEP_STATUS_DATE, " +
" RSS.VALUE_RECORDED " +
"FROM ITR, " +
" REPORT R, " +
" INSTRUCTION I, " +
" INSTRUCTION_STEP INS, " +
" REPORT_STEP RS, " +
" REPORT_STEP_STATUS RSS " +
"WHERE ITR.ITR_NO = '%01' AND " +
" I.INSTRUCTION_ID = '%02' AND " +
" INS.STEP_NO = '%03' AND " +
" R.INSTRUCTION_ID = I.INSTRUCTION_ID AND " +
" RS.REPORT_ID = R.REPORT_ID AND " +
" RS.INSTRUCTION_STEP_ID = INS.INSTRUCTION_STEP_ID AND " +
" RSS.REPORT_STEP_ID = RS.REPORT_STEP_ID AND " +
" RSS.MEASUREMENT_NAME = '%04'"
I'm looking at this portion (and others like it):
RSS.MEASUREMENT_NAME = '%04'
I expect you meant to do this:
RSS.MEASUREMENT_NAME LIKE '%04'
While I'm here, almost no one uses the "A,B" join syntax any more. It's extremely out-dated, and can lead to errors where join conditions are applied to the wrong tables, such that the query doesn't return any results... in other words, it might even be causing the problem you have right now.

Pass a SQL condition as a OleDb parameter

I have following code:
Dim executedCmd As OleDb.OleDbCommand = m_dbMgr.GetCommand()
executedCmd.CommandText = "select * from [Parameters] where "
Dim SQLcondition As String = String.Empty
For i As Integer = 0 To ParameterName.Count - 1
executedCmd.CommandText += "ParameterName = #parametername" + i.ToString() + " and ParameterValue #ParamaterCondition" + i.ToString() + " #ParameterValue" + i.ToString()
executedCmd.Parameters.AddWithValue("#parametername" + i.ToString(), ParameterName(i))
executedCmd.Parameters.AddWithValue("#ParameterValue" + i.ToString(), ParameterValue(i))
executedCmd.Parameters.AddWithValue("#ParamaterCondition" + i.ToString(), Condition(i))
Next
ParameterName, ParameterValue, ParameterCondition all are same length ArrayList, but the code does not work properly. I have verified all the variables have values.
When I run the code it reports a syntax error: "missing operations in query expression"
The problem is that ParameterCondition has values like ('>', '<', '=',.... some logical SQL operators).
Edit: How can I include conditions in parameters?
Add 1 = 1 after where to simplify building logical expression. Notice that all conditions added by AND logical operator. You can generate parameter name from columns name.
executedCmd.CommandText = "select * from [Parameters] where 1 = 1"
....
executedCmd.CommandText += " AND " + ParameterName(i) + " " + Condition(i) + " #" + ParameterName(i)
executedCmd.Parameters.AddWithValue("#" + ParameterName(i), ParameterValue(i))
ParameterCondition must all be binary operators.
The database engine would check the syntax of the SQL statement before it replaces the parameters with values. So somethinhg like "WHERE #p1 #p2 #p3" will not be parsed correctly.
Replace your condition with a string-expression e.g.
commandtext = parameterName + condition + " #p1"

SQL Server Dynamic SQL

I am executing Dynamic SQL,
sqlQuery = " SELECT ";
sqlQuery += _Allowed + " , ";
sqlQuery += " + cast( ";
sqlQuery += " _ID as nvarchar ) ";
sqlQuery += " FROM ";
sqlQuery += " TBL_SUCCESS ";
when i execute it suppose to return common separated values like 2,4,5 in single column
instead it return values in separate column
my MyDataTable suppose to populate
Column1
2,4,5
but it populates
column1 column2 column3
2 4 5
How to get the output?
Need to see the value of _Allowed to know what else is happening, but you need to at least put quotes around the comma and concatenate it inside the SQL statement, like this:
sqlQuery += _Allowed + " + ' , ' ";