Mysql Generated Column Compued By Conditions On Other Columns - mysql

Is it possible to create a generated MySQL column that runs a condition on other columns?
For example:
column "a" - type boolean
column "b" - type date
generate column "c" that implements the logic:
if (a == false) || (a == true && b < NOW()) {
return true;
} else {
return false;
}

You can use IF/ELSE (https://dev.mysql.com/doc/refman/5.7/en/if.html) or CASE/WHEN (https://dev.mysql.com/doc/refman/5.7/en/case.html) statements in MySQL.
If you're writing a procedure, you can save the output of a query to a variable and check against that. If you aren't doing a procedure, you could do the validation inside of the statement and that should work.
Good luck!

You can write scripts for databases. I've done it in Ruby but I'm sure there are plenty of others. You would write a script to create the table without the conditional column and then you would write logic to add a new column with values based on your conditions.

Related

Google App Script SQL query returns bool 'True' instead of Int value but query works outside App Script? [duplicate]

When I execute a SQL query from Java and store the boolean returned, the query always returns true which shouldn't be the case at all. So I emptied the table and fired the query again, and yet it returns true for the emptied table. I have attached a picture of the table. I want the query to return true or false, so I can store it in Java. Can someone please specify an alternate code for this, please?
This is my code on java for the query.
boolean avail = st.execute("SELECT EXISTS(SELECT * from sales WHERE product='"+n+"' AND ord_date='"+sqlDate+"');");
And this is my code for result set
Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
This is the table, name of the table is 'sales'
I'm new to MySQL, a more specific approach is appreciated.
Statement.execute will return true regardless of what the query returns. You are still supposed to retrieve the actual result of the query.
Returns
true if the first result is a ResultSet object; false if it is an update count or there are no results
As you execute an EXISTS statement, there will always be a result (true or false). The actual value still has to be retrieved:
You must then use the methods getResultSet or getUpdateCount to retrieve the result, and getMoreResults to move to any subsequent result(s).
For reference: https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#execute-java.lang.String-String
Also note that you are directly embedding strings into your query, this will leave you vulnerable to SQL injections. Please read: How can prepared statements protect from SQL injection attacks?. Recommended reading: Introduction to JDBC
The return value of Statement.execute() signals whether the query produces a result set (true) or - possibly - an update count (false). The query you execute is a select which will always produce a result set (even if empty). In other words, it will always return true for a select.
If you want to get the result of your query, then the recommend approach is to use executeQuery. However, you are also concatenating values into your query string, which is a bad idea because it leave you vulnerable to SQL injection. The recommended approach is to switch to prepared statements:
try (PreparedStatement pstmt = con.prepareStatement(
"SELECT EXISTS(SELECT * from sales WHERE product = ? AND ord_date = ?)")) {
pstmt.setString(1, n);
pstmt.setDate(2, sqlDate);
try (ResultSet rs = st.executeQuery() {
boolean avail = rs.next() && rs.getBoolean(1);
// use avail...
}
}

SSIS Conditional split handling nulls and other values in column

I have an SSIS package in 2010
I want to return any nulls in a column or a value in the same column
This using the conditional split
I have the first part
ISNULL([Data Conversion].ID)== TRUE
this will bring me all the null ID rows
but I want to add a OR part
I am looking for something like :
ISNULL([Data Conversion].ID)== TRUE && [Data Conversion].ID =="ABC"
what replaces the && to achieve the OR condition please - or how to amend the code to achieve the OR condition
|| (Logical OR) (SSIS Expression) : Performs a logical OR operation. The expression evaluates to TRUE if one or both conditions are TRUE.
(ISNULL([Data Conversion].ID) == TRUE || [Data Conversion].ID =="ABC" ) && [Data Conversion].Sex =="Male"

Compare datetime in peewee sql Python

Apparently, I could not compare the date in the peewee SQL.
START_DATE = datetime.datetime(2015, 7, 20, 0, 0, 0)
customer_records = Customers.select().\
join(Current_Insurers, on=(Customers.current_insurer == Current_Insurers.id)).\
switch(Current_Insurers).\
join(Insurers, on=(Current_Insurers.insurer == Insurers.id)).\
where(Customers.pol_type == "PC" & \
Current_Insurers.effective_date == START_DATE )
Where Customers, Current_Insurers, Insurers are three class. The result is always 0 records. But if I removed the datetime condition from the sql and compare as follows
customer_records = Customers.select().\
join(Current_Insurers, on=(Customers.current_insurer == Current_Insurers.id)).\
switch(Current_Insurers).\
join(Insurers, on=(Current_Insurers.insurer == Insurers.id)).\
where(Customers.pol_type == "PC"
for r in customer_records:
if(r.current_insurer.effective_date == START_DATE):
print(r.policy_id)
Surprisingly we can compare now and print out customers.
What do I need to do to add the datetime condition in the peewee sql?
Many thanks,
Apparently, I could not compare the date in the peewee SQL.
That's completely incorrect. Do you honestly think that the library would be that broken??
The problem is Python operator precedence. You need to wrap the equality expressions with parentheses. So you where clause should look like this instead:
where((Customers.pol_type == "PC") & \
(Current_Insurers.effective_date == START_DATE))
Additionally, it's typically only necessary to call switch() when you have multiple joins to a single model.
Put together, your query should be:
query = (Customers
.select()
.join(Current_Insurers, on=(Customer.current_insurer == Current_Insurers.id))
.join(Insurers, on=(Current_Insurers.insurer == Insurer.id))
.where(
(Customers.pol_type == "PC") &
(Current_Insurers.effective_date == START_DATE)))
I came here because I had the same problem abd subsequently the same question.
The cause of my issue was that mariaDB was stripping the milliseconds when the original insert was done and python/peewee was passing in the milliseconds in the predicate on the later update. Very frustrating.

check each character from a string by pgsql function

I want to make a function which will check each character of a string.
For example, lets take a word "pppppoooossssttt", in this case the function will return a warning if same character repeated for more that 2 times. Here 'p' is repeated for 5 times. So the function will return a warning message.
If you're able to install plpython on your setup, this is what I would do. Then you could simply place this test inside a "WHERE" clause of a standard SQL function. It's immutable so it will only be called once, and it always returns True so it won't affect the results of a SQL query. Postgres has had some pretty shaky python implementations but either they or EnterpriseDB cleaned things up in the latest release.
CREATE OR REPLACE FUNCTION two_or_less(v text)
RETURNS BOOLEAN AS $$
#If the string is two characters
#or less, we can quit now.
ct = len(v)
if ct < 3:
return True
import plpy
warned = set()
a,b,c = v[:3]
for d in v[2:]:
if a == b == c:
if a not in warned:
warned.add(a)
plpy.warning('The character %r is repeated more than twice in a row.' % a)
a,b,c = b,c,d
return True
$$ LANGUAGE 'plpython3u' IMMUTABLE;

Linq to SQL: Queries don't look at pending changes

Follow up to this question. I have the following code:
string[] names = new[] { "Bob", "bob", "BoB" };
using (MyDataContext dataContext = new MyDataContext())
{
foreach (var name in names)
{
string s = name;
if (dataContext.Users.SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
dataContext.Users.InsertOnSubmit(new User { Name = name });
}
dataContext.SubmitChanges();
}
...and it inserts all three names ("Bob", "bob" and "BoB"). If this was Linq-to-Objects, it wouldn't.
Can I make it look at the pending changes as well as what's already in the table?
I don't think that would be possible in general. Imagine you made a query like this:
dataContext.Users.InsertOnSubmit(new User { GroupId = 1 });
var groups = dataContext.Groups.Where(grp => grp.Users.Any());
The database knows nothing about the new user (yet) because the insert wasn't commited yet, so the generated SQL query might not return the Group with Id = 1. The only way the DataContext could take into account the not-yet-submitted insert in cases like this would be to get the whole Groups-Table (and possibly more tables, if they are affected by the query) and perform the query on the client, which is of course undesirable. I guess the L2S designers decided that it would be counterintuitive if some queries took not-yet-committed inserts into account while others wouldn't, so they chose to never take them into account.
Why don't you use something like
foreach (var name in names.Distinct(StringComparer.InvariantCultureIgnoreCase))
to filter out duplicate names before hitting the database?
Why dont you try something like this
foreach (var name in names)
{
string s = name;
if (dataContext.Users.SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
{
dataContext.Users.InsertOnSubmit(new User { Name = name });
break;
}
}
I am sorry, I don't understand LINQ to SQL as much.
But, when I look at the code, it seems you are telling it to insert all the records at once (similar to a transaction) using SubmitChanges and you are trying to check the existence of it from the DB, when the records are not inserted at all.
EDIT: Try putting the SubmitChanges inside the loop and see that the code will run as per your expectation.
You can query the appropriate ChangeSet collection, such as
if(
dataContext.Users.
Union(dataContext.GetChangeSet().Inserts).
Except(dataContext.GetChangeSet().Deletes).
SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
This will create a union of the values in the Users table and the pending Inserts, and will exclude pending deletes.
Of course, you might want to create a changeSet variable to prevent multiple calls to the GetChangeSet function, and you may need to appropriately cast the object in the collection to the appropriate type. In the Inserts and Deletes collections, you may want to filter it with something like
...GetChangeSet().Inserts.Where(o => o.GetType() == typeof(User)).OfType<User>()...