how to create a file with these sqlite instruccions using a .bat script? - windows

I want to create the next sqlite instructions using a .bat script and save them in a temp.txt file. The problem is that some parts of the instructions are variable and depend of a list of files in the current directory.
Example:
In my current directory I have the next files: file1.txt, file2.txt, file3.txt and some other that I dont care...
So I need to create the next sqlite sentences:
insert into table1(fileName) values('THE VARIABLE FILE NAME');
insert into table2(something1) select (idTable1) from table1 where fileName = 'THE VARIABLE FILE NAME';
.import THE VARIABLE FILE NAME table3
So the sentences must look like this:
insert into table1(fileName) values('file1.txt');
insert into table2(something1) select (idTable1) from table1 where fileName = 'file1.txt';
.import file1.txt table3
insert into table1(fileName) values('file2.txt');
insert into table2(something1) select (idTable1) from table1 where fileName = 'file2.txt';
.import file2.txt table3
insert into table1(fileName) values('file3.txt');
insert into table2(something1) select (idTable1) from table1 where fileName = 'file3.txt';
.import file3.txt table3
The file where those instruccions will be saved is named temp.txt
So in the end of myScript.bat I want to execute something like this:
sqlite3 < temp.txt
And the information in those files will be imported into my database.
And I already know that I can list those files in my cmd with the next instruction:
dir f*.txt /b
I also know that I can create a empty file like this:
echo. 2> temp.txt
And that I can write the text that I want into that temp.txt file like this:
echo TheseAreMyInstructions >> temp.txt
So myScript should start like this
#echo off // Wont show more info...
echo. 2> temp.txt // Will create the empty file
And I tried something like this
FOR %%a IN (dir f*.txt /b) DO echo insert into table1(fileName) values('%%a') >> temp.txt
I dont know how to put the other instructions here inside the for
And the results arent what i expected...
The results in my temp.txt file are:
insert into table1(fileName) values('dir') // This should not be here!
insert into table1(fileName) values('file1.txt')
insert into table1(fileName) values('file2.txt')
insert into table1(fileName) values('file3.txt')
insert into table1(fileName) values('/b') // This should not be here!
Please help me I really have to do this...
Thanks for Your help! ;)

To execute commands for a set of files, just specify the file pattern:
for %%a in (f*.txt) do (
echo ...%%a >> sql.txt
echo %%a... >> sql.txt
)

Related

Load multiple csv into ORACLE database using SQLLDR with NAMES of the loaded files

I need to load a banch of .csv files from a certain directory. Problem is I also need filenames as they contain information.
I'm managed to load files using similar command:
FOR %c in (C:\tmp\loader\*.csv) DO (
c:\oracle\db\dbhome_1\BIN\sqlldr <user>#<sid>l/<password> control=C:\tmp\loader\loader.ctl data=%c
)
C:\tmp\loader\loader.ctl is (again it's an example)
OPTIONS (ERRORS=0,SKIP=1)
LOAD DATA
APPEND
INTO TABLE scott.td_region_position
FIELDS TERMINATED BY '$$' TRAILING NULLCOLS
( POSITION_KEY,
POSITION_NAME ,
CHANNEL,
LVL,
IS_PARTNER,
MARKET_CODE
)
Can I add the name of files somehow to the loaded information?
Just generate temporary control file with CONSTANT for file name.
For example, gen_ctl.bat:
#echo off
echo OPTIONS (ERRORS=0,SKIP=1)
echo LOAD DATA
echo APPEND
echo INTO TABLE scott.td_region_position
echo FIELDS TERMINATED BY '$$' TRAILING NULLCOLS
echo ( POSITION_KEY,
echo POSITION_NAME ,
echo CHANNEL,
echo LVL,
echo IS_PARTNER,
echo MARKET_CODE,
echo FILE_NAME constant '%1'
echo )
then run it in your loop with filename in argument. Example:
C:\tmp>gen_ctl.bat my-file.dat >temp.ctl
C:\tmp>type temp.ctl
OPTIONS (ERRORS=0,SKIP=1)
LOAD DATA
APPEND
INTO TABLE scott.td_region_position
FIELDS TERMINATED BY '$$' TRAILING NULLCOLS
( POSITION_KEY,
POSITION_NAME ,
CHANNEL,
LVL,
IS_PARTNER,
MARKET_CODE,
FILE_NAME constant 'my-file.dat'
)
and pass this temp.ctl to sqlldr

generate file from bash script

I have to generate a file.sql file, in which I want to hold some DDL statements.
Firstly it should create a database user, schema and grant some permissions. Then it should make copyes of some tables into newly created schema. Table names I hold in bash array variable. Number of tables in array may vary.
I cannot make one cat > file.sql < EOF ... EOF block to do that, because I need to generate CREATE TABLE and ALTER TABLE commands.. depends on the table count.
I made a generate.sh script with variables and three bash functions:
TABLES=( "table_one" "table_two" "table_three" "table_four" "table_five")
SOURCE_SCHEMA="src"
TARGET_SCHEMA="tgt"
FILE=file.sql
function create_prepare_sql_v1 {
cat > $FILE << EOF_SQL_V1
...here goes create user/schema and grant statements...
EOF_SQL_V1
function create_prepare_sql_v2 {
count=1
for table in ${!TABLES[#]}; do
( echo -e "CREATE TABLE $SOURCE_SCHEMA.${TABLES[$table]} AS TABLE $TARGET_SCHEMA.${TABLES[$table]};" \
"\nALTER TABLE $SOURCE_SCHEMA.${TABLES[$table]} ADD PRIMARY KEY(id);" \
"\nINSERT INTO $SOURCE_SCHEMA.temp VALUES ("$count", '"$TARGET_SCHEMA"', '"${TABLES[$table]}"');" ) >> $FILE
((count++))
done
function create_prepare_sql_v3 {
cat >> $FILE << 'EOF_SQL_V3'
...here I put my custom PL/pgSQL functions...
EOF_SQL_V3
When I execute the functions and I check that file.sql has allprevious data by adding and removing step#_done strings. When all done, I remove step_3_done string.
It works but seems, that this is a very weak solution.
create_prepare_sql_v1 && echo "step1_done" >> $FILE || exit 1
create_prepare_sql_v2 && sed -i 's/step1_done/step2_done/' $FILE || exit 1
create_prepare_sql_v3 && sed -i 's/step2_done/step3_done/' $FILE || exit 1
if ! fgrep -q 'step3_done' $FILE ; then
echo "Something went wrong. Exiting.."
exit 1
fi
sed -i '/step3_done/d' $FILE
echo "All good."
After generation the file.sql should be something like that:
\connect dbname
CREATE USER u_user WITH PASSWORD 'blah';
CREATE SCHEMA IF NOT EXISTS src AUTHORIZATION u_user;
GRANT USAGE ON SCHEMA src TO u_user;
CREATE TABLE src.temp (
id INTEGER PRIMARY KEY,
schema_name VARCHAR(100),
table_name VARCHAR(100),
truncated BOOLEAN DEFAULT false
);
CREATE TABLE src.table_one AS TABLE tgt.table_one;
ALTER TABLE src.table_one ADD PRIMARY KEY(id);
INSERT INTO src.temp VALUES (1, 'tgt', 'table_one');
CREATE TABLE src.table_two AS TABLE tgt.table_two;
ALTER TABLE src.table_two ADD PRIMARY KEY(id);
INSERT INTO src.temp VALUES (2, 'tgt', 'table_two');
CREATE TABLE src.table_three AS TABLE tgt.table_three;
ALTER TABLE src.table_three ADD PRIMARY KEY(id);
INSERT INTO src.temp VALUES (3, 'tgt', 'table_three');
etc
CREATE OR REPLACE FUNCTION ..
CREATE OR REPLACE FUNCTION ..
CREATE OR REPLACE FUNCTION ..
If it was only sql statements with constant number of tables, there would be no problem to do that with one cat > $FILE << EOF <some_code> EOF block...
Can you plese offer a better solution?
Thanks!

Check if a PostgresSQL DB Exists with Batch File and Output Custom Values to a Text File

Basically I am trying to check if a certain PostgreSQL DB exists with a batch file from the CMD in Windows. Then output custom results onto a text file within the same location, the text file will contain custom values. But the batch I created keeps giving me this (below), does not create the file and instead outputs this on the cmd:
SET _chk_DB=server
was unexpected at this time.
And I would like to know where I went wrong.
I am a beginner with batch so please do take that into consideration.
SET _chk_DB=server
FOR /F "usebackq" %%S IN (psql.exe -h %_svr% -d %_db% -U %_usr%
-P %_psw%
-Q "set nocount on; select count(*) from dbo.sysdatabases where
[name]='%_dtb%'") DO ( SET _chk_DB=%%S )
IF [%_chk_DB%]==[server]
"1" >> Info.text
else
echo "0" >> Info.txt
IF [%_chk_DB%]==[login]
"1" >> Info.text
else
echo "0" >> Info.txt
IF [%_chk_DB%]==[0]
"1" >> Info.text
else
echo "0" >> Info.txt

Creating and Writing in a Text File using DOS Command

I want to know how can I create a file named e.g myfile.txt in a D:\MyFiles directory and write first & last name in it
I wrote below code for that.
MD D:\Workdirectory\PRIVATE\DOCUMENT\type myfile.txt First_Name Last_Name
This would also work:
#echo First_Name Last_Name > D:\MyFiles\myfile.txt
If you want to append to the file you can do this:
#echo First_Name Last_Name >> D:\MyFiles\myfile.txt
You could do something like the following:
echo First_Name Last_Name > D:\MyFiles\myfile.txt

Including pipe running Oracle sql from DOS batch script

We use the approach below to run SQL from a DOS batch script.
The model works fine but this specific code doesn't work. I believe because of the || characters. I tried using ^|^| but this didn't work.
Any ideas?
(
echo update mytable set file_path = 'C' || substr(file_path, 2);
echo commit;
echo exit
) | sqlplus x/x#orcl
Store the SQL as file and redirect SQL Plus's input:
sqlplus x/x#orcl <sql.txt
You can use CONCAT instead of the || operator
Escaping the || with ^|^| leaves you with yet another problem: cmd.exe thinks that the closing parenthesis of substr(file_path, 2); belongs to the opening parenthesis in the first line. It is therefore not printed to SQL*Plus, thus rendering the update statement to something like update mytable set file_path = 'C' || substr(file_path, 2 which obviously cannot be interpreted by Oracle.
You can solve this if you put the entire update statement into double quotes and feed this to (yet another) cmd.exe, like so:
(
#echo select * from mytable;
#cmd /c "echo update mytable set file_path = 'C' ^|^| substr (file_path, 2);"
#echo commit;
#echo exit
) | sqlplus x/x#orcl

Resources