Filtering records from database using certain criteria - python-3.x

I created a database with a students table
myStr1 = "CREATE TABLE Students (reg_no VARCHAR(15), name VARCHAR(30), email VARCHAR(30), average_mark INTEGER, PRIMARY KEY(reg_no))"
self.myCursor.execute(myStr1)
I then added a function to add students details to the table and would like to filter out certain records based on a criteria. The following was my code:
def insert_student(self,reg_no,name,email,average_mark):
self.reg_no = reg_no
self.name = name
self.email = email
self.average_mark = average_mark
self.myCursor.execute("INSERT INTO Students VALUES (:reg_no, :name, :email, :average_mark)",{'reg_no':self.reg_no,'name':self.name,'email':self.email,'average_mark':self.average_mark})
self.myConnection.commit()
def get_students(self,criteria = None):
self.criteria = criteria
self.myCursor.execute("SELECT * FROM Students WHERE '{}'".format(self.criteria))
return self.myCursor.fetchall()
myWrapper = DBWrapper()
myWrapper.insert_student('F17/42770/2017','Mutheu Lorraine','mutheu#gmail.com',100)
myWrapper.insert_student('F17/3030/2015','Ron Weasley', 'ron#eie.com',71)
myWrapper.insert_student('F17/3031/2015','Hermione Granger', 'hermine#eie.com',71)
myWrapper.insert_student('F17/3031/2017','Ginny Weasley', 'ginny#eie.com',71)
myWrapper.myConnection.commit()
students = myWrapper.get_students('reg_no = F17/42770/2017')
print(students)
However when i run my code I only get '[]' instead of all the details of the student with the given registration number. How should I go about this?

After the formatting, the resulting SQL command is:
SELECT * FROM Students WHERE 'reg_no = F17/42770/2017'
The entire WHERE clause is a string, and that string does not evaluate to true for any row.
To make the criteria an SQL expression, drop the quotes. But the comparison value must be quoted so that it is recognized as a string:
self.myCursor.execute("SELECT * FROM Students WHERE {}".format(self.criteria))
...
students = myWrapper.get_students("reg_no = 'F17/42770/2017'")

Related

Custom LIKE statement in Java Spring Data and Cassandra #Query

I need to query from a table using LIKE statement where parameters are optional.
This is custom query where I can filter employee table by which Non-Empty request param:
Select select = QueryBuilder.select().from("employee");
Where selectWhere = select.where();
if (!email.isEmpty()) {
selectWhere.and(QueryBuilder.like("email", "%" + email + "%"));
}
if (!firstName.isEmpty()) {
selectWhere.and(QueryBuilder.like("first_name", "%" + firstName + "%"));
}
//Note: User will provide either email or first_name or both.
However, the above custom query will need to manually map the Rows to the object which I find too tedious:
ResultSet rs = cassandraClient.getApplicationSession().execute( select );
return rs.all().stream().map(row -> row.getString("first_name")).collect( Collectors.toList() );
Is there a way where I can use a Query annotation like below, so it will return the entity directly?
#Query("SELECT * FROM employee WHERE email LIKE :email AND first_name LIKE :firstName")
Employee search(#Param(value="email" String email, #Param(value="firstName" String firstName)
I tried passing an empty parameter value, but I am getting the following error:
LIKE value can't be empty.

Problems with the BQL "IN<>" statement

The requirement I have is to get a list of all discount codes defined in an instance and which ones a particular customer is currently assigned to, in the case given CustomerID=28. I further have to include only discount codes that naturally will be applicable to customers. There are only 3 of these; "Customer", "Customer and Item", "Customer and Item price Class". These are ARDiscount.ApplicableTo containing "CU", "CP","CI"
Select a.CompanyID, a.DiscountID, a.DiscountSequenceID, b.ApplicableTo, c.CustomerID
From DiscountSequence a
Join ARDiscount b On a.CompanyID = b.CompanyID and a.DiscountID = b.DiscountID
Left Outer Join DiscountCustomer c On a.CompanyID = c.CompanyID
And a.DiscountID = c.DiscountID
And a.DiscountSequenceID = c.DiscountSequenceID
And (IsNull(c.CustomerID,0) = 0 OR c.CustomerID = 72)
Where a.CompanyID = 2
And b.ApplicableTo In ('CU','CP','CI')
Order By a.DiscountID, a.DiscountSequenceID
I created data view delegate to return the 4 columns I need to display and in the view I created
to read the data like the SQL query above I used the BQL "IN<>" statement like this. The method was taken directlty from a blog post found here :
https://asiablog.acumatica.com/2017/11/sql-in-operator-in-bql.html
Object[] applicableTovalues = new String[] { "CP","CI","CU" }; // Customer and Price Class // Customer and Item// Customer
var Results = PXSelectJoin<DiscountSequence
, InnerJoin<ARDiscount, On<DiscountSequence.discountID, Equal<ARDiscount.discountID>>
, LeftJoin<DiscountCustomer, On<DiscountSequence.discountID, Equal<DiscountCustomer.discountID>,
And<DiscountSequence.discountSequenceID, Equal<DiscountCustomer.discountSequenceID>,
And<Where<DiscountCustomer.customerID, Equal<Current<Customer.bAccountID>>,
Or<DiscountCustomer.customerID, IsNull>>>>>>>
, Where<DiscountSequence.discountID, IsNotNull
, And<ARDiscount.applicableTo, In<Required<ARDiscount.applicableTo>>>>
, OrderBy<Asc<DiscountSequence.discountID, Asc<DiscountSequence.discountSequenceID>>>
>.Select(Base, applicableTovalues);
The problem is that the resulting SQL server select statement caught with TRACE only includes the first of the three IN values (''CU'') leaving (CI and CU) out.
I was expecting all three values in the IN statement like this : AND [ARDiscount].[ApplicableTo] IN ( ''CP'', ''CI'', ''CU'')
exec sp_executesql N'SELECT [DiscountSequence].[DiscountID], [DiscountSequence].[DiscountSequenceID], [DiscountSequence].[LineCntr],
<snip>
[DiscountCustomer].[CreatedDateTime], [DiscountCustomer].[LastModifiedByID], [DiscountCustomer].[LastModifiedByScreenID], [DiscountCustomer].[LastModifiedDateTime]
FROM [DiscountSequence] [DiscountSequence] INNER JOIN [ARDiscount] [ARDiscount] ON ( [ARDiscount].[CompanyID] = 2) AND [DiscountSequence].[DiscountID] = [ARDiscount].[DiscountID]
LEFT JOIN [DiscountCustomer] [DiscountCustomer] ON ( [DiscountCustomer].[CompanyID] = 2) AND [DiscountSequence].[DiscountID] = [DiscountCustomer].[DiscountID]
AND [DiscountSequence].[DiscountSequenceID] = [DiscountCustomer].[DiscountSequenceID] AND ( [DiscountCustomer].[CustomerID] = #P0 OR [DiscountCustomer].[CustomerID] IS NULL )
WHERE ( [DiscountSequence].[CompanyID] = 2)
AND ( [DiscountSequence].[DiscountID] IS NOT NULL
AND [ARDiscount].[ApplicableTo] IN ( ''CU''))
ORDER BY [DiscountSequence].[DiscountID], [DiscountSequence].[DiscountSequenceID]
OPTION(OPTIMIZE FOR UNKNOWN) /* AR.30.30.00 */',N'#P0 int',#P0=39
The issue is passing the array into the 'params' parameter. It thinks that you are passing a list of parameters into the bql query instead of a single array as a parameter.
If you cast it as follows it should work:
.Select(Base, (object)applicableTovalues);

Updating table based on user input

I created a table with the following details:
myStr2 = "CREATE TABLE Lecturers (lec_no VARCHAR(3), name VARCHAR(30), email VARCHAR(30), PRIMARY KEY(lec_no))"
I then created a function that would be able to update the table.
def update_lecturer(self, field_to_update, value_to_set, lec_no):
self.field_to_update = field_to_update
self.value_to_set = value_to_set
self.lec_no = lec_no
self.myCursor.execute("UPDATE Lecturers SET field_to_update = :field_to_update WHERE lec_no =:lec_no",{'field_to_update':self.field_to_update,'value_to_set':self.value_to_set,'lec_no':self.lec_no})
The table is updated based on the user input:
field_to_update = input("Field update:")
value_to_set = input("Value to set:")
lec_no = input("Lec_no:")
where the field_to_update can be name or email, the value_to_set can be either new value of name or the new value of email.The lec_no is the id of the lecturer whose details we would like to change.
However when I run the my code I get the following error:
sqlite3.OperationalError: no such column: field_to_update
I know there is no such column as field_to_update in my table but how can I set the column to be updated based on user input.
In your last line you should replace the field_to_update with your input and the updated values.
self.myCursor.execute("UPDATE Lecturers SET :field_to_update = :value_to_set ...
(you missed a colon and the actual value_to_set)
I concatenated the variable field_to_update in the update statement then added question marks to represent the other two variables and it worked. Here is my code:
def update_lecturer(self, field_to_update, value_to_set, lec_no):
self.field_to_update = field_to_update
self.value_to_set = value_to_set
self.lec_no = lec_no
self.myCursor.execute("UPDATE Lecturers SET "+self.field_to_update+" = (?) WHERE lec_no = (?)",(self.value_to_set,self.lec_no))
self.myConnection.commit()

Removing a column from result set in Groovy Sql rows

I have a query where I need to retrieve a column which I need only temporarily because I need to pass it in the parameter for a where clause, how can I remove this column and its value from my result set after it served that purpose. Hopefully the code will show what I mean...
def empQuery = "select id, name, address from Employee"
def retObj = [:]
def sql = new Sql(datasource)
retObj = sql.rows(empQuery.toString())
retObj.each {
def addressQuery = "select street from Address where employe_id = ${it['id']}
// at this point I want to remove 'id:n' from the result set hash map aka 'it'
}
Because later on I am displaying that result set on a page for the user, and the ID field is not relevant.
So can you please show the Groovy code to remove a column and its value from the rows data structure returned from sql.rows?
from http://docs.groovy-lang.org/latest/html/api/groovy/sql/GroovyRowResult.html
It looks like you can do something line:
retObj.each { it.remove('id')}
However I haven't tried it....

linq to entity Contains() and nested queries

i've a trouble with linq, i'll explain on example :
i have a database table called Employee which got FirstName and LastName columns,
and a method to search employees which gets a nameList list as argument, the elements in this list are names formatted like this one "Fred Burn", or this1 "Grim Reaper",
already tryed these approaches with no luck =[
//just all employees
var allData = from emp in Context.Employee select emp;
var test1 = from emp in allData
where(emp.FirstName + " " + emp.LastName).Contains
("" + ((from n in nameList select n).FirstOrDefault()))
select emp;
var test2 = (from emp in allData
where (emp.FirstName + " " + emp.LastName)
== ((from n in nameList select n).FirstOrDefault())
select emp);
var test3 = from emp in allData
where (from n in nameList select n).Contains
(emp.FirstName + " " + emp.LastName)
select emp;
first and second queries give : {"Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."} exceptionand third : {"LINQ to Entities does not recognize the method 'Boolean Contains[String](System.Collections.Generic.IEnumerable`1[System.String], System.String)' method, and this method cannot be translated into a store expression."}
would be glad to hear your suggestions :)
Thank You!
p.s.
yea i know it's possible to split names in list and compare them separately, but still curious why wont these queries work.
I assume nameList in this case is an in memory collection and that you are trying to use the LINQ to SQL trick creating a SQL "IN" clause inside of the Entity Framework. Unfortunately, EF doesn't support this syntax (yet). Depending on the number of records you are trying to match, you may be able to run separate queries for each child you are desiring. Alternatively, you could build an entitysql query using concatenation to append the multiple items from the nameList as separate OR clauses in the WHERE operation.

Resources