Selecting MySQL views using $wpdb class - php

I am building a Wordpress site and it is connected to a MySQL database. I am using the wordpress class wpdb (https://codex.wordpress.org/Class_Reference/wpdb) to interact with the database. With that class, I am able to query TABLES of my database, but not Views.
I need to be able to select Views of my database. Is this something that is not allowed with wpdb, or is my code just wrong? Is there a way to query views the same way I can query tables using wpdb?
I have tried using the query function, as well as treating a view the same way I treat a table, but it does not work. It returns empty.
Query method:
$test = $mydb->query(
$mydb->prepare(
"
SELECT name FROM $mydb->$view_name
WHERE id = 1"
)
);
echo $test; //returns empty; should return a name
Table method:
$test = $mydb->get_var(
"select name from $view_name WHERE id = 1"
);
echo $test; //returns empty; should return a name
Any suggestions? Am I able to connect to my database using something other than $wpdb (does Wordpress allow that?).

name seems to be a reserved word in MySQL (reference). Try surrounding it with back-ticks (`) like this:
SELECT `name` FROM ...
You should be seeing some errors, do you keep an eye on the logs? Also, when you have doubts in your queries, you can simply copy the raw query and execute it into phpMyAdmin or whatever tool you are using to access your database manually

Related

Laravel - Where Condition on Multiple Database

I'm using laravel with multiple DB connection. Oracle and PostgreSQL. I can do query from both of instance.
But the problem is I have to look inside my Oracle DB WHERE NOT EXISTS on my postgreSQL.
This is my current Query :
DB::connection('ora')->table('ora_purch')
->whereExists(function($query)
{
$query->select(DB::connection('pgs')->raw(1))
->from('pg_purch')
->whereRaw('ora_purch.id = pg_purch.id');
})
->get();
From this query, I get error "database pg_purch is not exists". It's just like laravel reads pg_purch as an oracle instance.
I also do simulation with the same query and the same instance (multiple database on postgreSQL only), the query is fine and produces correct data.
Is it possible to makes the laravel reads pg_purch refer to the connection?
Or maybe i've missing something?
Please advise, thank you.
Your code generates query like this:
SELECT * FROM ora_purch WHERE EXISTS (SELECT 1 FROM pg_purch WHERE ora_purch.id = pg_purch.id);
And make it with "ora" connection, ignoring "pgs" connection.
You can't use multiple connections inside one query.
Try to split them:
$ids = DB::connection('pgs')->from('pg_purch')->pluck('id');
$result = DB::connection('ora')->from('ora_purch')->whereIn('id', $ids)->get();

Postgresql returned timestamp format differes from test and prod db?

I have a column called start_date in table X.
In my php project, when I use a simple select * from table x where id = 1 to retrieve a row from table X in my test DB, the following is returned:
{"id":1,"start_date":"2017-12-05 18:56:07"}
Now when I do the same in my production database the following is returned:
{"id":1,"start_date":"05\/12\/2017 18:56:07"
Both my databases have the same datestyle which I have set to ISO,DMY using
ALTER DATABASE xx SET datestyle TO ISO, DMY;
Why if both of these settings are the same and my production db is a restore of my test db, are these two queries returning different formats?
Edit: I'm using codeigniters query builder in my php project to retrieve the values from the db. I then view the value of the direct result using var_dump. Here is my php codeigniter method:
function get_last($id) {
$this->db->where ( "id", $id);
return $this->db->get ('table_x')->row_array ();
}
If I replace the function with the following it works, but I would still like to know why the top is returning two different results.
function get_last($id) {
$this->db->select("id, to_char(dataman, 'DD/MM/YYYY') as start_date");
$this->db->where ( "id", $id);
return $this->db->get ('table_x')->row_array ();
}
This also makes me believe even more that postgregsql is the reason the format is coming back different since by directly defining the format works.

Doctrine Raw SQL not calling custom function

I'm having an issue calling an custom defined function in my database from Doctrine when using the Raw SQL.
Here is an example SQL Query that is being run
SELECT unicodeDecoder(answer) from answers;
unicodeDecoder is a custom defined function in my database and runs perfectly fine when I run the SQL statement directly on the database.
However when I run the query using raw sql, as follows:
$sql = "SELECT unicodeDecoder(answer) from answers";
$stmt = $this->getEntitityManager()->getConnection()->prepare($sql);
$stmt->execute();
I get the following error:
SQLSTATE[42000]: Syntax error or access violation: 1305 FUNCTION unicodeDecoder does not exist
Do I need to create a custom ORM mapping when using custom functions or could this be some form of caching issue?
Any help would be massively appreciated.
Thanks in advance
Try to prefix the function with database name:
$sql = "SELECT my_db.unicodeDecoder(answer) from answers";
If found the issue. Thank you to #alex-blex for giving me a point of somewhere to start looking.
My database has a . in the name: cms.app.com
The issue was caused by the .
When Doctrine tries to access the method it automatically appends the database name to the beginning.
When I attempted to add the cms.app.com to the beginning (as suggested by #alex-blex) it created the following method call (which is the wrong syntax)
cms.app.com.unicodeDecoder()
I attempted the following
`cms.app.com`.unicodeDecoder but this still resolved to
cms.app.com.unicodeDecoder()
I removed the . from the database name and it now works as expected.
Important Note: Do not use . in your database name as Doctorine doesn't resolve the name correctly as the ` symbol get stripped out.

How can i check for a table without errors being displayed

I want to check if a table in the OpenCart database exist so i made this function
public function CheckCustomer(){
$query = $this->db->query('SELECT * FROM '.DB_PREFIX.'customer_online');
return $query->row;
}
and in my controller i test if it exists i set a variable to 1 or 0 depending.
The table does exist everything is fine, byt if i delete the c from customer just to simulate the table not being there my tpl page is not rendered instead i get this error :
Notice: Error: Table 'OpenCart-Test.oc_ustomer_online' doesn't exist
Error No: 1146
SELECT * FROM oc_ustomer_online in /home/justine/www/opencart-test/opencart-1.5.5.1/upload/system/database/mysql.php on line 50
Is there anyway of doing this without it throwing errors on screen as i need to know if the table exists before i display certain information in my tpl file.
Hope someone can shed some light on this.
Generally speaking dynamically-created tables are a bad idea. Any table you need should always exist, and you can simply use TRUNCATE TABLE mytable to quickly remove all rows rather than DROP TABLE.
edit: way better idea than below
Change the query to SHOW TABLES FROM my_database [or simply SHOW TABLES if the db is already selected] and check to see if the table name you're looking for exists in the result set.
That said, you should be able to suppress the error by prefixing the function with #, ie:
$query = #$this->db->query('SELECT * FROM '.DB_PREFIX.'customer_online');
Or you should be able to switch your mySQL database object to use Exceptions rather than PHP Errors, then enclose the function call in a try{ } catch() { } block.
Resolved .
Putting this in my controller file fixed it.
$this->data['checkcustomer'] = #mysql_query ('SELECT * FROM '.DB_PREFIX.'customer_online');
MySQL can list all tables in a database. By specifying a "like tablename" you can search for a specific table.
/**
* Check if the table 'customer_online' exists
* #return boolean TRUE if table exists, FALSE otherwise.
*/
public function CheckCustomer(){
$res = $this->db->query("SHOW TABLES LIKE '".DB_PREFIX."customer_online'");
return (boolean) $res->num_rows;
}
This does not generate any errors as it is not trying to access the table, just looking for the table name in the list of tables in the database.

Monitor usage of a certain database field

I have a nasty problem. I want to get rid of a certain database field, but I'm not sure in which bits of code it's called. Is there a way to find out where this field is used/called from (except for text searching the code; this is fairly useless seeing as how the field is named 'email')?
Cheers
I would first text search the files for the table name, then only search the tables that contain the table name for the field name.
I wrote a program to do this for my own purposes. It builds an in-memory listing of tables and fields and relates the tables to the fields. Then it loops through tables, searching for the code files that contain the table names, and then searches those files for the fields in the tables found. I'd recommend a similar methodology in your case.
setting mysql to log all queries for some time might help. the queries will give you the tip where to look
brute force - set up a test instance - remove the column - and excercise your test suite.
create a before insert trigger on that table that monitors the insertion on that column.
at the same time create another table called monitor with only one column email
make that table insert the value of NEW.email field into monitor.email as well as in real table.
so you can run your application and check for the existence of any non-null value in monitor table
You should do this in PHP i would expect
For example:
<?php
class Query
{
var $command;
var $resource;
function __construct($sql_command = '')
{
$this->command = $sql_command;
}
public function setResource($resource)
{
$this->resource = $resource;
}
}
//then you would have some kind of database class, but here we would modify the query method.
class Database
{
function query(Query $query)
{
$resource = mysql_query($query->command);
$query->setResource($resource);
//Then you can send the class to the monitor
QueryMonitor::Monitor($query);
}
}
abstract class QueryMonitor
{
public static Monitor(Query $query)
{
//here you use $query->resource to do monitoring of queryies
//You can also parse the query and gather what query type it was:-
//Select or Delete, you can also mark what tables were in the Query
//Even meta data so
$total_found = mysql_num_rows($query->resource);
$field_table = mysql_field_table ($query->resource);
//Just an example..
}
}
?>
Obviously it would be more advanced than that but you can set up a system to monitor every query and every queries meta data in a log file or w.e

Categories