JDBC SQL : if statement string == char.toString not working. :) - sql

How come my if statement if (tablename == Character.toString('S')) is not registering as true? Both print out the be S... Is there a different why I can implement this? I could do a != but I need to add more arguments to my if statement, and my tablename needs to stay a string.
System.out.println("Enter table:");
String line = input.readLine();
StringTokenizer tk = new StringTokenizer(line);
String tablename = tk.nextToken();
DatabaseMetaData d = conn.getMetaData();
ResultSet rm = d.getColumns(null, null, tablename, null);
System.out.println(tablename);
System.out.println(Character.toString('S');
System.out.println(tablename == Character.toString('S');
if (tablename == Character.toString('S')){
System.out.println("Woot!");
}
OUTPUT:
Enter table:
S
S
S
false

Since you're comparing both objects for equality, you need to use:
if (tablename.equals(Character.toString('S'))) {
...
Here's a nice reference on equality comparison in java:
http://leepoint.net/notes-java/data/expressions/22compareobjects.html

The == only relates to the equality of the pointer that Character.toString() returns. Need to use the below.
tablename.equals(Character.toString('s'))

Related

How to set large string as param without getting ORA-01460: unimplemented or unreasonable conversion error?

In spring-boot using namedParameterJdbcTemplate (Oracle db version 12 and odbc8 driver 12.2)
I am getting the following error while executing a SELECT query bound with a parameter larger than 4000 character whereas update queries working fine.
ORA-01460: unimplemented or unreasonable conversion requested
The unit test I am trying to execute;
#Test
public void testSqlSelectQueryLargeStringParameter() {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("param", theLargeStr);
// #formatter:off
String sql =
"SELECT NULL id, NULL text FROM DUAL WHERE 'X' != :param ";
// #formatter:on
namedParameterJdbcTemplate.queryForRowSet(sql, params);
}
Is there any way to set this large param via MapSqlParameterSource?
I am #ahmet-orhan 's colleague, we've found a solution.
Thanks #kfinity for your suggestion, It is working for insert and update but we are still getting this error when we set clob or blob as "paremeter" in select statements.
If using a driver that supports JDBC4.0, the right solution is create a DefaultLobHandler and set streamAsLob or createTemporaryLob to true.
MapSqlParameterSource params = new MapSqlParameterSource();
String myString = "";
for (int i = 0; i < MAX_CLOB_BLOB_SIZE_IN_SELECT; i++) {
myString = myString + "1";
}
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setStreamAsLob(true);
params.addValue("param", new SqlLobValue(myString, lobHandler), Types.CLOB);
// #formatter:off
String sql =
"SELECT 1 id FROM DUAL WHERE :param IS NOT NULL ";
// #formatter:on
Integer id = namedParameterJdbcTemplate.queryForObject(sql, params, Integer.class);
We prefer streamAsLob but to be honest we have no idea which one is better.
This comment points out that ORA-01460 in JDBC queries is the same as "ORA-01704: string literal too long". (You can't have string literals longer than 4000 characters.) Maybe try this solution?
params.addValue("param", theLargeStr, Types.CLOB);
Although also != won't work for clob comparison, so you'll also need to change your query to
SELECT NULL id, NULL text FROM DUAL WHERE dbms_lob.compare('X',:param) != 0

how do I compare values from List using simple Odata filter?

How do I write a filter which will compare Mylist-values to MyKeyTable-values?
I tried something like the following:
List<string> Mylist = new List<string>();
Mylist.Add("Welcome");
Mylist.Add("Hello");
var output = await client.For<MyKeyTable>()
//this is wrong I knew I need to correct this
.Filter(Mylist.Contains(x=>x.Key))
.FindEntriesAsync();
So output will come with all the values whoes Key-value matches as welcome and hello
Thanks in advance.
Done I tried it using custom expression
ParameterExpression pe = Expression.Parameter(typeof(MyTableClass), "entity");
Expression expression = null;
Expression predicateBody = null;
Expression leftExpression = Expression.Property(pe, "Key");
Expression rightExpression = Expression.Constant("Welcome");
expression = Expression.Equal(leftExpression, rightExpression);
predicateBody = predicateBody == null
? expression
: Expression.OrElse(predicateBody, expression);

ResultSet coming as empty after executing query

I have a query
SELECT instance_guid FROM service_instances WHERE service_template_guid='E578F99360A86E4EE043C28DE50A1D84' AND service_family_name='TEST'
Directly executing this returns me
4FEFDE7671A760A8DC8FC63CFBFC8316
F2F9DF641D8E2CACC03175A7A628D51D
Now I am trying same code from JDBC.
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = executionContext.getConnection();
if (conn != null) {
ps = (PreparedStatement)conn.prepareStatement(query);
if (params == null) params = new Object[0];
for (int i=0;i<params.length;i++) {
if (params[i] instanceof Integer) {
ps.setInt(i+1, ((Integer)params[i]).intValue());
} else if (params[i] instanceof java.util.Date) {
((PreparedStatement)ps).setDATE(i+1, new oracle.sql.DATE((new java.sql.Timestamp(((Date)params[i]).getTime()))));
//ps.setObject(i+1, new oracle.sql.DATE(new Time(((Date)params[i]).getTime())));
} else {
if (params[i] == null) params[i] = "";
ps.setString(i+1, params[i].toString());
}
}
rs = ps.executeQuery();
I see params[0] =E578F99360A86E4EE043C28DE50A1D84 and params[1]=TEST
But the resultSet is empty and not getting the result.I debugged but not much help?
Can you please let me know Am i trying right?
In java its defined as below
final static private String INSTANCE_GUID_BY_TEMPLATE_GUID =
"SELECT instance_guid FROM service_instances WHERE service_template_guid=? AND service_family_name=? "
SERVICE_FAMILY_NAME NOT NULL VARCHAR2(256)
SERVICE_TEMPLATE_GUID NOT NULL RAW(16 BYTE)
First and foremost this breaks every sql mapping pattern I have ever seen.
String sql = "SELECT instance_guid FROM service_instances WHERE service_template_guid=? AND service_family_name=?";
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = executionContext.getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1,guid);
ps.setString(2,family);
rs = ps.executeQuery();
while(rs.next(){...}
...
}
You should not be dynamically figuring out the data types as they come in, unless you are trying to write some code to port from database X to database Y.
UPDATE
I see you are using RAW as a datatype, from this post:
As described in the Oracle JDBC Developer's guide and reference 11g,
when using a RAW column, you can treat it as a BINARY or VARBINARY
JDBC type, which means you can use the JDBC standard methods
getBytes() and setBytes() which returns or accepts a byte[]. The other
options is to use the Oracle driver specific extensions getRAW() and
setRAW() which return or accept a oracle.sql.RAW. Using these two will
require you to unwrap and/or cast to the specific Oracle
implementation class.
Further from a code readability standpoint, your solution makes it painful for a new developer to take over. Far too often I see people making sql be "dynamic" when in reality 99% of the time you don't need this level of dynamic query building. It sounds good in most people's heads but it just causes pain and suffering in the SDLC.

Can I pass parameters to UDFs in Pig script?

I am relatively new to PigScript. I would like to know if there is a way of passing parameters to Java UDFs in Pig?
Here is the scenario:
I have a log file which have different columns (each representing a Primary Key in another table). My task is to get the count of distinct primary key values in the selected column.
I have written a Pig script which does the job of getting the distinct primary keys and counting them.
However, I am now supposed to write a new UDF for each column. Is there a better way to do this? Like if I can pass a row number as parameter to UDF, it avoids the need for me writing multiple UDFs.
The way to do it is by using DEFINE and the constructor of the UDF. So here is an example of a customer "splitter":
REGISTER com.sample.MyUDFs.jar;
DEFINE CommaSplitter com.sample.MySplitter(',');
B = FOREACH A GENERATE f1, CommaSplitter(f2);
Hopefully that conveys the idea.
To pass parameters you do the following in your pigscript:
UDF(document, '$param1', '$param2', '$param3')
edit: Not sure if those params need to be wrappedin ' ' or not
while in your UDF you do:
public class UDF extends EvalFunc<Boolean> {
public Boolean exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return false;
FileSystem fs = FileSystem.get(UDFContext.getUDFContext().getJobConf());
String var1 = input.get(1).toString();
InputStream var1In = fs.open(new Path(var1));
String var2 = input.get(2).toString();
InputStream var2In = fs.open(new Path(var2));
String var3 = input.get(3).toString();
InputStream var3In = fs.open(new Path(var3));
return doyourthing(input.get(0).toString());
}
}
for example
Yes, you can pass any parameter in the Tuple parameter input of your UDF:
exec(Tuple input)
and access it using
input.get(index)

.NET 4 - Using nullable operator (??) to simplify if statements

I have this piece of code, that checks whether a returned object is null. If so, it will return 0, or else it will return a property inside the object.
var userPoints = (from Point p in entities.Point
where p.UserName == userName
select p).SingleOrDefault();
if (userPoints == null)
{
return 0;
}
else
{
return userPoints.Points;
}
Is it possible to simplify the if statements with the nullable operator? I've tried this, but the system throws an exception when attempting to read the property
return userPoints.Points ?? 0;
No, unfortunately there's nothing which will do exactly that. Options:
Use the conditional operator:
return userPoints == null ? 0 : userPoints.Points;
Change your query to make that do the defaulting:
return (from Point p in entities.Point
where p.UserName == userName
select p.Points).SingleOrDefault();
Personally I'd go for the latter approach :) If you wanted a default other than 0, you'd need something like:
return (from Point p in entities.Point
where p.UserName == userName
select (int?) p.Points).SingleOrDefault() ?? -1;
You can do this:
var userPoints = (from Point p in entities.Point
where p.UserName == userName
select p.Point).SingleOrDefault();
return userPoints;
If there are no results then userPoints will be 0, otherwise it will be the value of Points.
You can't use it in your context.
Explanation:
You want to check whether userPoints is null, but want to return userPoints.Points if it is not null.
The ?? operator checks the first operand for null and returns it, if it is not null. It doesn't work if what you want to check and what you want to return are two different things.
Hover over var with the mouse and see what type it is.