What's the internals of a prepared statement like? [closed] - mysql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Here's how bind_params seem to be preparing sql statements:
stmt = db.prepare( "select * from table where a=? and b=?" )
stmt.bind_params( 15, "hello" )
So in reality inside the stmt, we need to have map/array or something that will eventually map the arguments and create the right stmt. What's the most optimal way of doing this internally? Plus strings need extra precaution I imagine - the above will have to be mapped like "select * from table where a = 15 and b = \"hello\" ".
I looked into SQLite3 and OCI and they seem to be passing these to internal C code.

I am trying to prepare the queries at the client side and send it to the server
If you're trying to do what it sounds like you're trying to do... don't try to do that.
That's not what a prepared statement is (or at least that isn't what it should be).
Your client code should not be trying to interpolate values into the query string in order to generate a "finished" query to send to the server for execution. That is a recipe for disaster, not to mention a false sense of security.
Prepared statements deliver the statement with ? placeholders to the server as-is, where the server "prepares" the statement for execution... and then the client send the parameters to the server ("binding" the parameters) for execution. Doing this, the server will never be confused as to "which part is the SQL" and "which part is the data," making sql injection impossible and making escaping and sanitizing the data unnecessary.
mysql_stmt_bind_param() is used to bind input data for the parameter markers in the SQL statement that was passed to mysql_stmt_prepare(). It uses MYSQL_BIND structures to supply the data. bind is the address of an array of MYSQL_BIND structures. The client library expects the array to contain one element for each ? parameter marker that is present in the query.
— http://dev.mysql.com/doc/refman/5.6/en/mysql-stmt-bind-param.html
If you are not communicating directly with the C-API then you should be calling the methods in your library that expose those same functions to you.

Related

Remove escape symbols in string using mysql command [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a MySQL column with data looking like this,
I need to convert the column to the JSON format via convert(somecolumn,JSON). However, it seems that I first need to remove the escape symbols (e.g., \"). I did some search and found that mysql_real_escape_string will do the job (from this question).
But if I understand correctly, mysql_real_escape_string is a PHP command. Is there any native MySQL command that do similar thing as mysql_real_escape_string (something like convert(mysql_native_function(somecolumn),JSON))?
Use REPLACE. For harder things REGEXP_REPLACE.
SELECT REPLACE(somecolumn, '\"', '"')
SELECT REGEXP_REPLACE('"..."', '(^"|"$)', '')
The latter will unquote the entire string, as ^ is the start, and $ the end.
BTW I would actually correct all the data in the table once. (After a backup.)
The mysql library is old.. if you really need to use something like it - use mysqli
the mysql_real_escape_string is not as secure as you would think it to be, see this: https://security.stackexchange.com/questions/8028/does-mysql-escape-string-have-any-security-vulnerabilities-if-all-tables-using-l
That said you're much better off by not using any of them but using Php PDO and replacing something like:
$data = [
'name' => $name,
'surname' => $surname,
'sex' => $sex,
];
$sql = "INSERT INTO users (name, surname, sex) VALUES (:name, :surname, :sex)";
$stmt= $pdo->prepare($sql);
$stmt->execute($data);
it will take care of the 'escaping' problems for you.
more examples here: https://phpdelusions.net/pdo_examples/insert

Num_rows doesn't work? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I have a MySQL Database but my function is not working. I want to know how many results I get for my database query, but I just get nothing back, not even 0. I also tried $values->num_rows; same result. Do not get back a number... just nothing
My Code:
$values = $database->query("SELECT * FROM `wp_all_import_xml` WHERE name = '$title' AND price = '$price' AND shop = '$shop' AND link = '$link'");
$count_values = mysqli_num_rows($values);
echo "ERROR by detecting Product (More than 1 Row return by SQL!): " .$title. " Preis: " .$price. " Shop: " .$shop. " Link: " .$link. "\t num_rows: " .$count_values. "\n";
How can I get the amount of rows I get returned?
Greetings
The mysqli_num_rows function does work.
The most likely explanation for the observed behavior is an error is occurring and being ignored.
For debugging this, start with making sure error reporting is enabled.
Modify the code to check the return from the query. Verify that it's not returning FALSE, by performing a conditional test.
if ($values = $mysqli->query(...) ) {
// query returned a resultset
} else {
// query returned FALSE
}
If all we need to retrieve is the number of rows, then we can use COUNT(*) in the SELECT list.
if ( $res = $mysqli->query("SELECT COUNT(*) AS cnt FROM ... ") ) {
If the query is successful, then we get a row back, even if the count is zero. And we can easily process the result like we process results from other queries, without the need to muck with num_rows, and worrying about whether the query is buffered or unbuffered, etc.
We're going to assume that $database is a mysqli connection, and not a PDO connection, since the code includes a call to the mysqli_num_rows function. If it's PDO connection, then "num_rows doesn't work".
The code in the question follows the pattern frequently seen in code that is vulnerable to SQL Injection. (In this excerpt, we can't determine if the values of the variables being included in the SQL text are potentially unsafe, so we can't tell if it's vulnerable or not.)
If this was a prepared statement with bind placeholders, then we could tell.
Use prepared statements with bind placeholders. It isn't hard.

I have a sample code, I need to know if it's PDO secure (MySQL) [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 6 years ago.
$s = "Update member_date" [snip]
$p = $pdo->prepare($s, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$p->execute();
Is that considered a "prepared" statement to justify being secure from SQL injection-type attacks?
UPDATE:
$member_id= htmlspecialchars($_GET['member_id']);
s1 = "
update member_date
set member_date= now()
where member_id= $member_id";
OVERALL QUESTION: "Is this how I should format all my new SQL-related code? I'm just finally making the switch from old mysql statements after reading my (new) error logs. Do I need to add in the question mark placeholders for strings and such or is the format how I have it at the first line of code ok for security purposes? I know the SQL I need to get the tasks accomplished just not the PDO security parts."
No. You are not using a prepared statement as intended. What you should do is add your $id as a paramater, and so separate your content (id) from your code (sql).
While you can do safe SQL with filtering yourself, the absolute best way is to, as you put it:
add in the question mark placeholders for strings and such
You can say "this needs to be an int, and then it will never be something scary like a " or some code that does magic with your query.
PDO is the best way to avoid sql injection that may attack the server. The code looks fine though. But PHP PDO is the absolute right way to avoid sql injection.

Question mark in field name of SQL INSERT statement

This may be a futile question, but I will ask anyway. I have now learned that it is bad practice to use a question mark at the end of a field name, as is the case with the Paid? field in the following statement:
$sql = "INSERT INTO `tblAppeals`
(
`#`,
`Year`,
`Property#`,
`Paid?`,
`Outcome`,
`ResolvedBy`,
`AppealCategory`
)
VALUES (?,?,?,?,?,?,?)";
When I try to run the statement, I get an error because the question mark is not handled correctly. I haven't been able to find any workarounds to avoid having to go back and change the field name.
Is there any way I can keep the field name the same, Paid?, and still use it in the INSERT statement? Thanks.
It looks like its an issue with your query layer and not MySQL itself. That is, whatever is doing the bind params handling is eagerly looking for all ? in the SQL and not just whats in the VALUES part of the clause.
What database drive / query framework are you using?

How to generate script in SQL SERVER 2008 R2 without using UI? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Hi i am using SQL SERVER 2008 R2, can someone please help me to generate a script like create, alter without using UI.
Stored procedures, views, functions etc. can all be scripted from sys.sql_modules as long as they're not encrypted:
SELECT definition
FROM sys.sql_modules
WHERE [object_id] = OBJECT_ID(N'dbo.object_name');
Or if you want to script multiple:
SELECT definition + CHAR(13) + CHAR(10) + 'GO'
FROM sys.sql_modules
WHERE OBJECT_NAME([object_id]) IN (N'name1', N'name2', ...);
Or all:
SELECT '--' + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
+ '.' + QUOTENAME(OBJECT_NAME([object_id]))
+ CHAR(13) + CHAR(10) + definition
+ CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
FROM sys.sql_modules
WHERE definition IS NOT NULL;
(Of course these are all doomed if you run them in Management Studio and any exceeds the max length of an output string there, ~8K in results to text. But it sounds like you want to consume these elsewhere.)
Note that this won't script the SET settings that were in force at the time the object was created, but you could extend this query to include settings like ANSI_NULLS and QUOTED_IDENTIFIER - which you can get from the same view.
Tables are a little trickier. If you generate the script in SSMS while profiler is running, you will see that it does this through a slew of queries and constructs the create table script within the code (in other words you can't sniff it out). It can be quite complex depending on what options you're using for your table, whether you need to script all foreign keys and dependent objects, etc. For this I would prefer the SMO method highlighted in podiluska's answer.
If you're already using SSMS then I don't understand the purpose of NOT using the generate scripts menu items. You can do so for multiple objects by using Object Explorer Details instead of Object Explorer, if the singleton approach is the problem:
You can use the Scripter class in SQL Management Objects (SMO) to do this.
eg: http://www.mssqltips.com/sqlservertip/1833/generate-scripts-for-database-objects-with-smo-for-sql-server/
Try this:
Create a sproc with following steps.
1.First get all the table names for which you need create table script.
2.loop through each table and get the below info:
select COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'tablename'
3.Now in the loop itself try to dynamically populate the create table script.
I wrote an open source command line utility named SchemaZen that does this. It's much faster than scripting from management studio and it's output is more version control friendly. It supports scripting both schema and data.
To generate scripts run:
schemazen.exe script --server localhost --database db --scriptDir c:\somedir
Then to recreate the database from scripts run:
schemazen.exe create --server localhost --database db --scriptDir c:\somedir