I am attempting to run MS SQL scripts from files in Ruby/DBI that may contain batch separators (the GO keyword.) The entire script is wrapped in a transaction so that any errors in the script will result in a rollback.
scriptContents = File.read(#path)
SqlDb.conn['AutoCommit'] = false
begin
SqlDb.conn.do scriptContents
SqlDb.conn.commit
rescue Exception
SqlDb.conn.rollback
##log.error "Executing #{#path} resulted in error. Transaction has been rolled back: #{$!}"
end
SqlDb.conn['AutoCommit'] = true
Executing a simple script that contains a GO, such as:
PRINT 'this script is pointless'
GO
SELECT 1
Results in the following error:
ERROR SqlUpgradeScript : Executing test/noop.sql resulted in error. Transaction has been rolled back: 37000 (102) [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'GO'.
Removing the GO causes the script to run successfully.
What is the cleanest way to run a SQL script that may contain multiple batches with Ruby/DBI, while still running the entire script as a single transaction?
GO is not a T-SQL statement. It is a console command used only by SQL Server Management Studio (or the command-line equivalents isq;/osql) to separate batches in scripts files.
Any command text you send to SQL Server is treated as a single batch. Remember, when calling .do you are sending a command to the server, not a script file to the console.
In some cases you may have to separate multiple statements with semicolons (;), eg when using CTEs ( WITH () .... SELECT...) otherwise there is no need to use any separators.
Simply remove GO and send the commands you want to the server. If you do want to execute script files, you will have to break them in batches in code, then send each batch as a single command.
Related
I am a beginner in SQL and was running a PL/SQL file in SQL plus command line however it is showing the message' "SP2-0103: Nothing in SQL buffer to run", and the output from the previous executed PL/SQL file is getting displayed followed by the correct output of the current file. Any suggestions on how to correct this?
I have a stored procedure in an Oracle database and I want to create a batch file that can call and run the said procedure. After running the stored procedure I want to call a certain sql file then run it also within just a single batch file.
name of stored procedure = health_check
name of SQL file = spool1.sql
I want to run the stored procedure first in the batch file. Upon success I want to call the said sql file then run it still at the same batch file.
I'm already able to execute the sql file. I just want to add the calling and running of the stored procedure in my current batch file
I want to achieve something like this:
#echo off
--run proc here
sqlplus user/password#DB #D:\mysqlfile.sql
Is this possible? Thanks in advance.
You could use a 'heredec' approach:
#echo off
#(
echo execute health_check
echo #D:\mysqlfile.sql
) | sqlplus -s -l user/password#DB
Untested but this pattern should work. Everythign in the parentheses is evaluated, which produces two lines of output:
execute health_check
#D:\mysqlfile.sql
and those are treated as input by SQL*Plus. So it's the equivalent of an interactive session where you start SQL*Plus and then enter those two lines in turn at the SQL> prompt. The #<file> can be used from that prompt too to run the file contents. And execute (or just exec) is a client shortcut for an anonymous PL/SQL block.
This assumes, based on how you did this in your question, that the .sql file ends with an exit. If it doesn't then you can add then to the heredoc with echo exit.
I am going through SQL*Plus script and came across set of lines that has below lines:
#test_data/EMPLOYEE.dat
#test_data/ADDRESS.dat
The .dat has some SQL code inside them. I tried to search in internet what the # symbole indicates but I did not get any results. I am new to SQL*Plus, please let me know what this symbol indicates.
This is about sql*plus scripting, we use this symbol to call scripts from external files.
# is used to call scripts from the external files
From the Oracle docs:
Runs the SQL*Plus statements in the specified script. The script can
be called from the local file system or from a web server. The #
command functions similarly to ## and START.
It is used to run the scripts from another file. eg:
SQL> #PreImport.sql
A shell script with a database connection using sqlplus contains this line:
sqlplus username/password#DBNAME<<EOF>tmp.
(here there is a select sql query)
I know <<EOF indicates the start of the command. I have the below doubts in the >tmp part.
1)Does it indicate storing into a file?
2) If yes will it put the results of the SQL query alone into the tmp file or the query and the results both.
Could you please clear me on this one?
<<EOF is known as "heredocs". It means that from the next line in the script, up to a line that says "EOF", will be read in by the shell, and offered to the command on standard input.
In your case, the sqlplus command is being fed the SQL query as if it came from standard input. Then, the output of sqlplus is being saved to the file called tmp.
The input and output are separate. However, sqlplus as a command has a habit of repeating its input to the output, unless instructed otherwise with SET ECHO OFF.
I have the following batch script:
sqlplus ms/ms#orcl < drop.sql
sqlplus ms/ms#orcl < create.1.0.sql
This works fine when I double click on the bat file in Windows Explorer and run it.
But when I type the command name from the DOS prompt I get an error:
C:\>create.bat
C:\>sqlplus ms/ms#orcl 0<drop.sql
The handle is invalid.
C:\>sqlplus ms/ms#orcl 0<create.1.0.sql
The handle is invalid
Any ideas?
Update: Made the change to use # instead of <. This gets around the error but now the script only executes the first file and then leaves you at the SQL> prompt. To get the second file to execute you have to type exit at the prompt, then the second file runs. Not sure how to get both files to execute. ??
If you want SQL*PLUS to execute a script, a better way than command-line redirection is the # syntax:
sqlplus ms/ms#orcl #drop.sql
sqlplus ms/ms#orcl #create.1.0.sql
Also read up on the ## syntax, which you can use to execute a .sql script from another .sql script in the same directory.
SQL> help #
SQL> help ##
Made the change to use # instead of <.
This gets around the error but now the
script only executes the first file
and then leaves you at the SQL>
prompt. To get the second file to
execute you have to type exit at the
prompt, then the second file runs. Not
sure how to get both files to execute.
??
I ended up writing a python script to run sql plus and then exit it to get around this issue. I have yet to find any way around that limitation. Although you would only have to deal with the issue once if you use ## as was suggested. You would just have to run the second script from the first script.