I am using PHP PDO to access a PostgreSQL database with various schemas, so first i create a connection and then i set the correct schema, like below:
$Conn = new PDO('pgsql:host=localhost;port=5432;dbname=db', 'user', 'pass');
$result = $Conn->exec('SET search_path TO accountschema');
if ( ! $result) {
die('Failed to set schema: ' . $Conn->errorMsg());
}
Is this a good practice? Is there a better way to do this?
In order to specify the default schema you should set the search_path instead.
$Conn->exec('SET search_path TO accountschema');
You can also set the default search_path per database user and in that case the above statement becomes redundant.
ALTER USER user SET search_path TO accountschema;
Related
The structure of the table I'm trying to reach is as such:
Database: INTERNAL_STUFF
Schema: INTERNAL_TEST
Table: TEST_TABLE_SIMPLE
I create a PDO as such:
$dbh = new PDO("snowflake:account=$this->account", $this->user, $this->password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
If I use this query:
$result = $dbh->query("SELECT * FROM INTERNAL_STUFF.INTERNAL_TEST.TEST_TABLE_SIMPLE");
I end up getting this response - 'Schema 'INTERNAL_STUFF.INTERNAL_TEST' does not exist or not authorized.'. So it appears to be treating the database and the schema as just the schema.
If I use the same query but drop the database from the front:
$result = $dbh->query("SELECT * FROM INTERNAL_TEST.TEST_TABLE_SIMPLE");
I end up getting this response - 'SQLSTATE[22000]: Data exception: 90105 Cannot perform SELECT. This session does not have a current database. Call 'USE DATABASE', or use a qualified name.'
What am I doing wrong here? My user has access to the correct role to view the table, and that exact query (the longer of the two) works just fine in a Snowflake Worksheet.
You may also set the default namespace(database & Schema) for your user using Alter User statement.
Details: https://docs.snowflake.com/en/sql-reference/sql/alter-user.html#usage-notes
Can you execute query USE DATABASE INTERNAL_STUFF and next query USE SCHEMA INTERNAL_TEST before you execute your main Sql query.
Using Doctrine, I need to run "SHOW DATABASES" and for each database perform some sanity checks.
What I did is:
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array('url' => $DB_URL, );
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$conn->prepare("SHOW DATABASES")
....
Now that I have the list of DB's, how can issue the Doctrine's equivalent of USE my_db ? So that further SQL's are executed on that database?
It depends on a database management system you use. In common case you should create a new connection if you want to use a new database.
Database is a part of connection params you give to a \Doctrine\DBAL\DriverManager to get a connection. (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html)
I'm making a WordPress plugin and I need to update tables for the current database in a query. However, instead of writing the database name into the sql, I need some way to select it in the query so that way it will work no matter what your database's name is. This is the code I currently have:
$stmt = $conn->prepare("UPDATE `wp_plugin_development` . `wp_users` SET `user_pass` = ? WHERE `user_login` = ?") or trigger_error($mysqli->error);
$stmt->bind_param('ss', $user_password[$i], $user_login[$i]);
wp_plugin_development is my current database name, but needs to be replaced with some other way of selecting the database name. I wish I could write something like UPDATE SELECT DATABASE() but that obviously doesn't work. Maybe there's an entirely different way to code this? I still consider myself new to all this, so I'm sorry if I'm missing something obvious. Any help is greatly appreciated.
You don't need the current database name, because the connection is already established with the current database.
You need the tablename! The prefix is set when setting up wordpress. You need the prefix, because every installation is different.
The proper Wordpress way is like this:
global $wpdb;
$table_name = $wpdb->prefix . 'plugin_development';
The prefix is stored (wp_). In WP; you don't use PDO or MySqli directly, you work with the global $wpdb object.
$wpdb->update($table_name, $data, $where, $format = null, $where_format = null);
If you really need the database name, it's stored in $wpdb->dbname;.
Here are examples and the class reference:
https://codex.wordpress.org/Class_Reference/wpdb
I was using another database as the connection method (this was defined in the $conn variable). So I made a new connection to the current database using $wpdb and named it $this_db. Now I don't have to specify the database name in the query and it works like I want it to. For better context, here's the code I added/changed:
$thisServername = $wpdb->dbhost;
$thisUsername = $wpdb->dbuser;
$thisPassword = $wpdb->dbpassword;
$thisDBname = $wpdb->dbname;
$this_db = new mysqli($thisServername, $thisUsername, $thisPassword, $thisDBname);
$stmt = $this_db->prepare("UPDATE `wp_users` SET `user_pass` = ? WHERE `user_login` = ?") or trigger_error($mysqli->error);
$stmt->bind_param('ss', $user_password[$i], $user_login[$i]);
So, for solving this specific issue, this solution works. Sorry I forgot to mention using the external database. That was an important thing I left out of the question. And thank you everyone for your input.
The function database() returns the DB name - http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_database -
so you can run SELECT DATABASE(); first to get the DB name.
I connect the normal way:
$dbh = ibase_connect($host, $username, $password) OR die("could not connect");
Then I run a query:
ibase_query($dbh, 'ALTER TABLE USERS ADD OLDUSERPASS VARCHAR(32) COLLATE NONE') or die(ibase_errmsg());
Directly after this I run:
ibase_query($dbh, 'UPDATE USERS SET OLDUSERPASS = USERPASS') or die(ibase_errmsg());
It complains:
Column unknown OLDUSERPASS At line 1
But when I look in the DB, the column has been created. So, for some reason that split second after run ALTER, the query is not actually committed to the server.
Any ideas why?
Try
ibase_commit($dbh) after alter statement
In Firebird, DDL is under transaction control and you are not allowed to use newly created objects (tables, columns, etc) within the same transaction. So you will first need to commit before executing a query that uses that object.
I want to create databases and users with CI programmatically. So far i have these 2 simple MySQL statements.
CREATE DATABASE `testdb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
and
CREATE USER 'test_user'#'%' IDENTIFIED BY '***';
GRANT ALL PRIVILEGES ON * . * TO 'test_user'#'%' IDENTIFIED BY '***' WITH GRANT
OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0
MAX_USER_CONNECTIONS 0 ;
GRANT ALL PRIVILEGES ON `testdb` . * TO 'test_user'#'%';
Can those be converted to Active Record, or does CI provides its own way of creating users/tables? i search the docs and couldn't find anything...
EDIT: I do this as an intranet application so no worries about permissions
CodeIgniter provides a class called as Database Forge , it contains some functions which can be used to perform basic maintenance on your DB.
$this->load->dbforge()
if ($this->dbforge->create_database('my_db'))
{
echo 'Database created!';
}
and regarding adding users, its possible, but I don't know if its a good practice or not.
and also make sure that the mysql user who runs the queries has the permissions to create db.
$data = array(
'Host' => 'localhost' ,
'User' => 'krish' ,
'Password' => 'somepass',
'Select_priv' => 'Y',
'Insert_priv' => 'Y'
);
$this->db->insert('mysql.user', $data);
IF I understand, you can try
$config['database'] = 'mysql';
// other config details e.g username. port, pass
$this->load->database($config);
$query = "INSERT INTO user (host, user, password, select_priv,
insert_priv, update_priv)
VALUES ('localhost', 'user', PASSWORD('mypass'), 'Y', 'Y', 'Y')";
$this->db->query($query);
My syntax might be a little off.
Essentially - use the mysql database, insert directly in to the user table.
Some hosts may deny access to this directy, however.