I'm trying to write function for selecting optional columns in linq(columns that may not exist). The problem is in linq like this:
using (DataDataContext db = new DataDataContext()){
var collection = from t in table
select new
{
Nonoptional = t.A;
Optional = IsInDB("table","B") ? t.B : -1; //this is optional column
}}
Unfortunately, this won't work because the fragment near Optional will be translated to case statement and error arises that column not exists.
So i decided to "cover" it with function:
using (DataDataContext db = new DataDataContext()){
var collection = from t in table
select new
{
Nonoptional = t.A;
Optional = IsInDB("table","B") ? OptionalColumnValue<int>("table","B","id_table",t.id_table) : -1; //this is optional column
}}
I want this function to be universal. It should work like that" If there is no value or column is nullable and value is null then return default value for type.
I came up with something like this:
//table,column - obvious,id_column - PK column of table, id - id of currently processing record
public static T OptionalColumnValue<T>(string table,string column,string id_columm,int id) T t = default(T);
DataDataContext db = new DataDataContext();
IEnumerable<object> value = db.ExecuteQuery<object>("select " + column + " from " + table + " where " + id_columm + " = " + id.ToString());
List<object> valueList = value.ToList();
if (valueList.Count == 1)//here is the problem
t = (T)valueList.First();
return t;
}
When there is null value db.ExecuteQuery return something like object{}. I'm assuming this is "empty" object,with nothing really in there. I was thinking about checking for "emptiness" of this object( BTW this is not DBull).
When i realised that this is no way either with concrete value in this column(it cannot cast it to return correct type), then I tried db.ExecuteQuery<T>. Then concrete value - OK, null - Exception.
I thought, maybe Nullable<T> as return value. Nop, because string also can be T.
I don't know what to do next. Maybe there's another solution to this problem.
Related
I want to send a sql query by using Spring JPA like :
"SELECT NEW com.blalba.model.service.FamilyMaterialDto "
+ "(ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness, ms.width) "
+ "FROM MaterialInstance mi, FamilyTypeCommodity ftc, MaterialSpecification ms "
+ "WHERE ftc.materialFamily.id = :familyId "
+ "AND (:typeId is null OR ftc.materialType.id = :typeId) "
+ "AND ftc.id = ms.familyTypeCommodity.id "
+ "AND ms.id = mi.materialSpecification.id "
+ "AND mi.materialSpecification.isActive = true"
However, when I remove some fields like "ms.width", I get the error:
Unable to locate appropriate constructor on class [com.commencis.sova.model.service.FamilyMaterialDto]. Expected arguments are: java.lang.String, java.lang.String, com.commencis.sova.model.entity.material.CommodityType, com.commencis.sova.model.entity.material.MaterialType, com.commencis.sova.model.entity.material.Grade, com.commencis.sova.model.entity.material.Thickness [SELECT NEW com.commencis.sova.model.service.FamilyMaterialDto (ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness) FROM com.commencis.sova.model.entity.material.MaterialSpecification ms, com.commencis.sova.model.entity.material.MaterialInstance mi, com.commencis.sova.model.entity.material.FamilyTypeCommodity ftc WHERE ftc.materialFamily.id = :familyId AND (:typeId is null OR ftc.materialType.id = :typeId) AND mi.materialSpecification.isActive = true AND ms.id = mi.materialSpecification.id AND ftc.id = ms.familyTypeCommodity.id]
I understand that return Object[] cannot be parsed to DTO object. If I write constructor without the parameter - "Width", it will work properly. However, I want to provide that a query can be sendable without some parameters(sometimes one of them, sometimes five of them) and a result can be parsable with FamilyMaterialDTO.
How can I do? I don't have to use DTO, if there is another solution for this problem, please recommend.
I think you can make the query to return a map and you can create a constructor for FamilyMaterialDTO which takes the argument as a map. And based on the keys present in the map you can set the values...
For simplicity let me create my own class.
Class foo { String a; Integer b; Boolean c;}
And a sample query
"select new map (a as a, b as b) from Foo f"
Now this query will return a list of maps and the size of the list depends on how many rows the query returns.
Now you can create a constructor like this. Assume the size of list is 1.
foo (List<Map<?,?> list) {
Map map = list.get(0);
If(map.containsKey("a")) this.a = map.get("a");
If(map.containsKey("b")) this.b = map.get("b");
If(map.containsKey("c")) this.c = map.get("c"); }
i have a dynamic list.
list=['a','b','c','d' ..... ] so length may change
i want to compare these list values in a query
select * from student where name in(all the list values);
i want to pass list values into this query
how i can do this.. ??? please help
Thank you
In Postgres, you can use arrays. The syntax in the where clause looks like:
where name = any (array[1, 2, 3])
or
where name = any (list_parameter)
You can write a function that gets a list as a parameter and return a string like "'one', 'two','three'".
// need a string like this 'one', 'two'
private String arrayToSqlInChecker(List<String> loc_list) {
StringBuilder value = new StringBuilder("");
for (int i = 0; i < loc_list.size(); i++) {
value.append("'" + loc_list.get(i) + "'");
if (i != loc_list.size() - 1) {
value.append(",");
}
}
return value.toString();
}
And then you have to append this string into you PostgreSQL IN query
"id IN (" + this.arrayToSqlInChecker(loc_list) + ")"
You can also handle null or empty values in the function
I am using sql.firstRow to check if a row exists in the postgres database based on some criteria.
def cur = sql.firstRow(r, '''
SELECT "some_thing"
FROM "my_table"
WHERE "customer_name" = :customer_name
AND "sad_date" = :sad_date
AND "forgiver" = :forgiver
''')
I find that this works:
if (cur){
log.debug("Found Some thing " + cur["some_thing"])
log.debug("Cur: " + cur.keySet())
}
however this lets in any rows that don't have some_field inside it.
ISSUE
To avoid this, when we try and check for the existance of a non empty value for some_field on the result row like this:
if (cur && "${cur.some_thing}" ){
log.debug("Found Some thing " + cur["some_thing"])
}
ERROR
I get an error suggesting that:
No signature of `String.positive` for argument types for the given type.
I have read this question and changed from cur.some_thing and cur['some_thing'] to "${cur.some_thing}" but the error does not go away
I have also tried this post and tried to use cur.getProperty("some_thing") and it still throws the same error.
I have this table:
Please, don't mind because it's on my native language and it doesn't matter..
Those are all attributes in table but when I go to Visual StudioS and try to use some of this I get this one:
I see all "normal" attributes in VS but where is those FK attributes?
I need them to compare few ones and get values?
I can't use it from name of other tables [dot] attribute etc...
like for example:
I need this: table1.ID == table2.ID
and not this: table1.ID == table1.table2.ID
Where or what is FK attribute in VS that is shown in SQL table ??
public void setParametri(int desID)
{
foreach (desavanje d in DM_Class.dc.desavanje)
if (d.desavanjeID == desID)
{
//THIS FIRST 4 LINES WORKS PERFECTLY
this.naziv_des = d.naziv_des;
this.datum_po = d.datum_pocetka.ToString();
this.datum_zav = d.datum_kraja.ToString();
this.cijena = d.cijena_des;
//foreach (klijenti k in DM_Class.dc.klijenti)
//{
// if(k.klijentID == //WHAT TO PUT HERE TO COMPARE VALUE klijentID from tables klijenti with FK value in table desavanje)
// this.klijent = k.Ime + ' ' + k.Prezime;
//}
//ON THIS LINE I'M GETTING ERROR - Object reference not set to an instance of an object. but why?
//I have data on that field in DB ?
//this.grad = d.mjesto_desavanja.gradovi.naziv_grada.ToString();
//this.mjesto = d.mjesto_desavanja.naziv_objekta;
//this.organizator = d.organizator.Ime + ' ' + d.organizator.Prezime;
//this.tip = d.tip_desavanja.vrsta_des;
this.klijent = d.klijenti.Ime + ' ' + d.klijenti.Prezime;
//this.status = d.status_desavanja.naziv_statusa;
//this.br_gost = d.specifikacija_desavanja.br_osoba;
}
}
If is there other solution to get values for attributes I'm willing to try it without using another foreach loop?
Ok, I managed this.. I've used a linq query to generate data that I need and in that queries I've compared needed ID's and finally get some working stuff.
I've looked around everywhere, but I can't seem to find exactly what I'm trying to do. It should be fairly simple...
I have a db table set up like this:
var db = Ti.Database.open('playerInfo.db');
db.execute('CREATE TABLE IF NOT EXISTS playersTable (id INTEGER PRIMARY KEY, name TEXT NOT NULL, "50" INTEGER, "25" INTEGER )');
I have two buttons with an assigned value of 25, and 50, respectively. Each button has a "value" key, where I assign their values. I am trying to accomplish three things:
When a button is pressed, find the column of corresponding value.
increase the value of this column by 1.
Retrieve the new value and console log it.
This is what my code looks like when a button is pressed:
var rows = db.execute("SELECT '" + button.value + "' FROM playersTable WHERE name= '" + owner + "'");
var imagesString = rows.fieldByName(button.value);
Ti.API.debug(imagesString)
This is all in a click event listener where the variable "owner" is passed in as a string.
This is the error I get:
message = "Attempted to access unknown result column 25";
I don't have too much experience with sql, so I'm not sure what I'm doing right and what I'm doing wrong. Any help is appreciated!
Thanks.
I'm not sure quite exactly what the problem is, but the following works for me. Note that the "?" variable substitution syntax makes sure that the values are quoted properly for MySQL:
button = e.source;
db = Titanium.Database.open('test');
var rows = db.execute("SELECT * FROM playersTable WHERE name= ?", "foo");
// Theoretically this should be returning a single row. For other results,
// we would loop through the result set using result.next, but here just check if
// we got a valid row.
if (rows.isValidRow()) {
var imagesString = rows.fieldByName(button.value);
var id = rows.fieldByName('id');
imagesString = imagesString + 1;
Ti.API.info("id = " + id + " val = " + imagesString);
// The ? substitution syntax doesn't work for column names, so we
// still need to stick the button value into the query string.
db.execute('UPDATE playersTable set "' + button.value +'"= ? where id = ?', imagesString, id);
}
else
{
Ti.API.info("Row not found.");
}
db.close();
If you get the row not found error, it's possible your data isn't getting inserted properly in the first place. Here's how I inserted my test row for player "foo":
db.execute('insert into playersTable (name, "50", "25") values (?,?,?)', 'foo', 0, 0);
I think this should solve your problem. Let me know if this doesn't work for you.