Java and MSSQL problems with getting data from database - java

Okay im getting a bit confused atm, im trying to retrieve some data from a datebase using java and mssql.
In sql i write this:
use MyChamp SELECT *
FROM [GROUP]
JOIN Team on [Group].GroupID = Team.GroupID
JOIN Match on Team.TeamID = HomeTeamID
WHERE [GROUP].GroupID = 9
and it work.
In java my string to execute looks like this:
String sql = "SELECT * FROM [GROUP]"
+ "JOIN Team on [Group].GroupID = Team.GroupID"
+ "JOIN Match on Team.TeamID = HomeTeamID"
+ "WHERE [GROUP].GroupID = 9"
+ "ORDER BY MatchRound:";
It does not work i get sql error msg saying:
Error: S0001Incorrect syntax near 'Match'.
but i cant find the error :(

Put spaces after string termination quote "
String sql = "SELECT * FROM [GROUP] "
+ "JOIN Team on [Group].GroupID = Team.GroupID "
+ "JOIN Match on Team.TeamID = HomeTeamID "
+ "WHERE [GROUP].GroupID = 9 "
+ "ORDER BY MatchRound "
If you don't your string will be generated like this.
SELECT * FROM [GROUP]JOIN Team on [Group].GroupID = Team.GroupIDJOIN Match on Team.TeamID = HomeTeamIDWHERE [GROUP].GroupID = 9ORDER BY MatchRound

Related

Jpa native query doesnt work with group by case/when statement with binding values

Iam trying to use Jpa repository to get data from my sql server using a native query
This is a simple call from my service
repo.testData("h3","h3");
This is my repository query.
Select statement can read the binding variable :level but group by is unable to read it.
#Query(value="SELECT sum(pos.total_weekly_sales) as curr_yr_sales, sum(pos.total_weekly_qty) as curr_yr_qty, pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when :level = 'h3' then pos.category_id\n" +
"else 0\n" +
"end category_id\n" +
"from dbo.agg_sams_data pos\n" +
"join dbo.calendar_dim cal on pos.wm_year_wk_nbr = cal.wm_year_wk_nbr\n" +
"WHERE \n" +
"cal.calendar_date BETWEEN '2019-09-11' and '2020-09-09'\n" +
"and pos.vendor_nbr = 68494\n" +
"and pos.gmm_id = 45\n" +
"and (:h3Flag = 'N' or pos.category_id = 52)\n" +
"GROUP by pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when :level='h3' then pos.category_id\n" +
"else 0\n" +
"end",nativeQuery = true)
List<List<Double>> testData(String level,String h3Flag);
And i get the following error
com.microsoft.sqlserver.jdbc.SQLServerException: Column 'dbo.agg_sams_data.category_id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If i pass the hardcoded value in the group by clause it works fine(as below)
"GROUP by pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when 'h3'='h3' then pos.category_id\n"
You should try putting pos.category_id into the group by instead of the whole case when statement. The problem is, that SQL Server can't be sure that the parameter in both cases will have the same value so the expressions could be different.

sql syntax error, but concatenated text runs fine in Datagrip

I'm trying to run a query, but I get an error when running it.
However, I'm using Intellij and when I use the copy string concatenation to clipboard feature, and run the query in the datagrip, the query runs fine (after putting in the parameters)
The error I am getting is "ERROR: syntax error at or near "tstoredarticle"\n Position: 199"
I find it a bit weird that it's showing there's a line change, after tstoredartiacle but besides that I don't see what's wrong.
What could be some issues that could cause a problem like that?
my query in intellij looks like this:
private ResultSet getHuaweiSqlQuery(Integer intBrandID, Integer intStorageID, Vector<Integer> vecArticleTypes, int iCurrencyID, int iContactSupplierID, int secondaryStorage, BigDecimal exchangeRate) throws SQLException {
return Hibernate3To4Utils.getConnection(session).createStatement().executeQuery("SELECT storedarticleid, "
+ " CASE WHEN storedarticle_storageid = " + intStorageID
+ " THEN id_storedarticleid_replacement ELSE"
+ " (SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)"
+ " FROM etel.tstoredarticle x"
+ " WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid"
+ " AND x.storedarticle_storageid = " + intStorageID + ")"
+ " END as id_storedarticleid_replacement,"
+ " articlename,"
+ " articledescription, CASE WHEN price IS NULL THEN last_innprice*" + exchangeRate
+ " ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,"
+ " amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location"
+ " FROM etel.tstoredarticle"
+ " INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid"
+ " LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid"
+ " AND ((tusedarticle.datesnap >= CAST(now() as date)-" + LOOK_BACK_DAYS
+ " AND usedarticlefromstorage = true) OR waiting = true)"
+ " LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = " + Constants.SERVICEPLACE
+ " LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid"
+ " AND tsupplier_price.id_serviceplaceid = " + Constants.SERVICEPLACE
+ " AND tsupplier_price.id_currencyid = " + iCurrencyID
+ " AND tsupplier_price.id_contactid_supplier = " + iContactSupplierID
+ " LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid"
+ " AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where"
+ " latest_usedarticle.usedarticle_storedarticleid = storedarticleid)"
+ " WHERE storedarticle_storageid IN(" + intStorageID + ", " + secondaryStorage + ") AND b.id_brandid = " + intBrandID
+ " AND id_articletypeid IN (" + getStringFromArray(vecArticleTypes.toArray()) + ")"
+ " AND tstoredarticle.passive <> true"
+ " GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],"
+ " storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap"
+ " ORDER BY id_storedarticleid_replacement, storedarticleid");
}
and here's the same query after using the copy string concatenation to clipboard feature:
(this runs fine)
SELECT storedarticleid,
CASE WHEN storedarticle_storageid = ?
THEN id_storedarticleid_replacement ELSE
(SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)
FROM etel.tstoredarticle x
WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid
AND x.storedarticle_storageid = ?)
END as id_storedarticleid_replacement,
articlename,
articledescription, CASE WHEN price IS NULL THEN last_innprice*?
ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,
amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location
FROM etel.tstoredarticle
INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid
LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid
AND ((tusedarticle.datesnap >= CAST(now() as date)-42
AND usedarticlefromstorage = true) OR waiting = true)
LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = ?
LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid
AND tsupplier_price.id_serviceplaceid = ?
AND tsupplier_price.id_currencyid = ?
AND tsupplier_price.id_contactid_supplier = ?
LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid
AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where
latest_usedarticle.usedarticle_storedarticleid = storedarticleid)
WHERE storedarticle_storageid IN(?, ?) AND b.id_brandid = ?
AND id_articletypeid IN (?)
AND tstoredarticle.passive <> true
GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],
storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap
ORDER BY id_storedarticleid_replacement, storedarticleid
Don't use string concatenation with dynamic text values to build a SQL statement.
For one, if the text values are supplied by a user, you're leaving yourself vulnerable to SQL injection attacks, allowing hackers to steal your data and delete your tables.
But you also have problems getting the text values quoted and escaped correctly.
Instead, use a PreparedStatement, where you place ? markers anywhere a dynamic value needs to go. That is the string in the clipboard.
Example: You're doing:
String name = "John";
String sql = "SELECT * FROM Person WHERE name = " + name;
That gives you this text at runtime:
SELECT * FROM Person WHERE name = John
which is wrong, because the text value needs to be quoted:
SELECT * FROM Person WHERE name = 'John'
You could try
String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = '" + name + "'";
but that's also wrong, because this new text value has embedded quotes and would produce:
SELECT * FROM Person WHERE name = 'John's Cross'
To get it right, use a PreparedStatement:
String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = ?";
PreparedStatement stmt = Hibernate3To4Utils.getConnection(session).prepareStatement(sql);
stmt.setParameter(1, name);
return stmt.executeQuery();
The JDBC driver will take care of any escaping needed, and thereby protects you from both SQL injection attacks and SQL syntax errors.

I get a error in this sql statement in java, but it works in SQLite Studio. It says something is wrong near 'from'

I made this query on SQLite studio and now I am using it on a Android Application in Android Studio. In SQLite Studio, I get exactly what I need, but it closes the app whenever I call it on Android. The error message is:
Unable to start activity ComponentInfo{br.com.buraji.buraji/br.com.buraji.buraji.kanji_detalhes}: android.database.sqlite.SQLiteException: near "from": syntax error (code 1): , while compiling: select Kunyomi.leitura, Kunyomi. from Kunyomi where Kunyomi.idKanji = 1
select
Kunyomi.leitura,
\'くん\'as tipo,
VocabularioKun.vocabulario,
VocabularioKun.hiragana,
VocabularioKun.traducao,
VocabularioKun.exemploKanji,
VocabularioKun.exemploHiragana,
VocabularioKun.exemploTraducao
from Kunyomi
inner join VocabularioKun on Kunyomi._id = VocabularioKun.idKunyomi
where Kunyomi.idKanji = 1
union
select
Onyomi.leitura,
\'おん\' as tipo,
VocabularioOn.vocabulario,
VocabularioOn.hiragana,
VocabularioOn.traducao,
VocabularioOn.exemploKanji,
VocabularioOn.exemploHiragana,
VocabularioOn.exemploTraducao
from Onyomi join VocabularioOn on Onyomi._id = VocabularioOn.idOnyomi
where Onyomi.idKanji = 1
The string I am using is as follows:
Cursor c = myDataBase.rawQuery("select Kunyomi.leitura, \'くん\'as tipo, VocabularioKun.vocabulario, VocabularioKun.hiragana, VocabularioKun.traducao, VocabularioKun.exemploKanji, VocabularioKun.exemploHiragana, VocabularioKun.exemploTraducao from Kunyomi join VocabularioKun on Kunyomi._id = VocabularioKun.idKunyomi where Kunyomi.idKanji = 1 union select Onyomi.leitura,\'おん\' as tipo, VocabularioOn.vocabulario, VocabularioOn.hiragana, VocabularioOn.traducao, VocabularioOn.exemploKanji, VocabularioOn.exemploHiragana, VocabularioOn.exemploTraducao from Onyomi inner join VocabularioOn on Onyomi._id = VocabularioOn.idOnyomi where Onyomi.idKanji = 1", null);
I have no idea why there's this second Kunyomi. in the error message. It's not on the query. Any help please?
I solved this by putting a wild card instead of the various selects statements and it worked. I have no idea why:
Cursor c = myDataBase.rawQuery("select *, 'くん' as tipo " +
"from Kunyomi, " +
"VocabularioKun " +
"where Kunyomi._id = VocabularioKun.idKunyomi " +
"and Kunyomi.idKanji = 18" +
" union " +
"select *, 'おん' as tipo " +
"from Onyomi, " +
"VocabularioOn where Onyomi._id = " +
"VocabularioOn.idOnyomi and Onyomi.idKanji = 18", null);

SQLite fails to find existing column in SELECT via JDBC and jOOQ

I experience some strange results working with SQLite and JDBC (via JOOQ actually, but this problem can be reproduced by executing the query string manually via JDBC). My database consists of a three tables including a many-to-many and one-to-many relationship. I try to select all values of the 'main' table and join all needed values out of the relationship tables:
SELECT location.name,
world.world,
player.player
FROM location
JOIN world
ON location."world-id" = world."world-id"
LEFT OUTER JOIN (location2player
JOIN player
ON location2player."player-id" = player."player-id")
ON location."location-id" = location2player."location-id"
Within JDBC this query fails:
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such column: player.player)
When I execute the query in an external SQLite editor such as SQLite Manager for Firefox it works as expected.
I work with sqlite-jdbc-3.7.2 which I cannot change. For reference, the JOOQ query is:
create.select(LOCATION.NAME,WORLD.WORLD_,PLAYER.PLAYER_)
.from(LOCATION
.join(WORLD)
.on(LOCATION.WORLD_ID.eq(WORLD.WORLD_ID)
)
.leftOuterJoin(LOCATION2PLAYER
.join(PLAYER)
.onKey()
)
.on(LOCATION.LOCATION_ID.eq(LOCATION2PLAYER.LOCATION_ID)
)
.fetch()
Why fails this query in JDBC and how am I supposed to fix it?
While I think that you wrote valid ANSI SQL, it may well be that SQLite interprets your statement slightly differently. But you don't really need to nest joins the way you do. Try this insted:
SELECT location.name,
world.world,
player.player
FROM location
JOIN world
ON location."world-id" = world."world-id"
LEFT OUTER JOIN location2player
ON location."location-id" = location2player."location-id"
LEFT OUTER JOIN player
ON location2player."player-id" = player."player-id"
I was able to recreate your issue under sqlite-jdbc-3.7.2 using
sql =
"SELECT location.name, " +
"world.world, " +
"player.player " +
"FROM " +
"location " +
"JOIN world " +
"ON location.\"world-id\" = world.\"world-id\" " +
"LEFT OUTER JOIN (location2player " +
"JOIN " +
"player " +
"ON location2player.\"player-id\" = player.\"player-id\") " +
"ON location.\"location-id\" = location2player.\"location-id\"";
The problem appears to be that the location2player and player tables are "hidden" inside the parentheses () of the sub-join and are unavailable to the initial column list and the final ON clause. The following statement avoids that problem by giving the subquery an alias and using the alias name in those two places:
sql =
"SELECT " +
"location.name, " +
"world.world, " +
"playerlocation.player " +
"FROM " +
"location " +
"JOIN " +
"world " +
"ON location.\"world-id\" = world.\"world-id\" " +
"LEFT OUTER JOIN " +
"( " +
"SELECT location2player.\"location-id\", player.player " +
"FROM " +
"location2player " +
"JOIN " +
"player " +
"ON location2player.\"player-id\" = player.\"player-id\"" +
") AS playerlocation " +
"ON location.\"location-id\" = playerlocation.\"location-id\"";

Trouble with a line of SQL in my java program

So the program is the connecting to a .mdb file as our data base. I have written all the other code to the program and know it works fine but I am now having trouble with a complex SQL statement being passed as a parameter to a createQuery(Sring, int) method.
There are two tables
Person, which has Name, Id, City, State
Classes, which has Id, Course, Grade
The intended purpose of this line is to print out "Name and Id" from a table of Persons and also print "Course and Grade" from the Classes table. The query only prints entries with matching Id's(Person.Id = Classes.Id), in a specific Course('CSC 225'), and that have a Grade > 70.
We never were taught the SQL statements in any depth so my basic understanding has concocted the following lines of code.
String s = "SELECT " + personTableTitle + ".Name, " + personTableTitle + ".Id, " +
classesTableTitle + ".Course, " + classesTableTitle + ".Grade FROM " +
personTableTitle + " " + classesTableTitle + " WHERE " +
personTableTitle + ".ID = " + classesTableTitle + ".Id AND " +
"Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
personTableTitle + ".Id = ? AND " + classesTableTitle + ".Id = ?";
System.out.print(s); // Double check of my SQL Statement before passing
db.createQuery(s, 4);
I have been playing with this SQL statement since Wednesday night and haven't been having much luck.
I only see two problems. Sql needs commas between the table names in the FROM clause, i.e. ...FROM table1, table2 WHERE.... So change your line to
personTableTitle + ", " + classesTableTitle + " WHERE " +
This next one might not be a problem, but it's a good idea to include the table name in front of every field reference.
classesTableTitle + ".Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
You should definitely try your query directly on the database (console or GUI). Once your query is valid, you'll be able to translate it very quickly back into Java.
Otherwise, it's good practice to add an alias to tables; for example:
select *
from Person P, Classes C
where P.Name = 'joe' and P.id = C.id
You may also need to do an outer join to get your data (look at how to do joins for your database).
Here's what I would suggest for SQL code
String s = "SELECT P.Name, P.Id, ";
s = s + "C.Course, C.Grade ";
s = s + "FROM Person P ";
s = s + "JOIN Classes C ";
s = s + "ON P.ID = C.ID ";
s = s + "WHERE Course = 'CIS 225' AND C.Grade > 70;";
I split up each assignment into its own line.
Solved it everyone, thanks for the help.
I started rewriting it using the suggestions posted and came up with this as the string:
String s = "SELECT Person2.Name, Person2.Id, Classes.Course, Classes.Grade FROM Person2, Classes WHERE Classes.Id = Person2.Id AND Classes.Course = 'CIS 225' AND Classes.Grade >70";
It works so I can make it more presentable now. The reason I am using my variable names from java in the original post was that is what the teacher wanted. She is very stubborn and has taken off points from my material for things as simple as writings += whatever; instead of s = s + whatever;

Categories

Resources