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.
Related
I am looking for some ideas or help on how I could make my query a little less resource intensive but I am not sure if there is an easier way to do what I am doing.
I have a search Store Proc that takes in a large number of parameters to search the database for different products. The user can search for multiple makes and models etc in the same search.
The way I work the search is the parameters are all organised and the call of the store procedure is produced and saved in the data base this is then called and the store procedure is executed and the results returned.
An example:
Make Ids selected : 1 ,2 ,3 ,4
Model IDs selected : 2,3,4
Proc call generated "Call my_store_prod ('1,2,3,4','2,3,4')"
This is saved in the database with a random string eg "wmF14ndfglq2p3yuMMM6cr" then this is used to call the store proc using $_Get['search_id'] www.site.com?search=wmF14ndfglq2p3yuMMM6cr
In the Store proc I then create some temp tables:
DROP TEMPORARY TABLE IF EXISTS tmp_manufacturer_id;
CREATE TEMPORARY TABLE tmp_manufacturer_id (manufacturer_id varchar(255));
/*MODEL_ID*/
DROP TEMPORARY TABLE IF EXISTS tmp_model_id;
CREATE TEMPORARY TABLE tmp_model_id (model_id varchar(255));
Then use a funtion to split the string of ids '1,2,3,4' and insert into the temp tables:
CALL sp_split(#manufacturer_id,'tmp_manufacturer_id');
/*MODEL_ID*/
CALL sp_split(#model_id,'tmp_model_id') ;
Then in the where clause I have something like this:
CASE WHEN #manufacturer_id = ''
THEN information_view.advert_id = information_view.advert_id
ELSE information_view.manufacturer_id IN (select * from tmp_manufacturer_id2)end
AND
CASE WHEN #model_id = ''
THEN information_view.advert_id = information_view.advert_id
ELSE information_view.model_id IN (select * from tmp_model_id2)end
This all is working fine but one of my problems is I need to return 7 Random "Featured" Adverts with the same search results.
The only that I have thought of is to do a UNION with the same query only with a
order by rand()
LIMIT 7
I was wondering if there would be an easier way to get my 7 random adverts without having to duplicate the whole query?
Any pointers for be really useful.
Server version: 5.7.37-log - MySQL Community Server (GPL)
Is it possible to write a query which uses tables which are in different databases on different servers?
I have table_1 which exists in database "db1" on server1 and there is another table table_2 which exists in database "db2" on server2.
How can I do this?
The servers can be any of MySQL, HSQL or MS-SQL.This is the main question that.........there are not different server but also different type of servers.
Will sp_addlinkedserver work for such case???
Set up linked servers on the MS SQL server. Then you can just query both servers like
select * from [server1].[database].[dbo].[table]
and
select * from [server2].[database]..[table]
or use OPENQUERY (might be preferred cause this just sends the command to the other server rather than the source server trying to parse it)
You'll need to use sp_addlinkedserver to create a server link. See the reference documentation for usage. Once the server link is established, you'll construct the query as normal, just prefixing the database name with the other server. I.E:
-- FROM DB1
SELECT *
FROM [MyDatabaseOnDB1].[dbo].[MyTable] tab1
INNER JOIN [DB2].[MyDatabaseOnDB2].[dbo].[MyOtherTable] tab2
ON tab1.ID = tab2.ID
Once the link is established, you can also use OPENQUERY to execute a SQL statement on the remote server and transfer only the data back to you. This can be a bit faster, and it will let the remote server optimize your query. If you cache the data in a temporary (or in-memory) table on DB1 in the example above, then you'll be able to query it just like joining a standard table. For example:
-- Fetch data from the other database server
SELECT *
INTO #myTempTable
FROM OPENQUERY([DB2], 'SELECT * FROM [MyDatabaseOnDB2].[dbo].[MyOtherTable]')
-- Now I can join my temp table to see the data
SELECT * FROM [MyDatabaseOnDB1].[dbo].[MyTable] tab1
INNER JOIN #myTempTable tab2 ON tab1.ID = tab2.ID
Check out the documentation for OPENQUERY to see some more examples. The example above is pretty contrived. I would definitely use the first method in this specific example, but the second option using OPENQUERY can save some time and performance if you use the query to filter out some data.
The following Query will helpful.
SELECT TS1.COLUMN01, TS2.COLUMN02
FROM Server1.DBName..TableName TS1, Server2.DBName..TableName TS2
WHERE TS1.COLUMN03 = TS2.COLUMN03
In my project I have two code paths that interact with MySQL during first time setup. The first step is the database structure creation, in here, a user has the ability to pick and choose the features they want - and some tables may not end up being created in the database depending on what the user selects.
In the second part, I need to preload the tables that did get created with some basic data - how could I go about inserting rows into these tables, only if the table exists?
I know of IF NOT EXISTS but as far as I know, that only works with creating tables, I am trying to do something like this
INSERT INTO table_a ( `key`, `value` ) VALUES ( "", "" ) IF EXISTS table_a;
This is loaded through a file that contains a lot of entries, so letting it throw an error when the table does not exist is not an option.
IF (SELECT count(*)FROM information_schema.tables WHERE table_schema ='databasename'AND table_name ='tablename') > 0
THEN
INSERT statement
END IF
Use information schema to check existence if table
If you know that a particular table does exist with at least 1 record (or you can create a dummy table with just a single record) then you can do a conditional insert this way without a stored procedure.
INSERT INTO table_a (`key`, `value`)
SELECT "", "" FROM known_table
WHERE EXISTS (SELECT *
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'table_a')) LIMIT 1;
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(...);
Maybe my question above may be could be stupid , but I just want to know if is it possible to have insert query inside select or where.
The reason that I want to know that is if someone hack website or any application database, can the hacker input data to hacked database without my knowledge ?
the following example of SQL injection I see in other sites
http://www.example.com/empsummary.php?id=1 AND 1=-1 union select 1,group_concat(name,0x3a,email,0x3a,phone,0x2a),3,4,5,6,7,8,9 from employee
I know what exactly that above query does, but can the hacker input (use insert query) on the database or on any table ?
Yes, it can happen, if the database interface is configured to allow multiple statements in a query.
An INSERT can't run as part of a SELECT statement. But it's possible that the exploit of a vulnerability could finish a SELECT and then execute a separate insert.
Say you have a vulnerable statement like this:
SELECT foo FROM bar WHERE fee = '$var'
Consider the SQL text when $var contains:
1'; INSERT INTO emp (id) VALUES (999); --
The SQL text could be something like this:
SELECT foo FROM bar WHERE fee = '1'; INSERT INTO emp (id) VALUES (999); --'
If multi-statement queries are enabled in the database interface library, it's conceivable that an INSERT statement could be executed.
See: https://www.owasp.org/index.php/SQL_Injection