Prevent SQL File From Running As a Script - sql

I have tens of SQL files that contain individual queries and update commands. These commands are intended to be used as a starting point for manual updates to the database, they are not structured to be ran as scripts.
Is there an SQL command I can place at the start of these files to stop an inadvertent click of the 'Run Script' button? Return, halt, stop?
I'm opening these in Oracle's SQL Developer, and the 'Run Command' and 'Run Script' buttons are right next to each other...

You can use the exit command at the top of your script.
If someone accidentally runs it as a script, it will immediately disconnect and will not run the rest of the statements.
Example:
exit
update t set a = 'abc';
drop table t;
...

Related

How to close the window after a sql file has finished running

I have a script that I turned into an exe that connects to an oracle database, then runs a sql script. after the script is done, the window stays open. I have tried a few commands and the sql> stays there. Thanks!
ALTER USER &user_name ACCOUNT UNLOCK;
Edit your C:\Scripts\Script2.sql file and add an exit statement at the end on a line by itself.
You may need to ensure that the prior command is correctly terminated with a ; or a / character on a line by itself.
ALTER USER &user_name ACCOUNT UNLOCK;
exit

Change the database connection programmatically

In Oracle SQL Developer, I need to switch the active database connection manually. Is there a command that will connect to a different database programmatically, assuming that the login credentials are already saved? I'm trying to avoid clicking on the drop-down menu at the top right of the window which selects the active connection.
Perhaps I should rather have a single SQL file per database? I could understand that argument. But this to prepare to migrate some tables from one database to another and so it's nice to have all of the context in one file.
On database1, run a query on table1 which is located in schema1.
-- manually switch to database1 (looking for a command to replace this step)
ALTER SESSION SET CURRENT_SCHEMA = schema1
SELECT * FROM table1;
On database2, run a query on table2 which is located in schema2.
-- manually switch to database2
ALTER SESSION SET CURRENT_SCHEMA = schema2
SELECT * FROM table2;
Looks like this is well documented here
Use this command
CONN[ECT] [{<logon>| / |proxy} [AS {SYSOPER | SYSDBA | SYSASM}] [edition=value]]
You need a DDL TRIGGER to perform an event after your presql
CREATE TRIGGER sample
ON TABLE
AFTER
Event
........
THEN
ALTER SESSION SET
CURRENT_SCHEMA = schema2
SELECT * FROM table2;
I don't know of a way in which to change your selected connection in SQL Developer, but there is a programmatic method for temporarily changing the connection under which the script commands are run, as #T.S. pointed out. I want to give a few examples, which might be helpful to people (as they would have been for me).
So let's say your script has part A and part B and you want to execute them one after the other but from different connections. Then you can use this:
CONNECT username1/password1#connect_identifier1;
-- Put commands A here to be executed under this connection.
DISCONNECT; -- username1
CONNECT username2/password2#connect_identifier2;
-- Put commands B here to be executed under this connection.
DISCONNECT; -- username2
The connect_identifier part identifies the database where you want to connect. For instance, if you want to connect to a pluggable database on the local machine, you may use something like this:
CONNECT username/password#localhost/pluggable_database_name;
or if you want to connect to a remote database:
CONNECT username/password#IP:port/database_name;
You can omit the password, but then you will have to input it in a prompt each time you run that section. If you want to consult the CONNECT command in more detail, this reference document may be useful.
In order to execute the commands, you would then select the code that you are interested in (including the relevant CONNECT commands) and use Run Script (F5) or just use Run Script (F5) without selecting anything which will execute the entire script file. SQL Developer will execute your commands, put the output into the Script Output tab and then stop the connection. Note that the output of SELECT commands might be unpleasant to read inside Script Output. This can be mitigated by running the following command first (just once):
SET sqlformat ansiconsole;
There is also Run Statement (Ctrl+Enter), but do note that Run Statement (Ctrl+Enter) does not seem to work well with this workflow. It will execute and display each SELECT statement into a separate Query Result tab, which is easier to read, BUT the SELECT query will always be executed from the context of the active connection in SQL Developer (the one in the top right), not the current code connection of the CONNECT statement. On the other hand, INSERT commands, for instance, DO seem to be executed in the context of the current code connection of the CONNECT statement. This (rather inconsistent) behaviour is probably not what you want, so I recommend using Run Script (F5) as described above.

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

How to Start a SQL insert query from failed step?

I am running a Select query and getting lots of rows from it(sometimes more than 500) then inserting thoes values one by one into another table. Now i want to know which insert step failed so that i can start inserting from that failed step again so that table does not update with duplicate value.
Syntax may vary from system to system, however structure and process remains.
When one does database deployments to live system he prepares two SQL scripts.
1.Change script that has structure like this:
PRINT 'Doing X'
SCRIPT X
....
GO
PRINT 'DOING Y'
SCRIPT Y
....
GO
2.Rollback script that reverts all the changes that section of script does.
Revert scripts are executed in reverse order.
REVERT SCRIPT Y
REVERT SCRIPT X
When change script fails you will know which section failed by the last message printed out, then you will take all sections of rollback script that run after the failed section and revert changes.

How to run a stored procedure every day in SQL Server Express Edition?

How is it possible to run a stored procedure at a particular time every day in SQL Server Express Edition?
Notes:
This is needed to truncate an audit table
An alternative would be to modify the insert query but this is probably less efficient
SQL Server Express Edition does not have the SQL Server Agent
Related Questions:
How can I schedule a daily backup with SQl Server Express?
Scheduled run of stored procedure on SQL Server
Since SQL Server express does not come with SQL Agent, you can use the Windows scheduler to run a SQLCMD with a stored proc or a SQL script.
http://msdn.microsoft.com/en-us/library/ms162773.aspx
I found the following mechanism worked for me.
USE Master
GO
IF EXISTS( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[MyBackgroundTask]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[MyBackgroundTask]
GO
CREATE PROCEDURE MyBackgroundTask
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- The interval between cleanup attempts
declare #timeToRun nvarchar(50)
set #timeToRun = '03:33:33'
while 1 = 1
begin
waitfor time #timeToRun
begin
execute [MyDatabaseName].[dbo].[MyDatabaseStoredProcedure];
end
end
END
GO
-- Run the procedure when the master database starts.
sp_procoption #ProcName = 'MyBackgroundTask',
#OptionName = 'startup',
#OptionValue = 'on'
GO
Some notes:
It is worth writing an audit entry somewhere so that you can see that the query actually ran.
The server needs rebooting once to ensure that the script runs the first time.
Create a scheduled task that calls "C:\YourDirNameHere\TaskScript.vbs" on startup. VBScript should perform repeated task execution (in this example, it's a 15 minute loop)
Via command line (must run cmd.exe as administrator):
schtasks.exe /create /tn "TaskNameHere" /tr "\"C:\YourDirNameHere\TaskScript.vbs\" " /sc ONSTARTUP
Example TaskScript.vbs: This executes your custom SQL script silently using RunSQLScript.bat
Do While 1
WScript.Sleep(60000*15)
Set WshShell = CreateObject("WScript.Shell")
WshShell.RUN "cmd /c C:\YourDirNameHere\RunSQLScript.bat C:\YourDirNameHere\Some_TSQL_Script.sql", 0
Loop
RunSQLScript.bat: This uses sqlcmd to call the database instance and execute the SQL script
#echo off
sqlcmd -S .\SQLEXPRESS -i %1
If you are using Express Edition, you will need to use the Windows Scheduler or the application connecting to the server in some way.
You would use the scheduler to run sqlcmd. Here are some instructions for getting the sqlcmd working with express edition.
SQL Scheduler from http://www.lazycoding.com/products.aspx
Free and simple
Supports all versions of SQL Server 2000, 2005, and 2008
Supports unlimited SQL Server instances with an unlimited number of jobs.
Allows to easily schedule SQL Server maintenance tasks: backups, index rebuilds, integrity checks, etc.
Runs as Windows Service
Email notifications on job success and failure
Since another similar question was asked, and will likely be closed as a duplicate of this one, and there are many options not mentioned in the answers already present here...
Since you are using SQL Express you can't use SQL Server Agent. However there are many alternatives, all of which you can schedule using AT or Windows Task Scheduler depending on your operating system:
VBScript
C# command line app
batch file with SQLCMD
PowerShell
All of these languages/tools (and many others) have the capacity to connect to SQL Server and execute a stored procedure. You can also try these Agent replacements:
SQLScheduler
Express Agent
Standalone SQL Agent (beta)
The easiest way I have found to tackle this issue is to create a query that executes the stored procedure then save it. The query should look similar to this one below.
use [database name]
exec storedproc.sql
Then create a batch file with something similar to the code below in it.
sqlcmd -S servername\SQLExpress -i c:\expressmaint.sql
Then have the task scheduler execute the batch as often as you like
Another approach to scheduling in SQL Express is to use Service Broker Conversation Timers. To run a stored procedure periodically, which you can use to bootstrap a custom scheduler.
See eg Scheduling Jobs in SQL Server Express
You could use Task Scheduler to fire a simple console app that would execute the Sql statement.
As you have correctly noted, without the agent process, you will need something else external to the server, perhaps a service you write and install or Windows scheduler.
Note that with an Express installation for a local application, it is possible that the machine may not be on at the time you want to truncate the table (say you set it to truncate every night at midnight, but the user never has his machine on).
So your scheduled task is never run and your audit log gets out of control (this is a problem with SQL Server Agent as well, but one would assume that a real server would be running non-stop). A better strategy if this situation fits yours might be to have the application do it on demand when it detects that it has been more than X days since truncation or whatever your operation is.
Another thing to look at is if you are talking about a Web Application, there might be time when the application is loaded, and the operation could be done when that event fires.
As mentioned in the comment, there is sp_procoption - this could allow your SP to run each time the engine is started - the drawbacks with this method are that for long-running instances, there might be a long time between calls, and it still has issues if the engine is not running at the times you need the operation to be done.
Our company also use SQLEXPRESS and there is no SQL Agent.
Since there is no marked answer as "right" and all the solutions are quite complex I'll share what I did there. May be its really bad, but it worked great to me.
I've chosen operations of Insertion (people do) to a table that got closely the same time range i needed and made a trigger "ON INSERT" that applies needed function.