Simple select with max using scalike jdbc - sql

Still trying to get familiar with scalikejdbc. What is the simplest way to just use sql syntax to send a query using scalike jdbc into a table to get max date? Something really simple like the below works fine but gives me an error when I try to add max around the column.
val maxDate: Option[String] = DB readOnly { implicit session =>
sql"select <column> from <table>"
.map(rs => rs.string("<column")).first.apply()
}
this does not work:
val maxDate: Option[String] = DB readOnly { implicit session =>
sql"select max(<column>) from <table>"
.map(rs => rs.string("<column")).first.apply()
}
error:
Failed to retrieve value because The column name not found.. If you're using SQLInterpolation,...

I expect this happens because column max(MyColumn) does not have name "MyColumn" by default. You may try something like this instead
val maxDate: Option[String] = DB readOnly { implicit session =>
sql"select max(MyColumn) as MyColumn_max from MyTable"
.map(rs => rs.string("MyColumn_max")).first.apply()
}

Related

How to 'replace' table name in raw SQL query?

I have the following SQL query, which works:
await sequelize.query(
"DELETE FROM `table_name` WHERE (?) IN (?)",
{
replacements: ["project_id", projectIds],
type: QueryTypes.DELETE,
}
);
But I also want to use a replacement for table_name like this:
await sequelize.query(
"DELETE FROM (?) WHERE (?) IN (?)",
{
replacements: ["table_name", "project_id", projectIds],
type: QueryTypes.DELETE,
}
);
But this doesn't work and generates an error about SQL syntax. How can I make this work?
You are mixing data value binding and quoting identifiers.
There is ancient issue in the repo: https://github.com/sequelize/sequelize/issues/4494, which sounds like the problem above.
I believe you can create a workaround that respects different sql dialects like this:
const queryInterface = sequelize.getQueryInterface();
const tableName = queryInterface.quoteIdentifier("projects");
const columnName = queryInterface.quoteIdentifier("project_id");
await sequelize.query(`DELETE FROM ${tableName} WHERE ${columnName} IN (?)`, {
replacements: [project_ids],
type: QueryTypes.DELETE,
});
Assuming you are using sequelize 6.x.

Linq2DB can't translate a mapped column in Where clause

I'm working with a legacy Oracle database that has a column on a table which stores boolean values as 'Y' or 'N' characters.
I have mapped/converted this column out like so:
MappingSchema.Default.SetConverter<char, bool>(ConvertToBoolean);
MappingSchema.Default.SetConverter<bool, char>(ConvertToChar);
ConvertToBoolean & ConvertToChar are simply functions that map between the types.
Here's the field:
private char hasDog;
[Column("HAS_DOG")]
public bool HasDog
{
get => ConvertToBoolean(hasDog);
set => hasDog = ConvertToChar(value);
}
This has worked well for simply retrieving data, however, it seems the translation of the following:
var humanQuery = (from human in database.Humans
join vetVisit in database.VetVisits on human.Identifier equals vetVisit.Identifier
select new HumanModel(
human.Identifier
human.Name,
human.HasDog,
vetVisit.Date,
vetVisit.Year,
vetVisit.PaymentDue
));
// humanQuery is filtered by year here
var query = from vetVisits in database.VetVisits
select new VetPaymentModel(
(humanQuery).First().Year,
(humanQuery).Where(q => q.HasDog).Sum(q => q.PaymentDue), -- These 2 lines aren't correctly translated to Y/N
(humanQuery).Where(q => !q.HasDog).Sum(q => q.PaymentDue)
);
As pointed out above, the .Where clause here doesn't translate the boolean comparison of HasDog being true/false to the relevant Y/N values, but instead a 0/1 and results in the error
ORA-01722: invalid number
Is there any way to handle this case? I'd like the generated SQL to check that HAS_DOG = 'Y' for instance with the specified Where clause :)
Notes
I'm not using EntityFramework here, the application module that this query exists in doesn't use EF/EFCore
You can define new mapping schema for your particular DataConnection:
var ms = new MappingSchema();
builder = ms.GetFluentMappingBuilder();
builder.Entity<Human>()
.Property(e => e.HasDog)
.HasConversion(v => v ? 'Y' : 'N', p => p == 'Y');
Create this schema ONCE and use when creating DataConnection

How to order queries in sql in flutter?

I am using sqlite database in Flutter. with provide and sqlite libraries. I want to get ordered list of String in the database when I get the list from sqlite. How can I achieve this? Thank you for your response!
You can use orderBy variable inside query method like this:
Future<List<SingleShiftModel>> getShiftModelsForParticularGroup(
String groupId) async {
Database db = await database;
final List<Map<String, dynamic>> maps = await db.query(
allShiftsTableName,
where: 'parentId = ?',
orderBy: "date ASC", // here you can add your custom order exactly like sqlite but EXCLUDE `ORDER BY`.
whereArgs: [groupId],
);
return List.generate(
maps.length,
(i) => SingleShiftModel.toShiftModelObject(maps[i]),
);
}

NHibernate Linq Expression dynamic projection

How can i dynamically change the selected columns in the generated sql query when using a linq expression?
Its a new session for each time the query is executed.
Even when I set the MapExp as null after first creation an then changing the bool value to false, it still generates the column in the sql query.
The code runs in a wpf application.
System.Linq.Expressions.Expression<Func<Entity, Model>> MapExp = x => new Model
{
Id=xId,
Count= LoadFormulaField ? x.Count: null,
...
};
var result = session.Query<Entity>().Select(MapExp))
Your problem seems to be the ternary-conditional as part of the expression which is causing the "Count" column to always be queried.
One option to avoid this could be:
var query = session.Query<Entity>();
IQueryable<Model> result = null;
if (LoadFormulaField)
{
result = query.Select(x => new Model
{
Id = x.Id,
Count = x.Count,
});
}
else
{
result = query.Select(x => new Model
{
Id = x.Id,
});
}
Which would get a little less ugly if you separate in a couple of methods I think.

Criterion based on boolean TSQL function

I'm calling the sql server function Contains like this :
ftquery = _OrElse(ftquery,Restrictions.Eq(Projections.SqlFunction("contains",NHibernateUtil.Boolean, Projections.Property<Document>(d => d.SearchContent), Projections.Constant(query.Query)),true));
OrElse will juste do an or using Restrictions.Or(ICriterion, ICriterion). The problem is that it generates invalid sql :
... and contains(this_.SearchContent, ?) = ? ORDER BY ...
I don't want to have the right part ( = ? ), I only need the Projection without the Restrictions.Eq, but without Restrictions.Eq I can't find any solution to convert a Projection to a Criterion.
How can we using NHibernate generate an sql like :
Select Name from Users where Contains(Name,'toto') or Contains(Job,'tata')
Register the function in your dialect:
RegisterFunction("FullTextContains", new StandardSQLFunction("contains", NHibernateUtil.Boolean));
Create a projection using Projections.SqlFunction then use this ProjectionAsCriterion class on your query:
var projection = Projections.SqlFunction("FullTextContains",
NHibernateUtil.Boolean,
Projections.Property<Document>(x => x.SearchContent),
Projections.Constant(query.Query));
var result = Session.QueryOver<Document>()
.Where(new ProjectionAsCriterion(projection))
.List();