Passing a string variable in SQLite with GDScript - sql

I have a question about SQLite in GDScript.
I wanted to print one query result to debug but I cannot find the way to do it.
In my code I have:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username=?;" + (username))
I cannot pass the username as "username", what is the correct way to do it?
I also try this:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username= " + username + ";")
And this:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username = " + 'username' + ";")
By the way, im getting the username from this:
var username = $NinePatchRect/VBoxContainer/username.get_text()
I've printed and the variable username is fine.
Thank you all!

What to do
The proper way to do this, is with prepared statements and argument bindings. You need to find a way to do that with whatever solution you are using.
If you are using this solution: 2shady4u/godot-sqlite (Which is available from the Godot Asset Library, here). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_bindings(query, [username])
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using this solution: godot-extended-libraries/godot-sqlite (towards which the Godot Core developers contributed). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_args(query, [username])
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using this solution: khairul169/gdsqlite-native (which is an older project). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_args(query, PoolStringArray([username]))
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using another solution, please figure out how to use prepared statements with it. And if there is no way to do it, please switch to a solution that supports them, such as the ones linked above.
What NOT to do, and why
SQLite needs the strings between quotation marks.
A common way to put quotation marks in Godot is by writing your string between ' instead of ".
For example:
print('Hello "World"')
Should print Hello "World".
Alternatively, you can use escape sequences:
print("Hello \"World\"")
Which should also print Hello "World".
Thus, you can - please don't - make your query like this:
db.query("SELECT username, email FROM " + tableName + " WHERE username= \"" + username + "\";")
Then if the user typed:
peter
The query would be built like this (And let us say tableName is users):
SELECT username, email FROM users WHERE username= "peter";
And you would have a SQL injection vulnerability. If the user writes a quotation mark, then the rest of the string will be considered part of the query.
For example if the user writes
" or "" = "
The query will be built like this:
SELECT username, email FROM users WHERE username= "" or "" = "";
And that will return all users. And that is just an example of what they could write, because remember they would be writing SQL.
Prepared statements avoids the vulnerability. And not by string tricks, but by proper support. And without the hassle. Please use prepared statements.

Related

double where statement in SQL and ASP

I am a little lost on how to incorporate TWO Where in my sql statement in my asp.
I am trying to get the userID and password entered previously and compare it with what I have in my database created on SQL:
I think my problem comes from my double quotation and single quotation.
UserID is a number in my database and Password is a short text.
var mycon = new ActiveXObject("ADODB.Connection");
var myrec = new ActiveXObject("ADODB.Recordset");
mycon.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Users\\Omnivox.mdb");
var txtpassword = Request.QueryString("txtpassword");
var txtuserID = parseInt (Request.QueryString("txtuserID"));
var sql;
sql = "SELECT UserID, UserPassword FROM UserOmnivox WHERE UserID=" +txtuserID+ " AND UserPassword='" + txtpassword + "';";
myrec.Open(sql, mycon);
thank you
UPDATE: It is still not working. The error massage is : no value given for one or more required parameters for the line myrec.Open(sql,mycon)
Change
sql = "SELECT * FROM UserOmnivox WHERE UserID=" +txtuserID "AND UserPassword="'+txtpassword';
to
sql = "SELECT * FROM UserOmnivox WHERE UserID=" +txtuserID + " AND UserPassword='"+txtpassword+"'";
If you'd done any kind of basic debugging, like LOOKING at the query string you're generating, you'd have seen this:
sql = "SELECT [..snip..] UserID=" +txtuserID "AND UserPassword="'+txtpassword
^^--- no space
^--- missing +
which produces
SELECT .... UserID=1234AND userPassword
^^---syntax error, no such field '1234AND'
And then, yes, your quotes are wrong too
sql = "SELECT ... UserID=" +txtuserID "AND UserPassword="'+txtpassword
^------------------^-- one string
^-----------------^-- another string
^---???
It should be
sql = "SELECT * FROM UserOmnivox WHERE UserID=" +txtuserID + " AND UserPassword='" + txtpassword + "';";
I find another more flexible solution is better. Sometimes based on conditions you have one where condition, in others you have zero, and in others you have two. If you go down these paths they don't solve that issue. The following does.....
Some sql query
where 1=1 -- ## A condition that will always be true and does nothing to your query.
and first optional where clause
and second optional where clause
This way if you don't have the first where clause in a given situation but you do have the second you are not missing the words "where". You always have the where and you optionally add any array of "and" parts to your where statement. 100% flexibility in this method works for all challenges. Plus it is easier to follow code once you get past the wtf is this 1=1 nonsense reaction.

Query to retrieve all row data for supplied column name

I am using Eclipse and Oracle SQL Developer. My connections are all set up. I am trying to query my database in SQL Developer by passing in a column name as a variable.
For example, I just want to use something similar to this statement:
select * from CUSTOMERS;
but allow CUSTOMERS to be a variable where I can pass in any table name.
Currently this pulls all column names from given column name and connection:
final String query = "select column_name from all_tab_columns"
+" where owner = ?"
+" and table_name = ?";
try {
headers = DAO.useJNDI(jndi)
.setSQL(query)
.input(1, host)
.input(2, tableName)
.list(String.class);
I want to do the same thing but with rows. Does anyone know how to do this? This is what I am thinking about so far:
final String sql = "select *"
+ " from table_name"
+ " where owner = ? and table_name = ?";
try {
logger.debug(tableName+sourceJNDI);
sourceList = DAO.useJNDI(sourceJNDI)
.setSQL(sql)
.input(1, host)
.input(2, tableName)
.list(DatabaseCompareDto.class);
The main focus is the SQL statements. I know everything else works.
If I'm reading your question correctly, I think what you want is to replace the first table_name in your SQL with ?, then add an additional .input( 1, tableName) :
final String sql = "select *"
+ " from ?"
+ " where owner = ? and table_name = ?";
try {
logger.debug(tableName+sourceJNDI);
sourceList = DAO.useJNDI(sourceJNDI)
.setSQL(sql)
.input(1, tableName)
.input(2, host)
.input(3, tableName)
.list(DatabaseCompareDto.class);
You can't pass the table name as a parameter. Instead of wasting your energy on such an alleged generic solution, use or create a small templating engine which allows you to replace the table name in your query before sending it to the database.

Can someone clarify this SQL command

I saw this in some ASP code and didnt understand the last line, specifically all the apostrophies and quotation marks between Name= and AND. what is being appended? why do we need both?
uName = getRequestString("UserName");
uPass = getRequestString("UserPass");
sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"
The code is building a query that looks like this:
SELECT * FROM Users WHERE Name = 'foo' AND Pass = 'bar'
It passes in the text from the uName and uPass variables into the query string.
This is very dangerous though - it's an open door for SQL Injection.
That is very simple, you have the start of a string sentence with double quotes. Double quotes indicate the start and the end or part of a string.
for example, if you have
sql ="SELECT * FROM USERS"
your sentence takes all the value; if you have:
sql = "SELCT * FROM USERS"
whereSentence = " WHERE id = 1"
wholeSql = sql + whereSentence
with the + (plus symbol) you are concatening all the string.
With the simple quotes you are adding the simple quote in the string and concatening the other parts of the sentence.
For example if
uName = 'John' and uPass = 'McDonals'
sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"
your final sentence should be
SELECT * FROM Users WHERE Name = 'John' And Pass = 'McDonals'.
Is a simple way to say that the name is John McDonals as String, but the parameters are variables, depending the request
The first quotation (') mark is in the SQL lateron. The second quotation mark ("), marks the String literal for ASP.
After parsing, the query will be something like:
SELECT * FROM Users WHERE Name ='name' AND Pass ='password'
Which is why you need the ', because your intention is to give the DBMS a string.
This code is building a complete string for the SQL request. Presumably, this is connected to a webpage that asks for the username and password to be submitted in a block.
The uName and uPass strings will be set to something like this:
uName = "John";
uPass = "qwerty";
When the sql string gets created, the SQL query needs to put quotes around the string values, so the final query will look like this:
sql = "SELECT * FROM Users WHERE Name ='John' AND Pass ='qwerty'"
If you wrote:
SELECT x from y where y.name = martin
you would get an error. You need apostrophes to denote a string, like so:
SELECT x from y where y.name = 'martin'
Quotes are because someone appends a variable to a string, then appends another string and first character of that string, the apostrophe, is a closing apostrophe after my martin example.
Don't do that though, I mean don't append variables to strings, unless you know what you are doing. Use parameterized queries.

DELETE FROM table WHERE var = value does not remove entries

So I fetched some data from a mdb file in c# via
"SELECT * FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE Note = '" + listBox2.GetItemText(listBox2.SelectedItem).Replace("'","\'") + "'";
which selects the right data, here it is
SELECT * FROM Main WHERE Note ='Hello'
The mdb data structure looks like this being plotted as a CSV-file:
"Record ID";Status;Placement;Private;Category;Note;Blob
14341665;4;2147483647;True;3;"""Hello"" - Neues
But when I try to remove entries with
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" LIKE '" + dr[0] + "';";
or
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" = '" + dr[0] + "';";
which looks like for instance
DELETE FROM Main WHERE "Record ID" LIKE '14341665';
The entries just stay there. I can rerun the select command even restart my application, the mdb is not changed.
Is record ID a numeric field? If so, lose the quotes.
DELETE FROM Main WHERE [Record ID] = 14341665;
Note that spaces in field (column) names will always be a problem. Such columns names have to be enclosed in square brackets, as do columns named with reserved words.
The record id is numeric, so don't put apostrophes around it:
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" = " + dr[0]
Note: You should avoid using select * in production code, you should specify the data that you want returned. Also, you should use parameterised queries instead of concatenating values into the query.
if i remember correctly, "like" only works on string data, please check the data type of Record ID.
If Record ID is numeric, you may want to use database's conversion function to convert it into string before filtering using "like".
btw, remember to make sure that dr[0] is properly escaped.

Matching text string on first letter in SQL query

SAMPLE CODE:
Dim sql As String = "SELECT * FROM " + tblName + " WHERE needsTranslation = 'True' AND dataText LIKE " & "'" & alpha & "%" & "'" & " ORDER BY dataText;"
da = New SqlDataAdapter(sql, strConnection)
OP:
I would like to create a SQL query that returns all records when the first letter of a string matches my variable. I am coding this in an ASP.net code behind page in vb.net.
SELECT * FROM " + tblName + " WHERE textData = ' & alpha & "
In this exmample textData is a string of text and alpha is a single letter a through z or A through Z.
I don't need the criteria to be case sensitive, but I do need only the first letter of textData to match alpha.
I have tested the LIKE comparator and it does not return all records that begin with alpha.
What is the best way to do this? Any and all help will be appreciated.
thanks again,
The LIKE operator is what you'd want to use, but you have to use the % wildcard character like so:
SELECT * FROM MyTable WHERE textData LIKE 'a%'
SQL has sub-string operator SUBSTR() or SUBSTRING()
select * from tableName where substr( textData ) in ( 'A', 'B', 'C', ... );
I couldn't add to the comments on one of the other posts, but I'll strongly second the need to use a parameterized query for these reasons (you can include usage of the like operator with the wildcard % like the other answer correctly summarized to answer your question):
It will protect you from making mistakes with single quotes, especially if the user enters a search string that includes them
(they will cause your query to fail).
It protects you from SQL injection exploits. Example, a user were able to input the value of the variable "alpha" in the above
example they could enter something like:
'; DELETE FROM ;
If the user you were using had excessive database rights, they could
wreak all kinds of havoc (or they could potentially get access to
data they shouldn't have access to).