Mysql output data in csv without using outfile in query - mysql

In the following command how can i output the data to be separated by comma(i.e, csv) ,I want the output in csv but i do not want to use the into outfile .Any way of doing this by changuing the query,
mysql -uroot -ppassword -h112.30.16.11 -e 'select * from Employee.conditions' > /home/tom/preweb/static/users/aa.com/output.csv

Try this, note each column name and delimiters will have to be added separately.
mysql -uroot -ppassword -h112.30.16.11 -e 'SELECT CONCAT(col1, ',', col2, ',', col3) FROM agents;' > /home/tom/preweb/static/users/aa.com/output.csv
Update based on comment:
This can be made to by dynamic by using prepared statements, in this case the table name should be added in the first parameter where it says 'table-name'
mysql -uroot -ppassword -h112.30.16.11 -e "SET #VTable = 'table-name'; SET #VAllCols = CONCAT('SELECT CONCAT(',(SELECT GROUP_CONCAT(COLUMN_NAME SEPARATOR ',\',\',') FROM information_schema.columns WHERE TABLE_NAME = #VTable GROUP BY table_name),') FROM ', #VTable, ';'); PREPARE stmt FROM #VAllCols; EXECUTE stmt; DEALLOCATE PREPARE stmt;" > /home/tom/preweb/static/users/aa.com/output.csv
Let me know if you need anything else like column headings.
Regards,
James

Related

Convert MySQL Variable Query to PostgreSQL

I have migrated MYSQL database to PostgreSQL and I am now converting my queries to match. I have this MySQL query in the Python file:
SET #Drop_Stm = CONCAT('DROP TABLE ', (SELECT GROUP_CONCAT(TABLE_NAME) AS All_Tables
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%' AND TABLE_SCHEMA = '{client_name}'))
 
I would like to make it works in Postgres, I tried the following but returns error:
WITH Drop_Stm AS (CONCAT('DROP TABLE ', (SELECT STRING_AGG(TABLE_NAME, ',') AS All_Tables
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%' AND TABLE_SCHEMA = '{client_name}')))
LINE 1: WITH Drop_Stm AS (CONCAT('DROP TABLE ', (SELECT STRING_AGG(T...
^
I also tried DECLARE, SET, and DO $$ .. END $$ with no luck
The query itself should be changed to this:
select concat('drop table ', string_agg(format('%I.%I', table_schema, table_name), ','), ' cascade;')
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%'
AND TABLE_SCHEMA = '{client_name}'
Note that I used the format() function to properly deal with identifiers needing quoting. I also generated a fully qualified table name (including the schema) so that you don't accidentally drop a table in the current schema, rather than {client_name}.
If you want to run the generated script, I see two options. One is to put this into a PL/pgSQL block and use execute:
do
$$
declare
l_stmt text;
begin
select concat('drop table ', string_agg(format('%I.%I', table_schema, table_name), ','), ' cascade;')
into l_stmt
FROM information_schema.tables
WHERE TABLE_NAME LIKE 'temp_%'
AND TABLE_SCHEMA = '{client_name}';
execute l_stmt;
end;
$$
;
I don't know Python, so I am not entirely sure if {client_name} gets replaced correctly with that approach.
Another option is to run the SELECT query in Python, and store the result into a Python variable then run that SQL through Python.

MySQL - create a table with all of the fields that two tables have [duplicate]

I have to convert a MSSQL stored proc that passes a varchar that is a query:
INSERT INTO Results
EXEC (#Expresion);
This isn't working. I'm pretty sure that EXEC and EXECUTE aren't MySQL commands, but CALL doesn't work either.
Does anyone know if it's even possible to have something like JavaScript's eval function for MySQL?
I think you're looking for something like this:
SET #queryString = (
SELECT CONCAT('INSERT INTO user_group (`group_id`,`user_id`) VALUES ', www.vals) as res FROM (
SELECT GROUP_CONCAT(qwe.asd SEPARATOR ',') as vals FROM (
SELECT CONCAT('(59,', user_id, ')') as asd FROM access WHERE residency = 9
) as qwe
) as www
);
PREPARE stmt FROM #queryString;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #asd = NULL;
This is the SQL equivalent of eval(my_string);:
#Expression = 'SELECT "Hello, World!";';
PREPARE myquery FROM #Expression;
EXECUTE myquery;
Basically I combined the existing answers, neither tells you how to do eval exactly.
If you want to add parameters, you can use this:
#username = "test";
#password = "asdf";
#Expression = 'SELECT id FROM Users WHERE name = ? AND pass = ?;'
PREPARE myquery FROM #Expression;
EXECUTE myquery USING #username, #password;
And to answer the original question exactly:
#Expression = 'SELECT "Hello, World!";'
PREPARE myquery FROM #Expression;
INSERT INTO Results
EXECUTE myquery;
Note that the PREPARE ... FROM statement wants a session variable (prefixed with #). If you try to pass a normal variable, it will throw its hands up in the air and it just won't care.
EXECUTE is a valid command in MySQL. MySQL reference manual
The EXECUTE MySQL command can only be used for one prepared statement.
If case you want to execute multiple queries from the string, consider saving them into file and source it, e.g.
SET #query = 'SELECT 1; SELECT 2; SELECT 3;';
SELECT #query INTO OUTFILE '/tmp/temp.sql';
SOURCE /tmp/temp.sql;

Using tablenames as argument in execute prepared statement

Working in the query-box of phpMyAdmin I want to write an outfile 'protokoll' for each table in a MySQL 5.5 database. As I have many databases that contain the same tables and are different by name only, I want the filename of the outfile to look like
/tmp/dbname_protokoll_tablename_.csv
This works:
SELECT DATABASE() into #client;
SET #dir = '/tmp/';
SET #table = 'Adressen';
SET #stmt = CONCAT( 'SELECT * from ', #table, ' WHERE MarkDel=1 into outfile ''', #dir, #client , '_Protokoll_', #table , '.csv'' CHARACTER SET utf8 FIELDS TERMINATED BY '','' OPTIONALLY ENCLOSED BY ''"'' LINES TERMINATED BY ''\r\n'' ');
PREPARE DoExport from #stmt;
EXECUTE DoExport;
DEALLOCATE PREPARE DoExport;
From what I read about prepare, I should be able to use a '?' inside the statement, like
SET #stmt = CONCAT( 'SELECT * from ? WHERE MarkDel=1 into outfile ...
and then execute this with a list of arguments like
EXECUTE DoExport USING 'Adressen', 'Familien', 'Kinder';
but I can't get this to work, all I receive is an unspecific syntax error. How do I have to rewrite this?

Run a query foreach databases (mysql)

I'm looking for a straight way to run a query on all databases hosted on my mysql server.
I have a bunch of Magento installations and I want to truncate all Magento log table on all databases:
log_customer
log_visitor
log_visitor_info
log_url
log_url_info
log_quote
report_viewed_product_index
report_compared_product_index
report_event
catalog_compare_item
I think it something very easy to accomplish in mysql but I cannot find a straight answer/solution.
*UPDATE *
According to #Ollie Jones it is not possible to do it without a STORE PROCEDURE or a server side language ( PHP or whatever )
UPDATE 1
I choose to follow the PHP approach (#samitha) for 2 reasons:
STORE PROCEDURE looks more complicated
Query on 'information_schema' table is very slow ( at least if you have many DB/TABLES)
SELECT DISTINCT SCHEMA_NAME AS `database`
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')
ORDER BY SCHEMA_NAME
gets you a list of all the non-MYSQL databases on your system.
SELECT TABLE_SCHEMA AS `database`,
TABLE_NAME AS `table`
FROM information_schema.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_SCHEMA, TABLE_NAME
gets you a list of all the actual tables (excluding SYSTEM VIEWs like the TABLES table, and user-defined views) in all the databases.
Then, you should implement logic in your program to ensure that, for each database, it really is a Magento database before you truncate certain tables. Otherwise, you might become a despised person among your co-workers. :-)
Edit
Here's a stored procedure.
You need to edit it to do exactly what you need it to do; in particular, it counts rows rather than truncating tables, and it doesn't contain the correct list of log tables. (It would be irresponsible for me to publish such a wildly destructive stored procedure; you should edit it yourself to do the destructive part.)
DELIMITER $$
DROP PROCEDURE IF EXISTS `zap_magento_logs`$$
CREATE PROCEDURE `zap_magento_logs`()
BEGIN
-- declare variables for database and table names
DECLARE dbname VARCHAR(128) DEFAULT '';
DECLARE tbname VARCHAR(128) DEFAULT '';
DECLARE done INTEGER DEFAULT 0;
-- declare cursor for list of log tables
DECLARE log_table_list CURSOR FOR
SELECT TABLE_SCHEMA AS `database`,
TABLE_NAME AS `table`
FROM `information_schema`.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME IN
(
'log_customer',
'log_visitor',
'log_visitor_info',
'log_url',
'log_url_info',
'log_quote'
)
ORDER BY TABLE_SCHEMA, TABLE_NAME;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET done = 1;
OPEN log_table_list;
log_table: LOOP
FETCH log_table_list INTO dbname, tbname;
IF done = 1 THEN
LEAVE log_table;
END IF;
-- create an appropriate text string for a DDL or other SQL statement
SET #s = CONCAT('SELECT COUNT(*) AS num FROM ',dbname,'.',tbname);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP log_table;
CLOSE log_table_list;
END$$
DELIMITER ;
You run this by issuing the SQL command
CALL zap_magento_logs();
A PHP approach would be:
$tables = array(
'log_customer',
'log_visitor',
'log_visitor_info',
'log_url',
'log_url_info',
'log_quote',
'report_viewed_product_index',
'report_compared_product_index',
'report_event',
'catalog_compare_item',
);
$dbh = new PDO('mysql:host=localhost;', 'USERNAME', 'PASSWORD', array(
PDO::ATTR_PERSISTENT => true
));
$sql = $dbh->query('SHOW DATABASES');
$getAllDbs = $sql->fetchALL(PDO::FETCH_ASSOC);
foreach ($getAllDbs as $DB) {
foreach ($tables as $table) {
$dbh->query('TRUNCATE TABLE ' . $DB['Database'] . '.' . $table);
};
};
I didn't feel like writing code to solve this so I found a different solution. I wrote SQL that generates the SQL that I need. So I saved the following to a file called createSomeSQL.sql:
SET sql_mode='PIPES_AS_CONCAT';
select
'truncate table ' || dbs.database || '.someLogTable;'
as ''
from (SELECT DISTINCT SCHEMA_NAME AS `database`
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql', 'test')
ORDER BY SCHEMA_NAME) as dbs;
You could replace the SQL in line 4 with anything you want. Then I ran this command to generate the SQL that I need:
mysql -u root -p < createSomeSQL.sql > sqlToExecute.sql
Replace "root" with your username, of course. Now the file sqlToExecute.sql contains a script you can run to execute that SQL against all your databases.
Try the following (very basic, no error handling, may not work at all, I've not tested this):
$db = mysqli_connect(); // your database connection
$tables = ["log_customer", "log_visitor", "log_visitor_info"]; // array with all the tables
foreach ($tables as $table) {
mysqli_query($db, "TRUNCATE TABLE `".$table."`"); // executes query for each element in the array
}

convert mysql stored procedure to mssql

I need to used dynamic order query in mysql and i have successfully achieved that through string concatenation in mysql as follows:
set #stmt_text := concat('select * from abc order by ',sorder);
prepare stmt_handle from #stmt_text;
execute stmt_handle;
deallocate prepare stmt_handle;
i need a similar way to convert this in mssql
Any ideas??
Yes, just run it like this:
execute ('select * from abc order by ' + #sorder);
But don't forget that you need to verify the sorder variable if you get it through user input (to stop sql-injections)