I'm trying to insert values in the contents table. It works fine if I do not have a PHP variable inside VALUES. When I put the variable $type inside VALUES then this doesn't work. What am I doing wrong?
$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description)
VALUES($type, 'john', 'whatever')");
The rules of adding a PHP variable inside of any MySQL statement are plain and simple:
1. Use prepared statements
This rule covers 99% of queries and your query in particular. Any variable that represents an SQL data literal, (or, to put it simply - an SQL string, or a number) MUST be added through a prepared statement. No exceptions.
This approach involves four basic steps
in your SQL statement, replace all variables with placeholders
prepare the resulting query
bind variables to placeholders
execute the query
And here is how to do it with all popular PHP database drivers:
Adding data literals using mysqli
$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description)
VALUES(?, ?, 'whatever')";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $type, $reporter);
$stmt->execute();
The code is a bit complicated but the detailed explanation of all these operators can be found in my article, How to run an INSERT query using Mysqli, as well as a solution that eases the process dramatically.
For a SELECT query you will need to add just a call to get_result() method to get a familiar mysqli_result from which you can fetch the data the usual way:
$reporter = "John O'Hara";
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?");
$stmt->bind_param("s", $reporter);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc(); // or while (...)
Adding data literals using PDO
$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description)
VALUES(?, ?, 'whatever')";
$stmt = $pdo->prepare($query);
$stmt->execute([$type, $reporter]);
In PDO, we can have the bind and execute parts combined, which is very convenient. PDO also supports named placeholders which some find extremely convenient.
2. Use white list filtering
Any other query part, such as SQL keyword, table or a field name, or operator - must be filtered through a white list.
Sometimes we have to add a variable that represents another part of a query, such as a keyword or an identifier (a database, table or a field name). It's a rare case but it's better to be prepared.
In this case, your variable must be checked against a list of values explicitly written in your script. This is explained in my other article, Adding a field name in the ORDER BY clause based on the user's choice:
Unfortunately, PDO has no placeholder for identifiers (table and field names), therefore a developer must filter them out manually. Such a filter is often called a "white list" (where we only list allowed values) as opposed to a "black-list" where we list disallowed values.
So we have to explicitly list all possible variants in the PHP code and then choose from them.
Here is an example:
$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) {
throw new InvalidArgumentException("Invalid field name");
}
Exactly the same approach should be used for the direction,
$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) {
throw new InvalidArgumentException("Invalid ORDER BY direction");
}
After such a code, both $direction and $orderby variables can be safely put in the SQL query, as they are either equal to one of the allowed variants or there will be an error thrown.
The last thing to mention about identifiers, they must be also formatted according to the particular database syntax. For MySQL it should be backtick characters around the identifier. So the final query string for our order by example would be
$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";
To avoid SQL injection the insert statement with be
$type = 'testing';
$name = 'john';
$description = 'whatever';
$con = new mysqli($user, $pass, $db);
$stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $type , $name, $description);
$stmt->execute();
The best option is prepared statements. Messing around with quotes and escapes is harder work to begin with, and difficult to maintain. Sooner or later you will end up accidentally forgetting to quote something or end up escaping the same string twice, or mess up something like that. Might be years before you find those type of bugs.
http://php.net/manual/en/pdo.prepared-statements.php
The text inside $type is substituted directly into the insert string, therefore MySQL gets this:
... VALUES(testing, 'john', 'whatever')
Notice that there are no quotes around testing, you need to put these in like so:
$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");
I also recommend you read up on SQL injection, as this sort of parameter passing is prone to hacking attempts if you do not sanitize the data being used:
MySQL - SQL Injection Prevention
That's the easy answer:
$query="SELECT * FROM CountryInfo WHERE Name = '".$name."'";
and you define $name whatever you want.
And another way, the complex way, is like that:
$query = " SELECT '" . $GLOBALS['Name'] . "' .* " .
" FROM CountryInfo " .
" INNER JOIN District " .
" ON District.CountryInfoId = CountryInfo.CountryInfoId " .
" INNER JOIN City " .
" ON City.DistrictId = District.DistrictId " .
" INNER JOIN '" . $GLOBALS['Name'] . "' " .
" ON '" . $GLOBALS['Name'] . "'.CityId = City.CityId " .
" WHERE CountryInfo.Name = '" . $GLOBALS['CountryName'] .
"'";
I'm new to web services and trying to query some tables using ORMLite, it doesn't support join statements so I'm using a raw query. I was wondering if there is a way to specify how the JSON is returned. What I have right now is:
Dao<CodesModel,String> CodesDao = DaoManager.createDao(connectionSource, CodesModel.class);
GenericRawResults<String[]> rawResults =
CodesDao.queryRaw(
"select r.CodeA, s.SubCodeA, r.CodeB, s.SubCodeB " +
"from CodesTable r JOIN SubCodesTable s ON s.CodeA = r.CodeA " +
"where SubCodeB = '" + b_sub + "' AND r.CodeB = '" + b_code + "'");
And the results are returned as a String[] and always seem to be in the order of
[CodeA, SubCodeA, CodeB, SubCodeB]
but I have only tested this locally and can't find in the documentation what determines the order for variables in the array that is returned.
The results are ordered that way because that is the order in which you specified them in the select statement. If you want the results ordered in a different way, reorder them in your query.
If anyone is looking for a way to know column names when using "select *" you can also use "getColumnNames()" on the rawResults object and they will always be in the order that the results are. Examples
//The result is returned as a GenericRawResults object
List<String[]> results = rawResults.getResults();
String[] columns = rawResults.getColumnNames();
JSONObject obj = new JSONObject();
if(results.size()>0)
{
obj.put(columns[0], results.get(0)[0]);
obj.put(columns[1], results.get(0)[1]);
obj.put(columns[2], results.get(0)[2]);
obj.put(columns[3], results.get(0)[3]);
}
I am trying to read multiple results after SQL query with ADODB object in Auoit.
$sqlCon = ObjCreate ("ADODB.Connection") ; Create SQL connection
$sqlCon.Open("DRIVER={SQL Server};" & $MY_PASS) ; Connect with required credentials
$rs = ObjCreate("ADODB.RecordSet") ; Creating a Record set object
$rs.Open($MY_QUERY, $sqlCon) ; Executing a query
$rs.GetString ;this return all (for example 4) records in one string
how to read only one specified record? $rs.RecordNumber(0).GetString??
how to get number of records returned? $rs.RecordCount ??
how to place records to array one by one?
Now I just found that method GetRosw() will do the job I was looking for
$arr = $rs.GetRows()
$records_number = Ubound($arr)
_ArrayDisplay($arr)
I want to create a report by using BIRT. I have 5 SQL criterias as the parameter for the report. Usually when I have 3 criterias, I am using nested if-else for the WHERE statement with javascript.
Since right now I have more criteria it becomes more difficult to write the code and also check the possibilities, especially for debug purposes.
For example the criteria for table employee, having these 5 criterias : age, city, department, title and education. All criteria will be dynamic, you can leave it blank to show all contents.
Do anyone know the alternative of this method?
There is a magical way to handle this without any script, which makes reports much easier to maintain! We can use this kind of SQL query:
SELECT *
FROM mytable
WHERE (?='' OR city=? )
AND (?=-1 OR age>? )
AND (?='' OR department=? )
AND (?='' OR title=? )
So each criteria has two dataset parameters, with a "OR" clause allowing to ignore a criteria when the parameter gets a specific value, an empty value or a null value as you like. All those "OR" clauses are evaluated with a constant value, therefore performances of queries can't be affected.
In this example we should have 4 report parameters, 8 dataset parameters (each report parameter is bound to 2 dataset parameters) and 0 script. See a live example of a report using this approach here.
If there are many more criteria i would recommend to use a stored procedure, hence we can do the same with just one dataset parameter per criteria.
Integer parameter handling
If we need to handle a "all" value for an integer column such age: we can declare report parameter "age" as a String type and dataset parameters "age" as an integer. Then, in parameters tab of the dataset use a value expression instead of a "linked to report parameters". For example if we like a robust input which handles both "all" "null" and empty values here is the expression to enter:
(params["age"].value=="all" || params["age"].value=="" || params["age"].value==null)?-1:params["age"].value
The sample report can be downloaded here (v 4.3.1)
Depending on the report requirements and audiance you may find this helpful.
Use text box paramaters and make the defualt value % (which is a wild card)
SELECT *
FROM mytable
WHERE city like ?
AND age like ?
AND department like ?
AND title like ?
This also allows your users to search for partial names. if the value in the city text box is %ville% it would return all the cities with "ville" anyplace in the city name.
If report parameters to be included in SQL-WHERE clause would be named according to some naming convention, for instance query_employee_[table column name], you could write Java-Script code in a generic way, so that you will not have to change it when new reporters being added.
for each param in params {
if param.name starts with query_employee_ {
where_clause += " and " + param.name.substring(after query_employee) + " == '" + param.value + "'";
}
}
You will have to check type of a parameter to make a decision whether you have to quote the parameter value.
The event handler could look as follows (implemented in Java, but it should be possible to port it to JavaScript, if you really need it to be in JavaScript):
public class WhereConditionEventHandler extends DataSetEventAdapter {
#Override
public void beforeOpen(IDataSetInstance dataSet,
IReportContext reportContext) throws ScriptException {
super.beforeOpen(dataSet, reportContext);
String whereClause = " where 1 = 1 ";
SlotHandle prms = reportContext.getDesignHandle().getParameters();
for (int i = 0; i < prms.getCount(); i++) {
if (prms.get(i) instanceof ScalarParameterHandle) {
ScalarParameterHandle prm = (ScalarParameterHandle) prms.get(i);
int n = prm.getName().indexOf("sql_customer_");
if (n > -1) {
String prmValue = "" + reportContext.getParameterValue(prm.getName());
if (DesignChoiceConstants.PARAM_TYPE_STRING.equals(prm.getDataType())) {
prmValue = "'" + prmValue + "'";
}
whereClause += " and " + prm.getName().substring("sql_customer_".length()) + " = " + prmValue;
}
}
}
System.out.println("sql: " + whereClause);
dataSet.setQueryText(dataSet.getQueryText() + whereClause);
}
}
By the way, you can pass in parameters that are not registered as report parameters in the BIRT report design. BIRT will nevertheless put them into "params" array.
How to find Hypernym relation from wordnet using Sparql query?
I can find easily hyponym relation but i can't able to find hypernym relation.
Following example for hyponym relation.
"SELECT ?hypo "
+ "WHERE {"
+ " wn20instances:synset-tank-noun-1 wn20schema:hyponymOf* ?hypo . "
+ "}";
Would simply reversing the relationship work for you?
Reverse the sense of the property:
{ wn20instances:synset-tank-noun-1 (^wn20schema:hyponymOf)* ?hyper . }
or (reverse the subject/object)
{ ?hyper wn20schema:hyponymOf* wn20instances:synset-tank-noun-1 . }