Delphi ListBox to a Text file with a specific string - mysql

I am still fairly new to Delphi and learning new things every day.
What I am trying to do is generate multiple MySQL queries into a .txt that I can have backed up for when I need them.
Basically I have the following setup.
A VCL program that currently at the click of a button captures the list of tables that exist on my one database.
The tables are listed into a ListBox and gives me a count of the total tables that I have.
Now how would I go about doing the following:
I want it to capture the name of the first item in the ListBox and then create a .txt file and insert the name of the item into a specific text string, eg:
mysqldump -uroot -pxxxx -D[]database [tablename] > [tablename]
The sections where it is in [] I need the item from the ListBox being inserted there and need this to repeat onto the next time.
I have 249 tables that I need to generate these queries for and someone suggested that I can do a Delphi app that can do this pretty quickly and automated for me. It is basically for a large scale table dump and then import.
I know this is really long winded and just looking for some guidelines and tips on how I can do this.
I am doing this locally and I do not wish to use myDAC or FireDAC I would like it to be done locally without needed to access the database through MySQL or anything of the such. Just want it to generate my queries to a .txt file.

Try something like this:
var
DBName, TableName: string;
SL: TStringList;
begin
DBName := 'yourdbname';
TableName := ListBox1.Items[0];
SL := TStringList.Create;
try
SL.Add(Format('mysqldump -uroot -pxxxx -D%s %s > %1:s', [DBName, TableName]));
SL.SaveToFile('c:\folder\query.txt');
finally
SL.Free;
end;
end;

IF I understood you right, you have a TListBox with table names from which you want to create queries. You did not
In that case, you need something like this:
var F : TexFile;
I : integer;
begin
AssignFile(F, 'queries.txt');
Rewrite(F);
for I := 0 to ListBox1.Items.Count - 1 do
Writeln(F, 'mysqldump -uroot -pxxxx -D[database] ['+ListBox1.Items[I]+'] > ['+ListBox1.Items[I]+']');
CloseFile(F);
end;

To make strings like that I would suggest using the format function.
All you'll need is the SysUtils unit.
It would make your code look like this:
Table1 := 'FirstTable';
Table2 := 'SecondTable';
Format('mysqldump -uroot -pxxxx -D[]database %s > %s', [Table1, Table2]);
//Results in mysqldump -uroot -pxxxx -D[]database FirstTable > SecondTable
Just simply replace the Table1 and Table2 with the text of the selected item in your listbox.
Hope this helped you in any way :)

Related

How to switch between databases using GORM in golang?

I'm new to GORM in golang. I'm stuck at a point. Generally we select the database like this:
DBGorm, err = gorm.Open("mysql", user:password#tcp(host:port)/db_name)
But my problem is I'll get the 'db_name' in the request, which means I don't know which db_name might come and I'll have to query according to that db_name.
So now, I'll create the database pointer in the init function like this:
DBGorm, err = gorm.Open("mysql", user:password#tcp(host:port)/) which is without the db_name.
Now how will I switch to db_name coming to me in request. Because when I try to do DBGorm.Create(&con), it shows No database selected.
If I use 'database/sql', then I can make raw queries like this: "SELECT * FROM db_name.table_name", this can solve my problem. But how to do this in gorm?
You can explicitly specify db_name and table_name using .Table() when doing query or other operation on table.
DBGorm.Table("db_name.table_name").Create(&con)
I saw a related article on Github. https://github.com/go-sql-driver/mysql/issues/173#issuecomment-427721651
All you need to do is
start a transaction,
set you database
run your desired query.
and switch back to your desired DB
commit once you are done.
below is an example
tx := db.Begin() // start transaction
tx.Exec("use " + userDB) // switch to tenant db
tx.Exec("insert into ....") // do some work
tx.Exec("use `no-op-db`") // switch away from tenant db (there is no unuse, so I just use a dummy)
tx.Commit() // end transaction

Delete substring via all mysql database at one query

I have a problem, cause some kind of malware have got to my site. I would like to delete all malware code from DB with 1 query. I believe it's possible.
I can't delete all rows, the malware has added a little code to each page/article/gallery/... title. So I would like to preserve original title of article. I hope it's possible.
For example:
<script src="...">...</script>About us
I need to About us will remain in database.
How can I do that via all database at once?
You can use string functions to do this.
Here's a demo:
mysql> SET #t = 'See <script src="...">...</script>About us';
mysql> SELECT CONCAT(
SUBSTRING(#t, 1, LOCATE('<script ', #t)-1),
SUBSTRING(#t, LOCATE('</script>', #t)+LENGTH('</script>'))) AS newstring;
+--------------+
| newstring |
+--------------+
| See About us |
+--------------+
This assumes the script tag only occurs once per string.
Then you'll have to use UPDATE to correct the data, one column and one table at a time:
UPDATE MyTable
SET MyStringColumn = CONCAT(
SUBSTRING(MyStringColumn, 1, LOCATE('<script ', MyStringColumn)-1),
SUBSTRING(MyStringColumn, LOCATE('</script>', MyStringColumn)+LENGTH('</script>')));
Another solution if you want to do all tables and all columns at once is to dump your database to a text file, and use a text editor to do global search and replace.
$ mysqldump mydatabase > mydatabase.sql
$ vim mydatabase.sql
:%s/<script src=.*<\/script>//g
$ mysql mydatabase < mydatabase.sql
Of course any data that changed between the dump and the restore will be overwritten.
If you can't pause changes to your database, you'll have to use the UPDATE solution to change data in-place.

MySQL: Is there a way to return a list of functions / procedures filtered by a string found within the code?

Basically I have the unenviable position of updating our entire system to stop using a certain table and instead use another one. I've already done this for all of our code, now I need to do it for all of our functions and procedures.
I know that I can get a list of the functions / procedures in a database as such:
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
I also know that I can look at the code for an individual function / procedure as such:
SHOW CREATE FUNCTION function_name
SHOW CREATE PROCEDURE procedure_name
However, I don't want to have to look through each function and procedure one by one, as we have over 200 of them.
I'm wondering if there is anything like...
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE code_column_name LIKE '%search_string%'
There doesn't seem to be any column in INFORMATION_SCHEMA.ROUTINES that contains the code, but... is there a way to do this on a different table perhaps?
I would use UNIX grep for that.
If you output the results of show create function/procedure to a flat file on disk then run grep on it. Or turn it directly thru grep.
Here is one way to do it:
echo 'show create function foo' | mysql -h*host* -u*user* -p*pass* *schema* | grep *obsolete-tablename*
or dump the entire database to disk and then grep it.
mysqldump -h*host* -u*user* -p*pass* *schema --routines > mydump.sql
grep *obsolete-tablename mydump.sql
Try:
SELECT * FROM mysql.proc WHERE body LIKE '%search_string%'
You asked about MySQL but I will just mention that I use this for stored procedures in MS SQL Server:
SELECT object_name(id)
FROM syscomments
WHERE text LIKE '%wibble%'
The INFORMATION_SCHEMA.ROUTINES table (which you mention) also contains similar stuff, but the text is cut off after 4000 chars, so you find less matches; not very helpful.

Running an INSERT statement automatically using Command Line

I have a statement that I run from MySQL Workbench that works just the way I want it.
INSERT INTO queuelist(songID)
select ID from songlist where filename LIKE CONCAT('%', substring(curdate(), 6,5) ,'%') order by filename
I now want to automate the process using Windows Scheduler and a batch file. I am fairly new to this process and not very familiar with how the command line works. I started like this:
mysql -u username -pMyPassword -D MyDatabase < code.sql
Where code.sql contains the query that I posted above -- When I run this, I get completely different results from when I run it in Workbench. Do I need to format it differently?
Thanks
Chuck
Why don't you put that insert statement into a MySQL event? Then the DB engine will run it for you automatically.
delimiter //
CREATE EVENT IF NOT EXISTS your_event
ON SCHEDULE EVERY 1 DAY
STARTS '2014-08-19 12:00:00'
ON COMPLETION PRESERVE ENABLE
DO
INSERT INTO queuelist(songID)
select ID
from songlist
where filename LIKE CONCAT('%', substring(curdate(), 6,5) ,'%')
order by filename
//
You need to adjust the times when it should run in the code above

Find and Replace text in the entire table using a MySQL query

Usually I use manual find to replace text in a MySQL database using phpMyAdmin. I'm tired of it now, how can I run a query to find and replace a text with new text in the entire table in phpMyAdmin?
Example: find keyword domain.example, replace with www.domain.example.
For a single table update
UPDATE `table_name`
SET `field_name` = replace(same_field_name, 'unwanted_text', 'wanted_text')
From multiple tables-
If you want to edit from all tables, best way is to take the dump and then find/replace and upload it back.
The easiest way I have found is to dump the database to a text file, run a sed command to do the replace, and reload the database back into MySQL.
All commands below are bash on Linux.
Dump database to text file
mysqldump -u user -p databasename > ./db.sql
Run sed command to find/replace target string
sed -i 's/oldString/newString/g' ./db.sql
Reload the database into MySQL
mysql -u user -p databasename < ./db.sql
Easy peasy.
Running an SQL query in phpMyAdmin to find and replace text in all WordPress blog posts, such as finding mysite.example/wordpress and replacing that with mysite.example/news
Table in this example is tj_posts
UPDATE `tj_posts`
SET `post_content` = replace(post_content, 'mysite.example/wordpress', 'mysite.example/news')
Put this in a php file and run it and it should do what you want it to do.
// Connect to your MySQL database.
$hostname = "localhost";
$username = "db_username";
$password = "db_password";
$database = "db_name";
mysql_connect($hostname, $username, $password);
// The find and replace strings.
$find = "find_this_text";
$replace = "replace_with_this_text";
$loop = mysql_query("
SELECT
concat('UPDATE ',table_schema,'.',table_name, ' SET ',column_name, '=replace(',column_name,', ''{$find}'', ''{$replace}'');') AS s
FROM
information_schema.columns
WHERE
table_schema = '{$database}'")
or die ('Cant loop through dbfields: ' . mysql_error());
while ($query = mysql_fetch_assoc($loop))
{
mysql_query($query['s']);
}
phpMyAdmin includes a neat find-and-replace tool.
Select the table, then hit Search > Find and replace
This query took about a minute and successfully replaced several thousand instances of oldurl.ext with the newurl.ext within Column post_content
Best thing about this method : You get to check every match before committing.
N.B. I am using phpMyAdmin 4.9.0.1
Another option is to generate the statements for each column in the database:
SELECT CONCAT(
'update ', table_name ,
' set ', column_name, ' = replace(', column_name,', ''www.oldDomain.example'', ''www.newDomain.example'');'
) AS statement
FROM information_schema.columns
WHERE table_schema = 'mySchema' AND table_name LIKE 'yourPrefix_%';
This should generate a list of update statements that you can then execute.
UPDATE table SET field = replace(field, text_needs_to_be_replaced, text_required);
Like for example, if I want to replace all occurrences of John by Mark I will use below,
UPDATE student SET student_name = replace(student_name, 'John', 'Mark');
If you are positive that none of the fields to be updated are serialized, the solutions above will work well.
However, if any of the fields that need updating contain serialized data, an SQL Query or a simple search/replace on a dump file, will break serialization (unless the replaced string has exactly the same number of characters as the searched string).
To be sure, a "serialized" field looks like this:
a:1:{s:13:"administrator";b:1;}
The number of characters in the relevant data is encoded as part of the data.
Serialization is a way to convert "objects" into a format easily stored in a database, or to easily transport object data between different languages.
Here is an explanation of different methods used to serialize object data, and why you might want to do so, and here is a WordPress-centric post: Serialized Data, What Does That Mean And Why is it so Important? in plain language.
It would be amazing if MySQL had some built in tool to handle serialized data automatically, but it does not, and since there are different serialization formats, it would not even make sense for it to do so.
wp-cli
Some of the answers above seemed specific to WordPress databases, which serializes much of its data. WordPress offers a command line tool, wp search-replace, that does handle serialization.
A basic command would be:
wp search-replace 'an-old-string' 'a-new-string' --dry-run
However, WordPress emphasizes that the guid should never be changed, so it recommends skipping that column.
It also suggests that often times you'll want to skip the wp_users table.
Here's what that would look like:
wp search-replace 'https://old-domain.example' 'https://shiney-new-domain.com' --skip-columns=guid --skip-tables=wp_users --dry-run
Note: I added the --dry-run flag so a copy-paste won't automatically ruin anyone's database. After you're sure the script does what you want, run it again without that flag.
Plugins
If you are using WordPress, there are also many free and commercial plugins available that offer a gui interface to do the same, packaged with many additional features.
Interconnect/it PHP script
Interconnect/it offers a PHP script to handle serialized data: Safe Search and Replace tool. It was created for use on WordPress sites, but it looks like it can be used on any database serialized by PHP.
Many companies, including WordPress itself, recommends this tool. Instructions here, about 3/4 down the page.
UPDATE `MySQL_Table`
SET `MySQL_Table_Column` = REPLACE(`MySQL_Table_Column`, 'oldString', 'newString')
WHERE `MySQL_Table_Column` LIKE 'oldString%';
I believe "swapnesh" answer to be the best ! Unfortunately I couldn't execute it in phpMyAdmin (4.5.0.2) who although illogical (and tried several things) it kept saying that a new statement was found and that no delimiter was found…
Thus I came with the following solution that might be usefull if you exeprience the same issue and have no other access to the database than PMA…
UPDATE `wp_posts` AS `toUpdate`,
(SELECT `ID`,REPLACE(`guid`,'http://old.tld','http://new.tld') AS `guid`
FROM `wp_posts` WHERE `guid` LIKE 'http://old.tld%') AS `updated`
SET `toUpdate`.`guid`=`updated`.`guid`
WHERE `toUpdate`.`ID`=`updated`.`ID`;
To test the expected result you may want to use :
SELECT `toUpdate`.`guid` AS `old guid`,`updated`.`guid` AS `new guid`
FROM `wp_posts` AS `toUpdate`,
(SELECT `ID`,REPLACE(`guid`,'http://old.tld','http://new.tld') AS `guid`
FROM `wp_posts` WHERE `guid` LIKE 'http://old.tld%') AS `updated`
WHERE `toUpdate`.`ID`=`updated`.`ID`;
the best you export it as sql file and open it with editor such as visual studio code and find and repalace your words.
i replace in 1 gig file sql in 1 minutes for 16 word that total is 14600 word.
its the best way.
and after replace it save and import it again.
do not forget compress it with zip for import.
In the case of sentences with uppercase - lowercase letters,
We can use BINARY REPACE
UPDATE `table_1` SET `field_1` = BINARY REPLACE(`field_1`, 'find_string', 'replace_string')
Here's an example of how to find and replace in Database
UPDATE TABLE_NAME
SET COLUMN = replace(COLUMN,'domain.example', 'www.domain.example')
TABLE_NAME => Change it with your table name
COLUMN => Change it to your column make sure it exists
I have good luck with this query when doing a search and replace in phpmyadmin:
UPDATE tableName SET fieldName1 = 'foo' WHERE fieldName1 = 'bar';
Of course this only applies to one table at a time.
Generate change SQL queries (FAST)
mysql -e "SELECT CONCAT( 'update ', table_name , ' set ', column_name, ' = replace(', column_name,', ''www.oldsite.example'', ''www.newsite.example'');' ) AS statement FROM information_schema.columns WHERE table_name LIKE 'wp_%'" -u root -p your_db_name_here > upgrade_script.sql
Remove any garbage at the start of the file. I had some.
nano upgrade_script.sql
Run generated script with --force options to skip errors. (SLOW - grab a coffee if big DB)
mysql -u root -p your_db_name_here --force < upgrade_script.sql