Using "Count" in PreparedStatement ... gives same result [duplicate] - sqlite

I already used the search here (and other forums as well) but haven't found an answer exacty to what I'm trying to do.
I know that it can easily be done in some other way, and this is just a small sandbox-framework I'm coding for a University course... in a real environment I'd just take Spring, Hibernate etc.
So what I did was coding myself a small generic Data Access Layer with POJOs, working with generic methods to retrieve, check or insert data to the database (Oracle). Most of this is done through PreparedStatements.
This is working as long as I don't have joins... is it possible to put in a Column as parameter?
Example:
Table A has Attribute X + others
Table B has Attribute Y + others
PreparedStatement with query SELECT * FROM A,B WHERE "A"."X" = ?
And then fill in "B"."Y" as the parameter...
The database doesn't throw me an error or exception, but the ResultSet returned after executing the statement is empty. Is it just not possible to do, or am I just missing some escaping?
I'm using PreparedStatement.setString(int index, String value) to fill in the parameter... in lack of ideas which other setX method I could use...
Again, in a real project I'd never code that myself, but rather use something like Spring or Hibernate and not re-invent the wheel, but I see it as an interesting exercise to code such a generic small data access layer myself.

No, JDBC does not allow this. Only column values can be set. If you want to make dynamic changes to the sql statement you will have to do it before you create the PreparedStatement.

Related

Can SQLite return default values for non-existent columns instead of error?

I know how to use IFNULL to get default values for non-existent rows or null values, but for creating queries that are compatible with older schema versions, it would be nice to be able to do this:
Schema v1: CREATE TABLE Employee (Name TEXT, Phone TEXT)
Schema v2: CREATE TABLE Employee (Name TEXT, Phone TEXT, Address TEXT)
Theoretical backward compatible query:
SELECT Name, Phone, IFNULL(Address, '') FROM Employee
Obviously this doesn't work for a file created with schema v1. Is there some way to do this though?
There are 2 alternative workflows, but both are rather annoying. Either 1) update the old db by adding missing columns (which would start with null values); or 2) build the query code dynamically based on schema version.
Create a temporary view that references a particular schema, substituting default values (or even transforming other data) for individual columns which differ between the base schemas.
Sqlite views can even be made modifiable by defining appropriate triggers.
This still requires programming some conditional logic upon connection, but it would allow more uniform queries and interaction with different versions of the schema.
The suggested syntax would perhaps be convenient in some limited cases, but this approach is much more useful since it can be expanded beyond simple "if column exists" Boolean operations and instead could be used to perform dynamic transformation of one schema into another, perhaps joining tables and providing more advanced logic for updates of differing schema, etc.
Pseudo code mixed with view definitions to demonstrate:
db <- Open database connection
db_schema <- determine schema version
If db_schema == 1 Then
db.execute( "CREATE VIEW temp.EmployeeX AS
SELECT Name, Phone, '' AS Address
FROM main.Employee;" )
Else If db_schema == 2 Then
db.execute( "CREATE VIEW temp.EmployeeX AS
SELECT Name, Phone, Address
FROM main.Employee;" )
End If
#Later in code
data <- db.getdata("SELECT Name, Address
FROM EmployeeX")
If you're really averse to conditional statements for the schema this may still be annoying, but it would at least reduce/eliminate conditional statements throughout the code--ideally occurring as part of the connection logic at one location in the code.
You might further notice that this pattern is really what object-oriented programming is supposed to solve. There's no mention of the language in the question, but a well-designed object model could be created in a similar fashion so that all database access is done through a unified interface. The implementation details for different schemas are internal to different objects that derive (i.e. implement interfaces and/or inherit from base class) from a basic set of interfaces. Consider the language you're using to see if the problem could be solved this way.

Error with SQLite query, What am I missing?

I've been attempting to increase my knowledge and trying out some challenges. I've been going at this for a solid two weeks now finished most of the challenge but this one part remains. The error is shown below, what am i not understanding?
Error in sqlite query: update users set last_browser= 'mozilla' + select sql from sqlite_master'', last_time= '13-04-2019' where id = '14'
edited for clarity:
I'm trying a CTF challenge and I'm completely new to this kind of thing so I'm learning as I go. There is a login page with test credentials we can use for obtaining many of the flags. I have obtained most of the flags and this is the last one that remains.
After I login on the webapp with the provided test credentials, the following messages appear: this link
The question for the flag is "What value is hidden in the database table secret?"
So from the previous image, I have attempted to use sql injection to obtain value. This is done by using burp suite and attempting to inject through the user-agent.
I have gone through trying to use many variants of the injection attempt shown above. Im struggling to find out where I am going wrong, especially since the second single-quote is added automatically in the query. I've gone through the sqlite documentation and examples of sql injection, but I cannot sem to understand what I am doing wrong or how to get that to work.
A subquery such as select sql from sqlite_master should be enclosed in brackets.
So you'd want
update user set last_browser= 'mozilla' + (select sql from sqlite_master''), last_time= '13-04-2019' where id = '14';
Although I don't think that will achieve what you want, which isn't clear. A simple test results in :-
You may want a concatenation of the strings, so instead of + use ||. e.g.
update user set last_browser= 'mozilla' || (select sql from sqlite_master''), last_time= '13-04-2019' where id = '14';
In which case you'd get something like :-
Thanks for everyone's input, I've worked this out.
The sql query was set up like this:
update users set last_browser= '$user-agent', last_time= '$current_date' where id = '$id_of_user'
edited user-agent with burp suite to be:
Mozilla', last_browser=(select sql from sqlite_master where type='table' limit 0,1), last_time='13-04-2019
Iterated with that found all tables and columns and flags. Rather time consuming but could not find a way to optimise.

what is :<variablename> in CAST statement in PL SQL

I found a query like select cast (:v as customtabletype) from dual.
Not able to understand what is the meaning of above line, written as dynamic query.
:<variablename>, in your case ":v", is what is known as a bind variable.
Essentially, this is a placeholder which is replaced with another value as the SQL statement is executed.
For more in-depth reading it is probably worth looking for bind variables in the Oracle documentation, as there is a lot of information available on why they're used and their benefits.

Object Mapping from stored procedure using the columnname attribute in EntityFramework CodeFirst

I have an existing db that I am using entityframework 6 Code-First on to work with. A requirement though is that all work with the db has to be via stored procedures. So I started out using the mapping that is new in 6.0:
modelBuilder.Entity<Post>().MapToStoredProcedures();
The issue is that this only supports mapping Insert, Update, and Delete sp's not the select sp's, I need to be able to us a sp to select. (I do not have access to edit any of the existing sp's)
My poco's have attributes on them specifying the column name's to use using the column attribute. Apparently though the built in mapping does not support using those unless you are doing a direct selection on the table via a dbset object.
Originally I had (which worked):
return (from c in DataContext.Current.AgeRanges orderby c.StartAge select c);
Then to switch it to the sp I tried (using the database sqlquery call):
return DataContext.Current.Database.SqlQuery<AgeRange>("[DIV].[GetAgeRangesList]").AsQueryable();
This returned valid objects, but none of the columns marked with the Column attribute had anything in them.
Then I tried (thinking since it was against the actual dbset object I'd get the column mapping):
return DataContext.Current.AgeRanges.SqlQuery("[DIV].[GetAgeRangesList]").ToList().AsQueryable();
Nope, this instead gave me an error that one of the properties in the POCO object (one of the Column attribute ones) was not found in the returned recordset.
So the question is, in entity framework (or best solution outside of that) what is the best way to call a stored procedure and map the results to objects and have that mapping respect the column attribute on the properties?
I would even be willing to use an old school Table object and a SqlCommand object to fill it, if I had a fast easy way to then map the objects that respects the Column Attribute.
SqlQuery does not honor Column attribute. If the names of the columns of the returned result set match the names of the properties of the entity the properties should be set accordingly. Note however that SqlQuery does only minimal amount of work (for instance it does not support relationships (.Include)) so you are limiting yourself if you decide using stored procedures for queries.
Enhancing SqlQuery to use ColumnName attributes is being tracked here: https://entityframework.codeplex.com/workitem/233 - feel free to upvote this codeplex item.

Entity Framework - Making a column auto-incremement

So I'm using the Entity Framework and we have a modal for a table called TPM_PROJECTVERSIONNOTES. This table has a column called NOTEID which is a number. Right now, when we create a new row, we get the next available number with this code:
note.NOTEID = (from n in context.TPM_PROJECTVERSIONNOTES
orderby n.NOTEID descending
select n.NOTEID).Max() + 1;
To me, this seems incredibly hacky (I mean you have to do an entire SQL query just to get the next value). Plus, it's incredibly dangerous; it's not thread safe or transaction safe. I've already found 9 instances in the DB that have the same NOTEID! Good thing no one even thought to put a UNIQUE constraint on that column... sigh.
So anyway, I've added a new sequence to the database:
CREATE SEQUENCE TPM_PROJECTVERSIONNOTES_SEQ START WITH 732 INCREMENT BY 1;
Now my question:
How do I instruct the Entity framework to use TPM_PROJECTVERSIONNOTES_SEQ.nextval when inserting a row into this table? Basically, I just don't want to specify a NOTEID at all and I want the framework to take care of it for me. It's been suggested I use a trigger, but I think this is a bit hacky and would rather have to Entity framework just create the correct SQL in the first place. I'm using Oracle 11g for this.
While this may still fall into what you call the 'hacky' category, you can avoid using triggers to call the nextval, but you must utilize a stored procedure to handle the insert (whereas it will call the nextval in lieu of using a TRIGGER). (I guess this could fall more into a TAPI/XAPI category)
Check out the recent article
TECHNOLOGY: Oracle Data Provider for .NET
it explains (and contains samples) to using a stored procedure to handle the insert, calling the sequence, and mapping it back to the ODP EF BETA.
This obviously does not have the ODP EF Beta do the SQL for nextval, but it is an alternative. (look at this forum, it does appear that most of the EF Oracle frameworks fall victim to this-- devart etc {https://forums.oracle.com/forums/thread.jspa?threadID=2184372} )

Resources