I have a function that works fine when I say
$results = $wpdb->get_results(
"SELECT meta_value
FROM wp_woocommerce_order_itemmeta
WHERE order_item_id = '21'
AND meta_key = '_qty"
);
This function returns 4, which is the correct number I would be looking for in my database.
Unfortunately, this code is returning an empty array to get_results(). There is something wrong in my code with passing a variable to $wpdb, does anyone have an idea?
$results = $wpdb->get_results(
"SELECT meta_value
FROM wp_woocommerce_order_itemmeta
WHERE order_item_id =" .$order_item_id.
"AND meta_key = '_qty'"
);
In this specific case I think it is a simple issue of missing white-space in your string concatenation. However there may be a more suitable way to prepare your statement that would have prevented this by making it easier to spot, and follows other good query building practices
Wordpress Prepared Statments
By using $wpdb->prepare() you can use (most of) the sprintf () syntax to help you build your query.
$query = $wpdb->prepare("SELECT meta_value
FROM wp_woocommerce_order_itemmeta
WHERE order_item_id = %d
AND meta_key = '_qty'", $order_item_id);
$results = $wpdb->get_results($query);
More info available at the wordpress codex and on prepared statements in general
Related
I have run into error below but it seems like I can't get proper error logs.
WordPress database error Query was empty for query made by
I had this codes that will throw almost similar to the error above.
$query_select = $wpdb->get_results($wpdb->prepare(
" % "
, 1
),ARRAY_A);
My question is, what are the possible codes that will throw query was empty like in my above code.
There are some of the possible ways to get these type of error. The below usage may or may not be useful to you.
Using the $wpdb Object
1st Method - Declaring $wpdb as global and using it to execute an SQL query statement that returns a PHP object
global $wpdb;
$results = $wpdb->get_results( 'SELECT * FROM wp_options WHERE option_id = 1', OBJECT );
2nd Method - Utilizing the $GLOBALS superglobal. Does not require global keyword ( but may not be best practice )
$results = $GLOBALS['wpdb']->get_results( 'SELECT * FROM wp_options
WHERE option_id = 1', OBJECT );
Some users asked these type of question in stack exchange link below
To refer:
Another link to refer
The $wpdb->prepare method performs this functionality for WordPress, which supports both a sprintf()-like and vsprintf()-like syntax.
The %s (string), %d (integer) and %f (float) formats are supported.
All % characters inside SQL string literals, including LIKE wildcards, must be double-% escaped as %%.
So if we debug your code we like this:
$sql = $wpdb->prepare(" % ", 1);
die( var_dump($sql) );
The result will be: string ' ' (length=1)
OMG an empty string! So that's why we see the query was empty error.
The prepare method is expecting the format string to contain any of the following; %d, %s, or %f. So if you want your SQL query to be 1 you would need to change you code to:
$query_select = $wpdb->get_results( $wpdb->prepare('%d', 1), ARRAY_A );
Or if you want your SQL to be % you would need escape it with another % like this:
$query_select = $wpdb->get_results( $wpdb->prepare('%%', 1), ARRAY_A );
You can find out more about the prepare method and placeholders here Class Reference/wpdb « WordPress Codex
When we execute wp db query it's change properties in last query.
I am not understand your question but following below code if this helpful for you.
global $wpdb;
$wpdb->get_results( $wpdb->prepare(" % " , 1 ) );
if( $wpdb->last_error ){
//print_r( $wpdb->dbh)
$dbh = $wpdb->dbh;
echo $dbh->errno; // if no == 1065 then query was empty
echo $dbh->error; // Query was empty
}
https://codex.wordpress.org/Class_Reference/wpdb
see the examples.
Prepare must have a valid sql query with placeholders for variables you want in your query:
$wpdb->prepare(
"
SELECT sum(meta_value)
FROM $wpdb->postmeta //valid sql statements here
WHERE meta_key = %s
",
$meta_key)
meanwhile your code does nothing:
$wpdb->prepare(
" % " //no sql statements here
, 1 ...)
it looks like you wanted to
select * from someTable where someField % 1 -- (it will return no rows)
so, any empty query will return this error.
I would like some help iterating through an object that is stored in the meta_value column of my wp_postmeta table.
I have ID's stored in the column and I would like to use those ID's in an inner SELECT that will go and get the Page Title that is associated with each ID.
Here is my SQL:
SELECT p.ID, p.post_title, p.post_status, p.post_type, pm.meta_key, pm.meta_value
FROM wp_posts p, wp_postmeta pm
WHERE p.ID = pm.post_id
AND pm.meta_key = topic_related_topics
AND pm.meta_value != ''
ORDER BY p.post_title, p.post_type desc
Here is an example of what is brought back:
1313,ADIPIC ACID,draft,post,topic_related_topics,
a:5:
{i:0;s:3:"961";
i:1;s:4:"1313";
i:2;s:3:"975";i:
Basically I need to know the title that is associated with ID 961. The title resides in the wp_posts table.
The value you are seeing in the database is an array that has been serialized to a string by PHP. The i stands for "integer" and the s stands for "string", with the number following the s indicating how long the string is. In this case, even though "961" is an integer, it is being stored as a string in the first place of a an array with 5 elements (it looks like you chopped the last 2 off).
There isn't a good way to unserialize the data in SQL, so you will need to do it in PHP and then make a second query to get the title. You can use the WordPress function maybe_unserialize() to convert it back into an array.
global $wpdb;
$sql = "your sql....";
$rows = $wpdb->get_results( $wpdb->prepare( $sql, $your_args ) );
foreach( $rows as $row ){
// convert to an array
$ids = maybe_unserialize( $row->meta_value );
// loop through the array
foreach( $ids as $id ){
// fetch the titles
$sql = "SELECT post_title FROM $wpdb->posts WHERE ID = %d";
$title = $wpdb->get_var( $wpdb->prepare( $sql, $id ) );
}
}
A more standard way of doing it would be to just use get_post_meta() to fetch the array, and have WordPress handle the serialization internally. The other big advantage here is that if you are using caching, support for it is already built into these functions.
Lastly if you do want to be able to fetch it all in a single SQL query, you will need some additional logic, likely hooked to the saving of the meta value. In addition to having it save as an array, you can grab the single value you want to JOIN on and save it in its own meta_key. With a single value you can then join the posts table to the postmeta to accomplish what you are looking for.
I'm creating a shortcode in wordpress where the user can use the post title or slug of a post to pull information from a post. Everything works well except for when a post's title has an apostrophe in it.
An example of the shortcode that works with the post slug is
[card]hunters-mark[/card]
When I use the post title and the title has a apostrophe it doesn't work.
[card]Hunter's Mark[/card]
When I use the shortcode with the title of a post that doesn't contain a apostrophe everyting works so the issue is with the apostrophe. The code I use to get the post id is
$sql="select * from $wpdb->posts where (post_title='$content' or post_name='$content' ) and post_type='cards' and post_status='publish' limit 0,1";
$my_posts = $wpdb->get_results($sql);
if( $my_posts ) {
$card_id = $my_posts[0]->ID;
}
Edit:
So what is weird is that when I try to output everything by using
`$data=strpos($content,"'");
var_dump($data);
$content=str_replace("'", "\'", $content);`
It is displaying strpos("Hunter's Mark","'")=false
So it is saying that there is no ' even though there is, and and I check the database and the post title is showing exactly how I have it in the shortcode.
Apparently you cannot autoescape quotes. You need to do that yourself:
$sqlContent = mysqli_real_escape_string($content);
I would also advise using curly brackets for variables.
$sql="select * from {$wpdb->posts} where (post_title='{$sqlContent}' or post_name='{$sqlContent}' ) and post_type='cards' and post_status='publish' limit 0,1";
$my_posts = $wpdb->get_results($sql);
...
UPDATE
You can do it another (safer) way:
$wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->posts} WHERE
(post_title=%s OR post_name=%s)
AND post_type='cards' AND post_status='publish'
LIMIT 0,1",
$content,
%content
)
);
you should use mysql_real_escape_string($content) before using it in your query , or even better use prepared statements to make things much safer, currently you are vulnerable to sql injection. If you use prepared statement this issue will be resolved and it will be safer for you as well.
https://codex.wordpress.org/Class_Reference/wpdb#Protect_Queries_Against_SQL_Injection_Attacks
You should use the $wpdb->prepare() method to correctly insert and escape your variables - it protects against SQL injections as well. Using %s in your SQL will indicate that you want to use a string, otherwise a %d would be used for a digit. It's also recommended to use curly braces around {$wpdb->posts}. Since you are just looking for a single row you might want to use get_row() instead of get_results() as well. If you just want the ID you should use get_var() with SELECT ID.
global $wpdb;
// set up the SQL statement
$sql = "SELECT * FROM {$wpdb->posts} WHERE ( post_title=%s OR post_name=%s ) AND post_type='cards' AND post_status='publish' LIMIT 0,1";
// replace %s with $content
$query = $wpdb->prepare( $sql, $content, $content );
// query for results
$my_post = $wpdb->get_row( $query );
// did we get a result?
if ( ! empty( $my_post ) ) {
// get the ID
$card_id = $my_post->ID;
}
I am set up the below sql with $wpdb->prepare. Currently this query is run in a function, and all the variables are passed to the function from my page.php file in wordpress. The below query works. However my question is do I need to use the %s on my variables for $field1, $field2, etc... If so can someone help me with how to set it up, it did not work when I tried. If not, could someone tell me why not? Thank you!
$query = $wpdb->prepare("SELECT DISTINCT wp_eva_geography.$field1, wp_eva_geography.$field2
FROM wp_eva_geography
WHERE wp_eva_geography.$field3=%s AND wp_eva_geography.$field4=%s",$type,$geo_no_dash);
$results = $wpdb->get_results( $query );
Use the reference document to find out how it works.
In your specific case it might be worth just echo-ing out the MySQL query string so you can see what it's actually trying to request. Then you can spot if something has gone wrong, like a bad column name or value entry.
http://codex.wordpress.org/Class_Reference/wpdb
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key = %s",
13, 'gargle'
)
);
I am trying to show the sum of meta_value (which is numeric) for all the instances where post_id is the same in table postmeta. From looking at other replies the following seems to be what should do this but I just get nothing returned
<?php
global $wpdb;
$data = $wpdb->query("
SELECT SUM(meta_value)
FROM $wpdb->postmeta
WHERE `post_id` = $post_id
");
echo $data;
?>
I can't figure out what is wrong with this when compared to other answers. Any pointers?
Thanks
Well... Are you connected to the database? And when you're including object properties inside a string, it's good form to encase them in braces, like so:
$data = $wpdb->query("SELECT SUM(meta_value)
FROM {$wpdb->postmeta}
WHERE `post_id` = $post_id
");
Encapsulate your php variables if they are complex, so:
FROM {$wpdb->postmeta}
For SELECTing, you should use $wpdb->get_results() instead of $wpdb->query().
$wpdb->query() "… returns an integer corresponding to the number of rows affected/selected."
http://codex.wordpress.org/Class_Reference/wpdb#SELECT_Generic_Results
OK, I have changed the code to reflect the above including he encapsulation and using get_results instead of query but now just get 'Array' as the returned result.
global $wpdb;
$data = $wpdb->get_results("
SELECT SUM($wpdb->postmeta.meta_value)
FROM {$wpdb->postmeta}
WHERE `post_id` = the_id()
");
echo $data;
Do I need to use a foreach() loop to cycle the resultant array? I have also checked there is data and also that the_id() is valid