I have been involved in mysql programming a bit. There we can create separate databases under the same user for different projects.e.g.(college database, hospital database) How can we achieve that in oracle sql? And I want a command line solution.I.e. sqlplus.
The problem appearing in sqlplus is that once two tables of different databases appear having the same name, error is delivered. What to do to have a different environment for each project under the same user alone?
It might be bit confusing to start with Oracle RDBMS when you got used to MySQL world.
A user in MySQL doesn't own DB objects: tables/views/etc, all DB objects belong to database. In Oracle all objects belong to schemes (synonym for user, showing that this user owns DB objects).
I want to show you different approaches in MySQL and in Oracle for the same tasks:
set current database (MySQL)/ set current schema (Oracle)
MySQL:
use db_name;
Oracle:
alter session set current_schema = schema_name;
Create fully qualified table:
MySQL:
create table db_name.table_name ...
Oracle:
create table schema_name.table_name ...
Select from another's DB/schema table
MySQL:
select * from database_name.table_name where ...
Oracle:
select * from user_owning_table.table_name where ...
So you basically want to create another Oracle schema (let's call it "hospital") for your new project:
create user hospital identified by "<password>";
create table hospital.employee( ... );
create table college.employee ( ... );
grant select, insert, update, delete on hospital.employee to human_user;
grant select, insert, update, delete on college.employee to human_user;
sqlplus human_user#your_tnsnames_alias
SQL> insert into hospital.employee(...) values(...);
SQL> insert into college.employee(...) values(...);
Related
Is there a query (not a stored procedure or a command) which can be executed to retrieve list of privileges for objects (Tables, Views, Stored Procedures, Functions & Triggers) and users for a particular database (require following columns -- Schema name, Object type, Object name, Permission)?
MySQL --
Tried this but require a consolidate query -- SHOW GRANTS FOR 'root'#'localhost';
Oracle --
Tried this SELECT * FROM DBA_TAB_PRIVS but it provides for tables and views only
MariaDB --
SQL --
As of Oracle (I don't know other databases; by the way, I believe you wrongly used the sql tag. It is the language, while the database you're probably talking about is named the MS SQL Server), remember that you can ask the Dictionary. For example:
SQL> select * From dictionary where lower(comments) like '%grant%';
TABLE_NAME COMMENTS
-------------------- -------------------------------------------------------
<snip>
USER_ROLE_PRIVS Roles granted to current user
USER_SYS_PRIVS System privileges granted to current user
USER_TAB_PRIVS Grants on objects for which the user is the owner, gran
tor or grantee
USER_TAB_PRIVS_MADE All grants on objects owned by the user
USER_TAB_PRIVS_RECD Grants on objects for which the user is the grantee
<snip>
20 rows selected.
SQL>
Saying that DBA_TAB_PRIVS (which displays info for the whole database; I'm running this from an ordinary user, not a DBA) shows only tables and views, well - you are wrong. It displays procedures as well. How do I know?
This is my procedure and I'll grant execute privilege to mike:
SQL> select object_name, object_type from user_procedures where object_name = 'P_TEST';
OBJECT_NAME OBJECT_TYPE
--------------- -------------------
P_TEST PROCEDURE
SQL> grant execute on p_test to mike;
Grant succeeded.
What do I see?
SQL> select grantee, owner, table_name, privilege
2 from user_tab_privs
3 where table_name = 'P_TEST';
GRANTEE OWNER TABLE_NAME PRIVILEGE
---------- ---------- -------------------- ----------
MIKE SCOTT P_TEST EXECUTE
SQL>
Here it is. So yes, you were wrong.
I have a script to run in my database.
But the problem is this script assume the tables have no prefix on it and all databases have a prefix (let call it prefix_).
Is there a command or a way to MySQL try to run
INSERT INTO prefix_mytable ...
instead of
INSERT INTO mytable...
for all of sql queries at the script (UPDATE, INSERT and DELETE)?
There is no way in MySQL to automatically prefix tables in the way you're describing. #MichaelBerkowski is correct.
The best I can suggest is that you create a second database with updateable views, using unprefixed names, as front-ends to your prefixed table names.
Here's an example:
mysql> CREATE DATABASE test;
mysql> CREATE TABLE test.prefix_mytable (id INT PRIMARY KEY, x VARCHAR(20));
mysql> CREATE DATABASE test2;
mysql> CREATE VIEW test2.mytable AS SELECT * FROM test.prefix_mytable;
Now you can insert using the unprefixed names:
mysql> INSERT INTO test2.mytable (id, x) VALUES (123, 'abc');
And to verify that the data was inserted into your original table:
mysql> SELECT * FROM test.prefix_mytable;
Once you do that, you can run your SQL script against database test2 and all the INSERTs should get to your original tables all right.
If you have a lot of tables you need to create views for, you can automate the creation of the CREATE VIEW statements:
mysql> SELECT CONCAT('CREATE VIEW test2.', REPLACE(TABLE_NAME, 'prefix_', ''),
' AS SELECT * FROM test.', TABLE_NAME, ';') AS _sql
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME LIKE 'prefix\_%';
Here is the guide to replace WordPress table prefix from wp_ to a different, like this you can update any mysql table. How to rename WordPress tables prefix?
I have been working on a pretty large database this last week. Basically I am taking an Access database and converting it to a MySQL database. I have seccessfully converted all the tables and views to MySQL. However I have a view that requires input from the user, the date. The other view is the view that will be call.
view 1 - compiled_fourweeks - needs date
view 2 - metrics_fourweeks - uses `compiled_fourweeks in query.
I was thinking of a precedure but I won't be able to reference the columns in the query.
I am kind of running out of ideas at this point.
If I understand correctly, you need to execute a view (metrics_fourweeks) that needs data from another view (compiled_fourweeks), and this last view requires input from the user.
I would go with the procedure approach:
create procedure fourWeeksData(d date)
create or replace view compiled_fourweeks
select ...
from ...
where recordDate = f -- Just an example; use whichever where clause you need
...;
select * from metrics_fourweeks;
end
If your database will be used just by a single user, your problem is solved. But if your database is meant to be used by more than one user... well, you can use temporary tables:
create procedure fourWeeksData2(d date)
drop table if exists temp_compiled_fourweeks;
create temporary table temp_compiled_fourweeks
select ...
from ...
where recordDate = f -- Just an example; use whichever where clause you need
...;
-- You will need to create the required indexes for this new temp table
-- Now replicate the SQL statement, using your new temp table
select ...
from temp_compiled_fourweeks
...;
end
Hope this helps you.
What is the best method to copy the data from a table in one database to a table in another database when the databases are under different users?
I know that I can use
INSERT INTO database2.table2 SELECT * from database1.table1
But here the problem is that both database1 and database2 are under different MySQL users. So user1 can access database1 only and user2 can access database2 only. Any idea?
CREATE TABLE db1.table1 SELECT * FROM db2.table1
where db1 is the destination and db2 is the source
If you have shell access you may use mysqldump to dump the content of database1.table1 and pipe it to mysql to database2. The problem here is that table1 is still table1.
mysqldump --user=user1 --password=password1 database1 table1 \
| mysql --user=user2 --password=password2 database2
Maybe you need to rename table1 to table2 with another query. On the other way you might use sed to change table1 to table2 between the to pipes.
mysqldump --user=user1 --password=password1 database1 table1 \
| sed -e 's/`table1`/`table2`/' \
| mysql --user=user2 --password=password2 database2
If table2 already exists, you might add the parameters to the first mysqldump which dont let create the table-creates.
mysqldump --no-create-info --no-create-db --user=user1 --password=password1 database1 table1 \
| sed -e 's/`table1`/`table2`/' \
| mysql --user=user2 --password=password2 database2
If you are using PHPMyAdmin, it could be really simple.
Suppose you have following databases:
DB1 & DB2
DB1 have a table users which you like to copy to DB2
Under PHPMyAdmin, open DB1, then go to users table.
On this page, click on the "Operations" tab on the top right.
Under Operations, look for section Copy table to (database.table):
& you are done!
MySql Workbench: Strongly Recommended
This will easily handle migration problems. You can migrate selected tables of selected databases between MySql and SqlServer. You should give it a try definitely.
I use Navicat for MySQL...
It makes all database manipulation easy !
You simply select both databases in Navicat and then use.
INSERT INTO Database2.Table1 SELECT * from Database1.Table1
it's worked good for me
CREATE TABLE dbto.table_name like dbfrom.table_name;
insert into dbto.table_name select * from dbfrom.table_name;
If your tables are on the same mysql server you can run the following
CREATE TABLE destination_db.my_table SELECT * FROM source_db.my_table;
ALTER TABLE destination_db.my_table ADD PRIMARY KEY (id);
ALTER TABLE destination_db.my_table MODIFY COLUMN id INT AUTO_INCREMENT;
Here is another easy way:
use DB1; show create table TB1;
copy the syntax here in clipboard to create TB1 in DB2
use DB2;
paste the syntax here to create the table TB1
INSERT INTO DB2.TB1 SELECT * from DB1.TB1;
I know this is old question, just answering so that anyone who lands here gets a better approach.
As of 5.6.10 you can do
CREATE TABLE new_tbl LIKE orig_tbl;
Refer documentation here: https://dev.mysql.com/doc/refman/5.7/en/create-table-like.html
Use MySql Workbench's Export and Import functionality.
Steps:
1. Select the values you want
E.g. select * from table1;
Click on the Export button and save it as CSV.
create a new table using similar columns as the first one
E.g. create table table2 like table1;
select all from the new table
E.g. select * from table2;
Click on Import and select the CSV file you exported in step 2
Try mysqldbcopy (documentation)
Or you can create a "federated table" on your target host. Federated tables allow you to see a table from a different database server as if it was a local one. (documentation)
After creating the federated table, you can copy data with the usual insert into TARGET select * from SOURCE
With MySQL Workbench you can use Data Export to dump just the table to a local SQL file (Data Only, Structure Only or Structure and Data) and then Data Import to load it into the other DB.
You can have multiple connections (different hosts, databases, users) open at the same time.
One simple way to get all the queries you need is to use the data from information_schema and concat.
SELECT concat('CREATE TABLE new_db.', TABLE_NAME, ' LIKE old_db.', TABLE_NAME, ';') FROM `TABLES` WHERE TABLE_SCHEMA = 'old_db';
You'll then get a list of results that looks like this:
CREATE TABLE new_db.articles LIKE old_db.articles;
CREATE TABLE new_db.categories LIKE old_db.categories;
CREATE TABLE new_db.users LIKE old_db.users;
...
You can then just run those queries.
However it won't work with MySQL Views. You can avoid them by appending AND TABLE_TYPE = 'BASE TABLE' from the initial query:
First create the dump. Added the --no-create-info --no-create-db flags if table2 already exists:
mysqldump -u user1 -p database1 table1 > dump.sql
Then enter user1 password. Then:
sed -e 's/`table1`/`table2`/' dump.sql
mysql -u user2 -p database2 < dump.sql
Then enter user2 password.
Same as helmor's answer but the approach is more secure as passwords aren't exposed in raw text to the console (reverse-i-search, password sniffers, etc). Other approach is fine if it's executed from a script file with appropriate restrictions placed on it's permissions.
Is this something you need to do regularly, or just a one off?
You can do an export (eg using phpMyAdmin or similar) that will script out your table and its contents to a text file, then you could re-import that into the other Database.
use below steps to copy and insert some columns from one database table to another database table-
CREATE TABLE tablename ( columnname datatype (size), columnname datatype (size));
2.INSERT INTO db2.tablename SELECT columnname1,columnname2 FROM db1.tablename;
For me I need to specific schema to "information_schema.TABLES"
for example.
SELECT concat('CREATE TABLE new_db.', TABLE_NAME, ' LIKE old_db.', TABLE_NAME, ';') FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'old_db';
IN xampp just export the required table as a .sql file and then import it to the required
create table destination_customer like sakila.customer(Database_name.tablename), this will only copy the structure of the source table, for data also to get copied with the structure do this create table destination_customer as select * from sakila.customer
I have a mysql query that joins data across 2 databases and inserts new records into one of the databases. The query below works if the same mysql user has access to both databases and both are on the same server. However, how would you re-write if each database has different user credentials?
PHP Script snippet:
$hard = mysql_connect($hostname_hard, $username_hard, $password_hard)
or trigger_error(mysql_error(),E_USER_ERROR);
# Insert artists:
mysql_select_db($database_hard, $hard);
$query_artsync = "insert ignore into {$joomla_db}.jos_muscol_artists
(artist_name, letter, added,url,class_name)
select distinct
artist
, left(artist,1) as letter
, now()
, website, artist
from {$sam_db}.songlist
where (songtype='s' AND artist <>\"\")";
mysql_query($query_artsync, $hard) or die(mysql_error());
echo "<br>Artist tables merged! <br><br> Now merging albums<br><br>";
So..in the above the {$sam_db} database is accessed by a different user than the {$joomla_db} user...
There are more complex inserts following this one, but I think if I can get the above to work, then I'll likely be able to apply the same principles to the other insert queries...
you're talking about using 2 different connections in the same query, which, unfortunately, is not possible. what you'll have to do is get (select) all the information you need from the one database, and use that info to construct your insert query on the other database (2 separate queries).
Something like this:
$result = mysql_query("SELECT DISTINCT artist, LEFT(artist,1) AS letter, now() as added, website
FROM {$sam_db}.songlist
WHERE (songtype='s' AND artist <>\"\"", $sam_con);
while(($row = mysql_fetch_assoc($result)) != false)
{
$artist = mysql_real_escape_string($row['artist']);
$letter = mysql_real_escape_string($row['letter']);
$added = mysql_real_escape_string($row['added']);
$website = mysql_real_escape_string($row['website']);
mysql_query("INSERT IGNORE INTO {$joomla_db}.jos_muscol_artists
(artist_name, letter, added,url,class_name)
VALUES
('$artist', '$letter', '$added', '$website', '$artist')", $joomla_con);
}
where $sam_con and $joomla_con are your connection resources.
There is no problem querying tables from different databases.
SELECT a.*, b.*
FROM db1.table1 a
INNER JOIN db2.table2 b ON (a.id = b.id)
Will run with no problems, as will your insert query.
However the user that starts the query needs to have proper access to the databases and tables involved.
That means that user1 (who does the insert) has to be granted insert+select rights to table {$joomla_db}.jos_muscol_artists and select rights to {$sam_db}.songlist
If you don't want to expand the rights of your existing users, then you can just create a new inserter user that has the proper access rights to use both databases in the proper manner.
Only use this user to do inserts.
Alternative solution without adding users
Another option is to create a blackhole table on db1 (the db you select from)
CREATE TABLE db1.bh_insert_into_db2 (
f1 integer,
f2 varchar(255),
f3 varchar(255)
) ENGINE = BLACKHOLE;
And attach a trigger to that that does the insert into db2.
DELIMITER $$
CREATE TRIGGER ai_bh_insert_into_db2_each ON bh_insert_into_db2 FOR EACH ROW
BEGIN
INSERT INTO db2.table2 (f1,f2,f3) VALUES (NEW.f1, NEW.f2, NEW.f3);
END $$
DELIMITER ;
The insert into table db2.table2 will happen with the access rights of the user how created the trigger.
http://dev.mysql.com/doc/refman/5.1/en/grant.html
With PHP for example, you will have to create 2 unique mysql instances, 1 per connection.
Then use both and do individual queries.
Explanation...
Setup connections to both databases using mysql_connect for example. Now, you now have defined the connenction variables...
In the mysql_query you apply those variables, e.g mysql_query($query, $connect1) or mysql_query($query, $connect2).
From there you can extract and insert using code.