Execute batch file with arguments - mysql

I'm working on a project that require me to use window task scheduler to execute mysql query, this is the batch file content:
mysql -ufoo -pbar -D %1 < %2
when I tested the batch file via cmd:
task_sheduler.bat dbName pathToSqlFile
I get:
mysql -ufoo -pbar -D dbName 0<pathToSqlFile
I just want to say that its working, my question is what is about the extra space and the 0, where did they came from?
The extra space is between the dbName and 0
I'm using Windows 7 Ultimate Service Pack 1 (x64)

I assume your Batch file does NOT have an #echo off command, so you refer to the echo of commands that appear in the screen when a Batch file is executed. The display of these commands frequently include additional characters that cmd.exe inserts to display exactly the executed commands.
In the case of redirections, <input is a short form of Stdin redirection, and the number of Stdin is zero, so the real redirection is 0<input. The same happens with >output, that is echoed as 1>output. cmd.exe also remove multiple spaces from the original code and insert needed ones in order to clearly show the executed commands.
If you want not to see these command expantions, just insert an #echo off command at beginning of your Batch file.

cmd prefixes all redirection commands by the default handle if none is provided. The handles are defined here. 0<file thus means that we want file to be redirected to standard input. The extra space is there to prevent a command like hi.exe<myfile from being wrongly interpreted as hi.exe0 < myfile

Related

Tcl: Get stdout from exec bash

Within tclsh I can run the following and get the expected output:
% exec bash -c "ulimit -v"
50331648
However within a Tcl script nothing is returned. No error, no output, nothing. There's clearly some gotcha with exec'ing 'bash -c' that I can't work out.
Alternatively, is there a native way in Tcl that I can get the system's memory limit to avoid having to do it this way in the first place?
In an interactive tclsh session, the REPL helpfully prints the output of commands/expressions. That's not the case in a non-interactive program.
exec returns the output of the command: you just need to capture it with the usual command substitution:
set output [exec bash -c "ulimit -v"]
puts $output
The code that you wrote should work; I can't identify why bash would silently fail to run ulimit -v. Even if the script was running in an environment where that was privileged information (why!?) one would still expect to get an error message of some form. That's a very weird problem!
Tcl's base command set doesn't expose any access to memory limits, whether for reading or writing. The simplest workaround that doesn't call an external program is the tclbsd package (apparently it mostly works on most other Unixes as well), which exposes a command that should help:
package require BSD
set limit [bsd::rlimit get soft virtual]

Executing a batch file to create a test file with xp_cmdshell - differentt results

I'm trying to execute a batch file in SQL Server 2008 Express using xp_cmdshell. If I use it to execute a batch file that contains the following command:
echo > C:\development\test\itworks.txt
a file called "itworks.txt" is created and inside it text says "ECHO is on".
But if I run a batch file that contains the command:
CD. >test1.txt
it doesn't work (no error, just nothing created)
and neither does:
type NUL > test2.txt
although both those batch files do create the file if double clicked/run from command prompt. I thought it might be a permissions error (I hadn't tried the echo command at that point), so changed file permissions so that NTAuthority (which is what the SQLServer service runs as) had full control over the folder but it still didn't work. Nothing in event logs. I'm a novice at DOS commands so I don't really understand the different commands. Does anyone have any idea what might be going on?
If you test the commands directly at a command prompt, they work. The cd statement produces a text file containing the name of the current directory; the type statement produces a zero-byte file, but it does indeed produce a file.
Most likely, xp_cmdshell is executing in a folder where the account it's running under has no write privileges, and you're not specifying another location for the file to be written. (The echo statement that works specifies a folder location for the text file, while your other two don't.)
Change your batch file to:
cd > C:\development\test\test1.txt
or
type NUL > C:\development\test\test1.txt
If the echo statement works there when run via xp_cmdshell, you know it's writable by the NTAuthority account.

Liquibase Diff operation not producing output file

I'm trying to run a liquibase diff operation on two tables.
The operation appears to work fine as I can see all the comparisons happening in Command Prompt. The only issue I have is that no file is being output. Here's my code, I've added line breaks to help readability:
java -jar liquibase/liquibase.jar
--driver=com.mysql.jdbc.Driver
--classpath=/liquibase/changelog-generating/mysql-connector-java-5.1.13.jar
--changeLogFile=liquibase/local.table.changelog.xml
--url="jdbc:mysql://localhost/table1"
--username=root
--password=""
diff
--referenceUrl="jdbc:mysql://localhost/table2"
--referenceUsername=root
--referencePassword=""
When I run the command without the diff and reference variables, I do receive an output file.
Access to the databases work without password (it is only local host after all).
Liquibase is installed in C:/liquibase
I'm using Windows Vista
Sorted. Was missing the...
generateChangeLog
at the end of the command.

Batch files and MySQL: pass a block of commands instead of another .bat file

I see that I can pass a batch file to mysql in order to run a sequence of commands. But can I put those commands in the same batch file as the one that initiates the mysql app?
I.e. can I pass a block of batch commands to mysql instead of passing a batch file, so that it might look something like this:
mysql < [list of commands, not a .bat filename]
You can also pipe commands into MySQL if you don't want/have them in a file:
echo " ...some SQL... " | mysql
The term "Batch file" in the mySQL manual doesn't refer to DOS .BAT files, but to a file with many mySQL commands.
mysql < list.sql
will do exactly what you need.

MySQL Memory engine + init-file

I'm trying to set up a MySQL database so that the tables are ran by the memory engine. I don't really care about loosing some data that gets populated but I would like to dump it daily (via mysqldump in a cronjob) and have the init-file set to this dump. However I can't seem to figure out how to get the mysqldump to be compatable with how the init-file wants the SQL statements to be formatted.
Am I just missing something completely obvious trying to set up a database this way?
MySQL dumps are exactly that -- dumps of the MySQL database contents as SQL. So, there isn't any way to read this directly as a database file.
What you can do, is modify your init script for MySQL to automatically load the last dump (via the command line) every time MySQL starts.
An even better solution would be to use a ramdisk to hold the entire contents of your database in memory, and then periodically copy this to a safe location as your backup.
Although, if you want to maintain the contents of your databases at all, you're better off just using one of the disk-based storage engines (InnoDB or MyISAM), and just giving your server a lot of RAM to use as a cache.
This solution is almost great, but it causes problems when string values in table data contain semicolons - all of them are replaced with newline char.
Here is how I implemented this:
mysqldump --comments=false --opt dbname Table1 Table2 > /var/lib/mysql/mem_tables_init.tmp1
#Format dump file - each statement into single line; semicolons in table data are preserved
grep -v -- ^-- /var/lib/mysql/mem_tables_init.tmp1 | sed ':a;N;$!ba;s/\n/THISISUNIQUESTRING/g' | sed -e 's/;THISISUNIQUESTRING/;\n/g' | sed -e 's/THISISUNIQUESTRING//g' > /var/lib/mysql/mem_tables_init.tmp2
#Add "USE database_name" instruction
cat /var/lib/mysql/mem_tables_init.tmp2 |sed -e 's/DROP\ TABLE/USE\ `dbname`;\nDROP\ TABLE/' > /var/lib/mysql/mem_tables_init.sql
#Cleanup
rm -f /var/lib/mysql/mem_tables_init.tmp1 /var/lib/mysql/mem_tables_init.tmp2
My understanding is that the --init-file is expecting each SQL statement on a single line and that there are no comments in the file.
You should be able to clear up the comments with:
mysqldump --comments=false
As for each SQL statement on one line, I'm not familiar with a mysqldump option to do that, but what you can do is a line of Perl to remove all of the newlines:
perl -pi -w -e 's/\n//g;' theDumpFilename
I don't know if --init-file will like it or not, but it's worth a shot.
The other thing you could do is launch mysql from a script that also loads in a regular mysqldump file. Not the solution you were looking for, but it might accomplish the effect you're after.
I stumbled onto this, so I'll tell you what I do. First, I have an ip->country db in a memory table. There is no reason to try to "save" it, its easily and regularly dropped and recreated, but it may be unpredictable how the php will act when its missing and its only scheduled to be updated weekly. Second, I have a bunch of other memory tables. There is no reason to save these, as they are even more volatile, with lifespans in minutes. They will be refreshed very quickly, but stale data is better than none at all. Also, if you are using any separate key caches, they may (in some cases) need to loaded first or you will be unable to load them. And finally, be sure to put a "use" statement in there if you're not dumpling complete databases, as there is no other interface (like mysql client) to open the database at start up.. So..
cat << EOF > /var/lib/mysql/initial_load.tmp
use fieldsave_db;
cache index fieldsave_db.search in search_cache;
EOF
mysqldump --comments=false -udrinkin -pbeer# fieldsave_db ip2c \
>> /var/lib/mysql/initial_load.tmp
mysqldump --comments=false -ufields -pavenue -B memtables \
>> /var/lib/mysql/initial_load.tmp
grep -v -- ^-- /var/lib/mysql/initial_load.tmp |tr -d '\012' \
|sed -e 's/;/;\n/g' > /var/lib/mysql/initial_load.sql
As always, YMMV, but it works for me.