How to insert into session row using pdo [duplicate] - pdo

I am still getting my head around a PDO statement but the code below does not do what I assumed it would
$temp = "6c ";
$weather_report = "Its currently $temp " ;
$qry = $pdo->exec("UPDATE data_weather SET text= '$weather_report' WHERE period='report' ");
This does update my database but only with 'Its currently' and the temp value is missing ,
After reading some articles I believe I need to use quote but I am not sure how to implement it ?
any help please ?

Please use query parameters instead of interpolating variables into SQL strings.
It's safer, faster, and easier.
$temp = "6c ";
$weather_report = "It's currently $temp " ;
$sql = "UPDATE data_weather SET text= ? WHERE period='report'";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($weather_report));
Note that you don't need to quote the string. In fact, you must not put quotes around the ? placeholder. You can use apostrophes inside your weather report string safely.
You can use a parameter placeholder any place you would normally put a single scalar value in an SQL expression. E.g. in place of a quoted string, quoted date, or numeric literal. But not for table names or column names, or for lists of values, or SQL keywords.

Although Bill has already answered the question, I'd like to add:
Do not use named parameters with TEXT columns, at least not with MySQL. It won't work. Use question marks instead.

Related

Update command in sql having issue

I have below details in the table
GEMS#TEST1>select BUILTIN_ARGUMENTS from FND_FORM_CUSTOM_ACTIONS WHERE (RULE_ID = 2243);
BUILTIN_ARGUMENTS
--------------------------------------------------------------------------------
='http://prod.client.com:3001/ords/f?p=1:2:::NO::P_ORDER_HEADER_ID,P_SESSION
_ID:'||${item.ORDER.HEADER_ID.VALUE}||','||${ps.db_session_id.value}
For a need ,I have to update this "prod.client.com:3001" as
"test1-scan.client.com"
When I am executing below getting error
GEMS#TEST1>update FND_FORM_CUSTOM_ACTIONS set = '='http://test1-scan.client.com/ords/f?p=1:2:::NO::P_ORDER_HEADER_ID,P_SESSION
_ID:'||${item.ORDER.HEADER_ID.VALUE}||','||${ps.db_session_id.value}' WHERE (RULE_ID = 2243);
SP2-0552: Bind variable "NO" not declared.
GEMS#TEST1>
I know I might have to use escape character or declare the variable but not getting clue as I am not very good in coding .
Using REPLACE in this case is better.
UPDATE fnd_form_custom_actions
SET builtin_arguments = REPLACE (builtin_arguments, 'prod.client.com:3001',
'test1-scan.client.com')
WHERE rule_id = 2243 ;
You have obvious typos in your statement:
set = '='http://test1-scan.client.com/ords/f?p=1:2:::NO [.......]
set what = .....?
Then: what is with the second equal sign, in single quotes? (OR... I see - did you mean single quotes within the assigned string? You must enter TWO single quotes to represent one single quote in a string!)
Then: since the second equal sign consumes the single quotes, what follows AFTER it is not quoted. So :NO is seen as a bind variable. Correct the syntax and Oracle won't ask you about any bind variables.
With that fixed, look at Kaushik's answer for a better approach altogether.

Is it injection safe to remove all quotes from the user input?

$id = $_GET['id'];
$id = str_replace("'", "", $id);
$sql = "select name from test where id='$id'";
$stmt = $conn->query($sql);
As the php code snippet above, it removes all single quotes from the user input, and then put it in a sql query, whaterver it gets from the user is not able to escape from the quotes surrounding them, it seems safe from sql injection. I am quite curious about how to inject sql code to this.
Some question said about escaping quotes, which has examples to exploit it. But in my occasion, removing all quotes isn't really the same as escaping.
I know there is the parameterized query way to prevent sql injection. And yes, it's possible that single quotes may be contained in legitimate data. I am asking this question out of curiosity while learing sql injection, all I want to know is there are any examples to exploit this code?
If you don't want to use parameterization or escaping, and assuming your id is an integer, you could use typecasting. This is totally safe, and faster code than calling a function to do string replacement:
$id = (int) $_GET['id'];
$sql = "select name from test WHERE id=$id";
$stmt = $conn->query($sql);
But you should just get into the habit of using parameters. It's simple and fast. It works for strings, even if the strings contain special characters like quotes.
It's super easy in PDO, and it takes just one extra line of code:
$id = $_GET['id'];
$sql = "select name from test WHERE id=?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
my question [is], is it safe to remove quotes for string fields?
No. Don't do this. You don't know enough to do this safely. For example, what about backslash (\)? And other special characters?
Do you know why the internal MySQL API https://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string.html escapes more than just the quotes? This is the list of characters that are escaped:
\, ', ", NUL (ASCII 0), \n, \r, and Control+Z
So is it enough to remove these characters? No, you still have to think about character sets and hex-encoded characters.
There's no reason to do this. You already have more reliable solutions to make SQL queries safe.
Don't get fixated on your remove-the-quote solution. It's not sufficient.

In Perl, how do I properly quote string fragments I am using to build an SQL query? [duplicate]

This question already has answers here:
Is there an equivalent of PHP's mysql_real_escape_string() for Perl's DBI?
(5 answers)
Closed 9 years ago.
I've a set of elements in an array which is read from a file.Now i want to use this array value in sql statement in in Claus!for that i need to enclose these string by '(single quote).so I've tried with for loop to do this! is there any way to do this same opp? like any in build functions like qw...
code:
open FILE, "<tab_name.txt" or die $!;
my #tab=<FILE>;
chomp(#tab);
#tab=split(",",$tab[0]);#set of like eg:$tab[0]=asc,cdf,sad,casd,aea,aee,asdf
my #sql_str=();
foreach my $item(#tab){
$item="'".$item."'";
push(#sql_str,$item);#add comma
push(#sql_str,",");
}
pop(#sql_str);#remove lase unwanted comma
i got the desired output like 'asc','cdf','sad','casd','aea','aee','asdf'
but is there any way to do this?
Do You need an array, or a string fr the in clasue? I assume a string is proper, so what about this?
my $sql_str = join ",", map { $dbh->quote $_ } split ",", $tab[0];
But Miguel Prz is right, You should use parameter binding instead! This will save Your Oracle server for parsing over and over again the same SQL statements.
Other minor issue. If You use my #tab=<FILE>; it will read the whole file. But in the code only the first line is used. So You could use my $tab = <FILE>; to read only the first line.
To do this with placeholders (i.e., properly), you need to first gather all the values for the IN clause into a single array (#values) so that you know how many of them there are, then:
my $in_clause = join(', ', ('?') x scalar #values);
my $sql_str = "select field1, field2 from my_table where id in ( $in_clause )";
my $sth = $dbh->prepare($sql_str);
$sth->execute(#values);
(scalar isn't strictly necessary here, but included to make it a little more obvious what's going on for the OP.)
This may works:
my $sql_str = join ',' => map { $_ = qq|'$_'|; } #tab;
But, manually building your SQL this way is a bad idea™. Parameter binding is the proper way to solve this problem.

SQLiteQueryBuilder.buildQuery not using selectArgs?

Alright, I'm trying to query a sqlite database. I was trying to be good and use the query method of SQLiteDatabase and pass in the values in the selectArgs parameter to ensure everything got properly escaped, but it wouldn't work. I never got any rows returned (no errors, either).
I started getting curious about the SQL that this generated so I did some more poking around and found SQLiteQueryBuilder (and apparently Stack Overflow doesn't handle links with parentheses in them well, so I can't link to the anchor for the buildQuery method), which I assume uses the same logic to generate the SQL statement. I did this:
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(BarcodeDb.Barcodes.TABLE_NAME);
String sql = builder.buildQuery(new String[] { BarcodeDb.Barcodes.ID, BarcodeDb.Barcodes.TIMESTAMP, BarcodeDb.Barcodes.TYPE, BarcodeDb.Barcodes.VALUE },
"? = '?' AND ? = '?'",
new String[] { BarcodeDb.Barcodes.VALUE, barcode.getValue(), BarcodeDb.Barcodes.TYPE, barcode.getType()},
null, null, null, null);
Log.d(tag, "Query is: " + sql);
The SQL that gets logged at this point is:
SELECT _id, timestamp, type, value FROM barcodes WHERE (? = '?' AND ? = '?')
However, here's what the documentation for SQLiteQueryBuilder.buildQuery says about the selectAgs parameter:
You may include ?s in selection, which
will be replaced by the values from
selectionArgs, in order that they
appear in the selection.
...but it isn't working. Any ideas?
The doc for SQLiteQueryBuilder.buildQuery also says, "The values will be bound as Strings." This tells me that it is doing the straight-forward thing, which is writing the SQL leaving the ? parameter markers in place, which is what you are seeing, and binding the selectArgs as input parameters.
The ? are replaced by sqlite when it runs the query, not in the SQL string. The first string in the array will go where you see the first ?, and so on, when the query actually executes. I would expect the logged SQL to still have the ? markers.
Probably, your query fails because you are quoting the ?. For example, don't use WHERE ID = '?', just use WHERE ID = ?, and make sure the selectArgs is a string that satisfies the query.
Two things:
The ? substitution will not be done at this point, but only when the query is executed by the SQLiteDatabase.
From what I've seen, ? substitution only works for the right side of comparison clauses. For example, some people have tried to use ? for the table name, which blows up. I haven't seen anyone try using ? for the left side of the comparison clause, so it might work -- I'm just warning you that it might not.

How can I escape single and double quotes in SQL prepared statement?

I have a SQL statement similar to the one shown below in Perl:
my $sql="abc..TableName '$a','$b' ";
The $a is free text which can contain anything including single quotes, double quotes, back- and front-slash characters, etc.
How can these characters be escaped to make the SQL statement work?
Thanks.
You can either use the ->quote method (assuming you're using DBI):
my $oldValue = $dbh->quote('oldValue');
my $newValue = $dbh->quote('newValue');
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue");
Better still, the best practice is to use bind values:
my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?');
$sth->execute('newValue','oldValue');
This should also work for stored procedure calls, assuming the statement once the strings have been expanded is valid SQL. This may be driver/DB specific so YMMV.
my $sth = $dbh->prepare("DBName..ProcName ?,? ");
$sth->execute($a, $b);
Use a prepared statement. Replace the variable with a ?. To crib an example from DBI manpages:
$sql = 'SELECT * FROM people WHERE lastname = ?';
$sth = $dbh->prepare($sql);
$sth->execute($user_input_here);
Interpolating user input into your SQL is asking for security holes.
If you use query parameter placeholders, you don't have to escape the content of the strings.
my $sql="DBName..ProcName ?, ?";
$sth = $dbh->prepare($sql);
$sth->execute($a, $b);
If the DBI is using true query parameters, it sends the parameter values to the RDBMS separately from the SQL statement. The values are never combined with the SQL statement string, therefore the values never have an opportunity to cause SQL injection.
If the DBI is "emulating" prepared statements by interpolating the variables into the query string, then DBI should handle the correct escaping logic so you don't have to. Let the experts (those who write and test DBI) worry about how to do it.
If you don't want to use ->quote (for some reason, this function doesn't run on my version of DBI) then try this:
$query=~s/\"/\\\"/g;
I tend to do the same with single quotes and commas too just to be safe.
Seems to work fine for me...!