Ignoring SQLPLUS commands in JDBC - sql

I have a .sql file that contains below statements:
SET LINESIZE 2000
WHENEVER SQLERROR EXIT 1 ROLLBACK
WHENEVER OSERROR EXIT 1 ROLLBACK
SET PAGESIZE 0
SET HEADING ON
SET FEEDBACK OFF
SET VERIFY OFF
INSERT INTO TABLE_A
--get some value from TABLE B that will be added in Table A....
COMMIT;
EXIT;
When I run this SQL in my SQL Editor (TOAD/SQL Navigator etc.) , it works fine. I see some messages though when SQLNavigator execute this command:
SQL*Plus command ignored.
Processing ...
WHENEVER SQLERROR EXIT 1 ROLLBACK
SQL*Plus command ignored.
Processing ...
WHENEVER OSERROR EXIT 1 ROLLBACK
SQL*Plus command ignored.
Processing ...
SET PAGESIZE 0
When I run this SQL through JDBC, i get an exception:
Caused by: java.sql.SQLException: ORA-00922: missing or invalid option
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3368)
I'm assuming this error is because JDBC is not able to understand SQLPlus statements and failing. Is there a way I can tell JDBC to ignore those statements and just run the main SQL? Or to resolve this I just need to modify the SQL file by removing the SQLPlus statements?

You'll need to remove the SQL*Plus commands from the file.
JDBC is intended to be a database-agnostic interface so it is designed to work the same with a variety of different database engines. SQL*Plus commands are designed to work just with SQL*Plus connecting to an Oracle database (though other tools that support Oracle databases will often support a subset of SQL*Plus commands as well). It wouldn't make sense for JDBC to know about what constitutes a SQL*Plus command so it has no way to figure out what is a SQL*Plus command or to filter them out.
Beyond that, simply removing the SQL*Plus commands will change the semantics of the script. The WHENEVER SQLERROR and WHENEVER OSEROR commands instruct SQL*Plus to issue a rollback in the event of an error (which it sounds like your script generates). You'd need to code that logic into your JDBC application if you want to match the behavior.

When you run these statements through TOAD, etc. they usually parse the text either by a delimiter (e.g. semi-column) or by line feed and run the statements separately. However, when you send the whole text to JDBC, it's probably trying to run it all at once, hence the error. You may have to parse the statements and separate them properly before sending to JDBC.

Related

ORA-00922: Missing or Invalid option for SET FEEDBACK OFF in TOAD

I am using TOAD application to execute my query which you can see below:
SET FEEDBACK OFF;
SELECT * FROM TABLENAME
-- and then rest of the queries
I used SET FEEDBACK OFF in Toad app (by Quest Software) as an alternative to SET NOCOUNT ON in SQL, but it shows error and says:
ORA-00922: Missing or Invalid option
Is there any alternative to SET NOCOUNT ON that we write in SQL for Oracle?
SET set of commands - in Oracle - was originally related to its command-line tool named SQL*Plus. It (the SET) works in some other tools, such as Oracle's GUI - SQL Developer.
Mathguy showed me that TOAD recognizes quite a lot SQL*Plus commands (I thought it does not); it is the way you run code in TOAD:
if you run it as a separate command, it won't work:
on the other hand, if you run it as a script, then it works, and the result is displayed in its "Script output" tab:

Disable auto-commit for execution procedures on PL/SQL Developer

I'm currently using PL/SQL Developer to run some queries at my job, and my colleague uses TOAD to run the EXECs for procedures, since TOAD does not autocommit them. So, whenever I need to run a procedure, I must send him the codes and wait for him response.
Is there a way to stop PL/SQL Developer from autocommiting them?
I've already looked in the preferences and couldn't find any option to stop this from happening. The option "autocommit after Execute" is disabled, as well as all other autocommit functions I could find.
I'm running the procedures using
Begin
PROCEDURE
End
since neither EXEC or EXECUTE seem to work
Here's the code I'm supposed to run (and works perfectly with TOAD)
exec PWSYS.MAINT.MOVE_INCIDENT('here goes some data','here goes more data');
It doesn't run with EXEC on PL/SQL Developer (it displays error ORA-00900: invalid SQL statement), so I tried this
Begin
PWSYS.MAINT.MOVE_INCIDENT('data here','data here as well');
End
It runs perfectly, but it also autocommits, and THAT'S my problem.
So, in summary, I need a way to stop it from autocommiting, or a way to rollback the data I've inserted/changed.
Thanks in advance

Is there a SQL equivalent of return?

Consider the following bit of SQL
SET DATEFORMAT ymd
SET ARITHABORT, ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, NOCOUNT ON
SET NUMERIC_ROUNDABORT, IMPLICIT_TRANSACTIONS, XACT_ABORT OFF
GO
USE master
GO
IF DB_NAME() <> N'master' SET NOEXEC ON
--
-- Create database [myDatabaseName]
--
PRINT (N'Create database [myDatabaseName]')
GO
CREATE DATABASE myDatabaseName
There is then a very long script setting up tables, views, stored procedures etc etc.
I would like to know if SQL would allow something along the likes of the following pseudo code;
If (myDatabaseName Exists)
Return // in other word abort the script here but don't throw an error
Else
//Carry on and install the database
I am aware of the Exists function in SQL but I can't seem to find anything that would simply abort the remains of the script straightaway.
This script will end up in an installation routine. In theory it should never be in an installer where the database is already present, however I would prefer not to take chances and prepare properly for a potential mistake. It is also crucial that the script does not throw any error as that will just cause the installer to roll back and install nothing.
I'm hoping that something exists in SQL that will just exit a script cleanly if particular conditions are met. By exit I really do mean exit as opposed to simply breaking out of the condition being currently evaluated.
The problem is, your client tool (SSMS, SQLCMd, etc) splits your script into batches based on the location of the GO keyword (it's a client tool thing, not SQL Server at all).
It then sends the first batch. After the first batch is complete (no matter what the outcome), it sends the second batch, then the third after the second, etc.
If you're running with sufficient permissions, a high-valued RAISERROR (severity 20-25) should stop the client tool in its tracks (because it forces the connection closed). It's not that clean though.
Another option is to try to set NOEXEC ON which still does some work with each subsequent batch (compilation) but won't run any of the code1. This allows you a slightly better recovery option if you want some batches at the end to always run, by turning it OFF again.
1Which means you still will see error messages for compilation errors for later batches which rely upon database structures that would have been created in earlier batches, if they weren't being skipped.
You can use GOTO as follows :
If (myDatabaseName Exists)
GOTO QUIT; // in other word abort the script here but don't throw an error
Else
//Carry on and install the database
QUIT:
SELECT 0;
There are several methods for that kind of request :
raiserror('Oh no a fatal error', 20, -1) with log
OR
print 'Fatal error, script will not continue!'
set noexec on
They should work and close the connection.
See here : Answer

Teradata JDBC Warning 3932 Issue

I can't get my Teradata sql transaction to work through a logstash file.
I am running a somewhat complex transaction with multiple statements (some of them DDL) relying upon previous statements in Teradata. I’m using the jdbc input plugin in logstash. The statement creates multiple volatile tables to provide columns of information upon which I call upon in later statements to complete the transaction. This transaction works perfectly fine when run in Teradata Studio, but has yet to work when I've tried to run it through a jdbc.conf file.
When I run the transaction through my config file from the command line I receive error message 3932 which essentially tells me that I need to enter in COMMIT statements after my volatile tables. I have looked into the error and have, to no productive success tried:
entering in COMMIT statements after each volatile table
placed BT and Et at the beginning and end of the transaction
changed modes within Teradata jdbc_connection_string parameters vector in hopes of having auto commit enabled (not sure if it is disabled or not).
I know the only issue is my transaction through the jdbc, as I (as mentioned before) have gotten the transaction to work in Teradata, and have successfully run my jdbc.conf file with a simpler query.
Any help would be much appreciated.

What is the difference between ";" and "GO" in T-SQL?

I use ADO.NET as well as the sqlcmd utility to send SQL scripts to SQL Server 2008. What is the difference between using ; and GO to separate chunks of SQL?
GO is not actually a T-SQL command. The GO command was introduced by Microsoft tools as a way to separate batch statements such as the end of a stored procedure. GO is supported by the Microsoft SQL stack tools but is not formally part of other tools.
You cannot put a GO into a string of SQL and send it as part of a ADO.NET command object as SQL itself does not understand the term. Another way to demonstrate this is with the profiler: set up some statements that use GO in Query Analyzer/Management Studio and then run the profiler when you execute. You will see they are issued as separate commands to the server.
The semi-colon is used to signify the end of a statement itself, not necessarily a whole batch.
http://msdn.microsoft.com/en-us/library/ms188037.aspx
"GO" is similar to ; in many cases, but does in fact signify the end of a batch.
Each batch is committed when the "GO" statement is called, so if you have:
SELECT * FROM table-that-does-not-exist;
SELECT * FROM good-table;
in your batch, then the good-table select will never get called because the first select will cause an error.
If you instead had:
SELECT * FROM table-that-does-not-exist
GO
SELECT * FROM good-table
GO
The first select statement still causes an error, but since the second statement is in its own batch, it will still execute.
GO has nothing to do with committing a transaction.
semicolon is a statement separator. The previous statement(s) is not necessarily executed when a semicolon is encountered.
GO
Signifies the end of a batch. Executes the previous batch of statements, as does encountering the end of the block.
GO 2
Means execute the batch that many times. I think I've used that option maybe twice in my life. Then again, I'm not a DBA by trade.
Under SQL Server TSQL (2005 - 2016) bear in mind that:
Semicolon (;) is a block terminator.
GO is a batch terminator.
Additionally, GO can be used to invoke the same DML block multiple times using the following syntax:
GO [count]
Where [count] is a positive integer that indicates how many times the TSQL block of commands preceding said GO are to be carried out over and over.
Also, unlike semicolon, GO is mandatory before a new DDL, say, when you create a new view, since a semicolon separating previous commands will trigger an error. For example:
drop view #temporary_viewGO
create view #another_view...
--> NO ERRORS
If you replaced GO with a semicolon in the previous example, it will raise the following error message:
'CREATE VIEW' must be the first statement in a query batch.
'GO' is typically used to indicate the end of a batch of SQL statements which means that you could have a begin transaction and end transaction wrapped up into a single collection of statements that could fail or succeed together.
';' is generally used to separate multiple SQL statements from one another. This is noticable in SQL scripts that need to return multiple recordsets, such as `select * from table1; select * from table2;' which would result in two separate recordsets on the client's side.
The command GO means the end of a batch.
Therefore all variables declared before GO are invalid after the GO command.
Against the semicolon does not end the batch.
If You will use a DML command in a procedure, use the semicolon instead GO.
For example:
CREATE PROCEDURE SpMyProc
#myProcParam VARCHAR(20)
AS
DECLARE #myOtherParam INT = 5
;DISABLE TRIGGER ALL ON tMyTable
UPDATE tMyTable SET myVar = #myProcParam, mySecondVar = #myOtherParam
;ENABLE TRIGGER OLL ON tMyTable
I thought the ; character separates a list of SQL commands, GO just instructs SQL Server to commit all the previous commands.