jdbcTemplate - queryForList - Invalid Column Type Error - spring

The table name will be dynamic and need to return the list of objects dynamically. The parameters also dynamic however 4 parameters will be same for any table.
Method name accepts the table name and 4 parameters required to query any table
List<?> conversations = jdbcTemplate.queryForList(
"select * from "+ tableName + " where id=? and userName=? and
password=? and tenantId=?" , paramsObjectArray);
tableName is a string which comes dynamically
paramsObjectArray is a Object[] which comes dynamically
Currently the query throws invalid column type.
Thanks.

Your paramsObjectArray contains wrong values. It should correspond with the ? in order declared in your SQL.
It will bind for each ? the correct value.
Now if one of the values in your paramsObjectArray is not what's expected, it will fail.
It could be that id in your db is integer, but you are giving it a String or tenantId - should be an integer I guess, but you are giving String.
Read the docs first.

Related

Nifi throwing None of the fields in the record map to the columns defined by [table name]

Am trying execute a sql query on oracle database and inserting the result into another table, for my trial am just performing a simple query as
SELECT 1 AS count
FROM dual
and trying to insert that into a single column table which has the name COUNT.
The content of the record on Nifi seems to be as follows
[
{
"COUNT" : "1"
}
]
but the logs keeps throwing the error
due to java.sql.SQLDataException:
None of the fields in the record map to the columns defined by
the schema_name.table_name table:
any ideas ?
I believe you get that same error message if your table name doesn't match. The Translate Field Names property only translates the fields (columns), not the table name. Try specifying the schema/table in uppercase to match what Oracle is expecting.

How to UPDATE multiple rows, based on multiple conditions?

I'm trying to update a single column in a table for many rows, but each row will have a different updated date value based on a unique where condition of two other columns. I'm reading the data from a csv, and simply updating the date column in the row located from the combination of values in the other two columns.
I've seen this
SQL update multiple rows based on multiple where conditions
but the SET value will not be static, and will need to match each row where the other two column values are true. This is because in my table, the combination of those two other columns are always unique.
Psuedocode
UPDATE mytable SET date = (many different date values)
WHERE col_1 = x and col_2 = y
col_1 and col_2 values will change for every row in the csv, as the combination of these two values are unique. I was looking into using CASE in postgres, but I understand it cannot be used with multiple columns.
So basically, a csv row has a date value, that must be updated in the record where col_1 and col_2 equals their respective values in the csv rows. If these values don't exist in the database, they are simply ignored.
Is there an elegant way to do this in a single query? This query is part of a spring batch job, so I might not be able to use native postgres syntax, but I'm struggling to even understand the format of the query so I can worry about the syntax later. Would I need multiple update statements? If so, how can I achieve that in the write step of a spring batch job?
EDIT: Adding some sample data to explain process
CSV rows:
date, col_1, col_2
2021-12-30, 'abc', 'def'
2021-05-30, 'abc', 'zzz'
2021-07-30, 'hfg', 'xxx'
I'll need my query to locate a record where col_1='abc' AND col_2=def, then change the date column to 2021-12-30. I'll need to do this for every row, but I don't know how to format the UPDATE query.
You can insert your CSV data into a (temporary) table (say mycsv) and use UPDATE with a FROM clause. For instance:
CREATE TEMP TABLE mycsv (date DATE, col_1 TEXT, col_2 TEXT);
COPY mycsv FROM '/path/to/csv/csv-file.csv' WITH (FORMAT csv);
UPDATE mytable m SET date = c.date
FROM mycsv c WHERE m.col_1 = c.col_1 AND m.col_2 = c.col_2;
Create an Itemwriter implementation, and override the write() method. That method accepts a list of objects, each returned from your ItemProcessor implementation.
In the write method, simply loop through the objects, and call update on each one in turn.
For Example:
In the ItemWriter:
#Autowired
private SomeDao dataAccessObject;
#Override
public void write(List<? extends YourDTO> someDTOs) throws Exception {
for(YourDTO dto: someDTOs) {
dataAccessObject.update(dto);
}
}
In your DAO:
private static final String sql = "UPDATE mytable SET dateField = ? WHERE col_1 = ? and col_2 = ?";
public void update(YourDTO dto) {
Object[] parameters = { dto.getDate(), dto.getCol1(), dto.getCol2()};
int[] types = {Types.DATE, Types.STRING, Types.STRING};
jdbcTemplate.update(sql, parameters, types);
}

Retrieving autoincrement value when using #JdbcInsert

I'm trying to store a row in a DB2 database table where the primary key is an autoincrement. This works fine but I'm having trouble wrapping my head around how to retrieve the primary key value for further processing after successfully inserting the row. How do you achieve this? #JdbcInsert only returns the amount of rows that were inserted ...
Since there does not seem to be a way to do this with SSJS (at least to me), I moved this particular piece of logic from my SSJS controller to a Java helper bean I created for JDBC related tasks. A Statement is capable of handing back generated keys (using the method executeUpdate()). So I still create my connection via #JdbcGetConnection, but then hand it in into the bean. This is the interesting part of the bean:
/**
* SQL contains the INSERT Statement
*/
public int executeUpdate(Connection conn, String SQL){
int returnVal;
Statement stmt = conn.createStatement();
stmt.executeUpdate(SQL,
Statement.RETURN_GENERATED_KEYS);
if(!conn.getAutoCommit()) conn.commit();
ResultSet keys = stmt.getGeneratedKeys();
if(keys.next()){
returnVal = keys.getInt(1);
} else {
returnVal = -1;
}
return returnVal;
}
If you insert more than one row at a time, you'll need to change the key retrieval handling, of course.
In newer DB2 Versions you can transform every Insert into a Select to get automatic generated key columns. An example is:
select keycol from Final Table (insert into table (col1, col2) values (?,?))
keycol is the name of your identity column
The Select can be executed with the same #Function than your usual queries.

SSRS - Pass MDX parameter value to SQL query

I have a EmployeeID parameter:
="[Employee].[Employee Id].&[12345678912345]"
I have a SQL query that calls for EmployeeID parameter like this:
Where...AND (EmployeeID = #EmployeeID)
I then go into the sql dataset's parameters list and set EmployeeID's value to:
=LEFT(RIGHT(Parameters!EmoloyeeID.Value,15),14)
This should give 12345678912345. EmployeeID column in SQL table has datatype of nvarchar(25).
Now when I use lookup to connect Cube's dataset (dataset of the tablix I am working on) with this SQL dataset,
=Lookup(Cube's EmployeeName field, SQL's EmployeeName field, SQL's EmployeeStatus, "SQLDataSet")
I get no output. I get blank. (I know for fact that there is data because when I execute SQL query in SSMS with EmployeeID declared to 12345678912345, I get right EmployeeeName (matches with Cube's EmployeeName value) and EmployeeStatus values.
What am I doing wrong? Am I doing something wrong to EmployeeID parameter's value manipulation?
Is this a typo?
=LEFT(RIGHT(Parameters!EmoloyeeID.Value,15),14)
Just want to check to ensure it's not a simple fix :-)

LINQ - How to insert null DateTime into database column?

Using LINQ, how do I insert a null value into a SQL Server 2008 DateTime column?
The code below inserts "1/1/1900 12:00:00 AM",
But I want to insert "NULL" instead
CreatDate = System.Data.SqlTypes.SqlDateTime.Null
Ensure that the column in the DB is set to allow NULL and your entity property, "CreateDate" is defined as "DateTime? CreateDate {get;set;}". Then, simply set "CreateDate = null".
Your CreateDate property needs to be declared Nullable<DateTime> (aka DateTime?). Then, you can set that property on your Linqed-up object to null (not System.Data.SqlTypes.SqlDateTime.Null, just plain old C# null) and you should get the desired result. This of course assumes that your SQL table has the column properly defined to allow NULLs and that your definition for the column in the DBML also allows them.

Resources