How to run a Microsoft SQL Server Agent Job from VBScript - sql-server

I have an ERP system that allows me to attach VBScript to a button on a customized window. I would like to be able to run this script so that it fires off a SQL Server Agent Job on the server (SQL Server 2008). I've been looking in to this for a couple hours now and the closest thing I could see was a short script which seems to use a depreciated command (SQL.DMO). Here's the code I swiped from the web:
On Error Goto 0: Main()
Sub Main()
Set objSQL = CreateObject("SQLDMO.SQLServer")
' Leave as trusted connection
objSQL.LoginSecure = True
' Change to match the name of your SQL server
objSQL.Connect "Server Name"
Set objJob = objSQL.JobServer
For each job in objJob.Jobs
if instr(1,job.Name,"Job Name") > 0 then
msgbox job.Name
job.Start
msgbox "Job Started"
end if
Next
End Sub
The resulting error is:
Line: 3
Char: 3
Error: ActiveX component can't create object: 'SQLDMO.SQLServer'
Code: 800A01AD
Source: Microsoft VBScript runtime error

Use sqlcmd and execute sp_start_job command:
Set oShell = CreateObject ("WScript.Shell")
oShell.run "sqlcmd -S localhost -E -Q ""EXECUTE msdb.dbo.sp_start_job N'My Job Name'""
sqlcmd should exist on the SQL Server.
Note:
This is a potential a security risk. As per documentation, by default, only members of sysadmin role can execute sp_start_job. You will need your VBScript to run under security context of a user that has sysadmin privileges in the SQL Server (which is not good).
Use Task Scheduler and a trigger file
Rather than starting the SQL Agent Job directly, create a Scheduled Task on the SQL Server that would:
be scheduled to run every 10 minutes
execute a cmd script, which would:
check for existence of a trigger file in a specified location
if file is found, would start the SQL Agent Job using sqlcmd, and delete the trigger file thereafter
The VBScript triggered by the ERP system should simply place an empty correctly named trigger file in the specified location.
Use a stored procedure to control what is being started
To further reduce attack vectors, you can create your own wrapper stored procedure in SQL Server that would start the required SQL Agent Job.
Create a server Login:
USE [master]
GO
CREATE LOGIN [erp_trigger_user] WITH PASSWORD=N'pwd', DEFAULT_DATABASE=[msdb], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
Create a database user:
USE [msdb]
GO
CREATE USER [erp_trigger_user] FOR LOGIN [erp_trigger_user] WITH DEFAULT_SCHEMA=[dbo]
GO
Create a stored procedure that will start your required SQL Server Agent Job:
Note: the stored procedure will execute as dbo user, which has permission to execute msdb.dbo.sp_start_job.
CREATE PROCEDURE dbo.sp_StartERPJob
WITH EXECUTE AS 'dbo'
AS
BEGIN
EXECUTE msdb.dbo.sp_start_job N'My Job Name'
END
Grant the user permissions to execute the stored procedure:
GO
GRANT EXECUTE ON [dbo].[sp_StartERPJob] TO [erp_trigger_user]
GO
Update your Scheduled Task to execute a Windows batch file that looks something like this:
if exist trigger_file.txt (
sqlcmd -S localhost -E -Q -U erp_trigger_user -P pwd "EXECUTE msdb.dbo.sp_StartERPJob"
del trigger_file.txt
) else (
rem file doesn't exist
)

Related

Automate Running SQL Queries in SSMS

I have a SQL Server database set up that I manage using SQL Server Management Studio 17.
In that database, I have 27 tables that I maintain by running pretty simple OPENQUERY scripts every morning, something to the effect of:
DROP TABLE IF EXISTS [databasename].[dbo].[table27]
SELECT * INTO [databasename].[dbo].[table27] FROM OPENQUERY(OracleInstance, '
SELECT
table27.*
FROM
table27
INNER JOIN table26 ON table27.criteria = table26.criteria
WHERE
< filter >
< filter >
');
And this works great! But, it is cumbersome to every morning, sign into SSMS, and right click on my database and hit "New Query" and copy in 27 individual SQL scripts and run them. I am looking for a way to automate that. My directory that holds these scripts looks like this:
I don't know if this is achievable in SSMS or in like a batch script. I would imagine for the latter, some pseudocode looking like:
connect to sql server instance
given instance:
for each sql_script in directory:
sql_script.execute
I have tried creating a script in SSMS, by following:
Tasks -> Script Database ->
But there is no option to execute a .sql file on the tables in question.
I have tried looking at the following resources on using T-SQL to schedule nightly jobs, but have not had any luck conceiving of how to do so:
https://learn.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-2017
Scheduled run of stored procedure on SQL server
The expected result would be the ability to automatically run the 27 sql queries in the directory above to update the tables in SQL Server, once a day, preferably at 6:00 AM EST. My primary issue is that I cannot access anything but SQL Server Management Studio; I can't access the configuration manager to use things like SQL Server Agent. So if I am scheduling a task, I need to do so through SSMS.
You actually can't access the SQL Server Agent via Object Explorer?
This is located below "Integration Services Catalog"
See highlighted below:
You describe not being able to access that in the question for some reason. If you can't access that then something is wrong with SQL Server or perhaps you don't have admin rights to do things like schedule jobs (a guess there).
In SSMS you would wnat to use Execute T-SQL Statement Task and write your delete statement in the SQL Statement field in the General Tab.
However, I would look at sqlcmd. Simply make a batch script and schedule it in Task Scheduler (if you're using windows). Or you could use
for %%G in (*.sql) do sqlcmd /S servername /d databaseName -E -i"%%G"
pause
From this post. Run all SQL files in a directory
So basically you have to create a Powershell script that calls and execute the sql scripts.
After that you can add your Powrshell script to the Task Scheduler.
I suggest you add these scripts as jobs for the SQL Server Agent.

Executing set of SQL queries using batch file?

I am using a SQL Server database. I have these SQL queries:
Delete from TableA;
Delete from TableB;
Delete from TableC;
Delete from TableD;
Delete from TableE;
Is it possible to run these scripts using a batch file? The database is a remote database.
Thanks!
Save the commands in a .SQL file, ex: ClearTables.sql, say in your C:\temp folder.
Contents of C:\Temp\ClearTables.sql
Delete from TableA;
Delete from TableB;
Delete from TableC;
Delete from TableD;
Delete from TableE;
Then use sqlcmd to execute it as follows. Since you said the database is remote, use the following syntax (after updating for your server and database instance name).
sqlcmd -S <ComputerName>\<InstanceName> -i C:\Temp\ClearTables.sql
For example, if your remote computer name is SQLSVRBOSTON1 and Database instance name is MyDB1, then the command would be.
sqlcmd -E -S SQLSVRBOSTON1\MyDB1 -i C:\Temp\ClearTables.sql
Also note that -E specifies default authentication. If you have a user name and password to connect, use -U and -P switches.
You will execute all this by opening a CMD command window.
Using a Batch File.
If you want to save it in a batch file and double-click to run it, do it as follows.
Create, and save the ClearTables.bat like so.
echo off
sqlcmd -E -S SQLSVRBOSTON1\MyDB1 -i C:\Temp\ClearTables.sql
set /p delExit=Press the ENTER key to exit...:
Then double-click it to run it. It will execute the commands and wait until you press a key to exit, so you can see the command output.
Check out SQLCMD command line tool that comes with SQL Server. http://technet.microsoft.com/en-us/library/ms162773.aspx
Use the SQLCMD utility.
http://technet.microsoft.com/en-us/library/ms162773.aspx
There is a connect statement that allows you to swing from database server A to server B in the same batch.
:Connect server_name[\instance_name] [-l timeout] [-U user_name [-P password]]
Connects to an instance of SQL Server. Also closes the current connection.
On the other hand, if you are familiar with PowerShell, you can programmatic do the same.
http://technet.microsoft.com/en-us/library/cc281954(v=sql.105).aspx
Different ways:
Using SQL Server Agent (If local instance)
schedule a job in sql server agent with a new step having type as "T-SQL" then run the job.
Using SQLCMD
To use SQLCMD refer http://technet.microsoft.com/en-us/library/ms162773.aspx
Using SQLPS
To use SQLPS refer http://technet.microsoft.com/en-us/library/cc280450.aspx

How to execute same SP in 2 different connection

How to execute same SP in 2 different connection.
Ex: ALTER PROCEDURE test
...
....
I want to execute this SP in db called "database1" in 192.168.1.100 and same in 192.168.1.102.
I want this to be done using script not using the change connection window
You can use SQLCMD to run a .sql file against multiple server connections.
sqlcmd -S <ComputerName>\<InstanceName> -i <MyScript.sql> -d <database_name> -T
You can do that in SSMS Tools Pack using one of its features called "Run one script on multiple databases".
Editing this to add that this is a tiny and free add-in to SQL Server, that you would find extremely useful.

How to attach a SQL Server database from the command line

Is it possible to enter a command line command (like in a batch file) to attach a detached database to SQL Server, in stead of opening the management studio and doing it in there?
you need to use: sqlcmd Utility
The sqlcmd utility lets you enter
Transact-SQL statements, system
procedures, and script files at the
command prompt, in Query Editor in
SQLCMD mode, in a Windows script file
or in an operating system (Cmd.exe)
job step of a SQL Server Agent job.
This utility uses OLE DB to execute
Transact-SQL batches.
Then use CREATE DATABASE (Transact-SQL) to do the attach and sp_detach_db (Transact-SQL) to do the detach. The sp_attach_db (Transact-SQL) is going to be removed in a future version of Microsoft SQL Server.
If you need to specify the log file name: USE master; GO; CREATE DATABASE DBNAME ON ( FILENAME = 'C:\DBFILE.mdf') LOG ON ( FILENAME = 'C:\DBLOGFILE_log.ldf') FOR ATTACH; GO; And to detach: USE master; GO; EXEC sp_detach_db 'DBNAME', 'true'; GO;
Small gotcha, it won't tell you what is wrong when using sqlcmd and your mdf/ldf files are marked read-only. Make sure they are read-write.

Restore database backup over the network

How do you restore a database backup using SQL Server 2005 over the network? I recall doing this before but there was something odd about the way you had to do it.
You have few options to use a network file as a backup source
Map network drive/path, hosting file, under SAME user as MS-SQL Server.
Use xp_cmdshell extended stored procedure to map network drive from inside of MS SQL (such way, command shell will have the same privilegies as the user account running SSMS)
-- allow changes to advanced options
EXEC sp_configure 'show advanced options', 1
GO
-- Update currently configured values for advanced options.
RECONFIGURE
GO
-- To enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1
GO
-- Update currently configured values for advanced options.
RECONFIGURE
GO
EXEC xp_cmdshell 'NET USE Z: \\Srv\Path password1 /USER:Domain\UserName'
Afterwards drive Z: will be visible in Server Managment studio, or just
RESTORE DATABASE DataBaseNameHere FROM DISK = 'Z:\BackNameHere.BAK'
GO
The database is often running as a service under an account with no network access. If this is the case, then you wouldn't be able to restore directly over the network. Either the backup needs to be copied to the local machine or the database service needs to run as a user with the proper network access.
You cannot do this through the SSMS GUI, but you can do it using a script. RESTORE DATABASE from DISK='\unc\path\filename' If you need this process automated, the best way is to setup a SQL Server Job and run it as a user with access to the file location.
You can use the SP xp_cmdshell to map the networkdrive for sql server, after that it will show up in the file browsing window.
EXEC xp_cmdshell 'NET USE Z: SERVERLOCATION PASSWORD /USER:DOMAIN\USERNAME'
more info here: DB Restore from Network Drive
Worked for me!
Make sure that the user running your SQL services in "Services.msc" is an active directory "Domain User" this will fix the issue.
I've had to do this a few times, and there are only two options that I know of. Copy the file locally to the SQL Server, or on the SQL server create a mapped network drive to the share that contains the backup file.
Also, you need to make sure that the SQL Server Service is running as a user that has network access - and permissions to the share where the backup file lives. 'Local System' won't have permissions to access the network.
As a side note, if you happen to be running SQL on a Virtual Machine it's often less hassle to just temporarily set up a new drive on the VM with enough space to copy your backup files to, do the restore from that new local copy, and then delete the temp drive.
This can be useful if stopping/starting the SQL service to change it's account is an issue.
Create a shared drive on machine that has the backups, say server1 has the backups in folder "Backups". Grant full control to the account running the SQL Server. On the Server that you want to restore to launch SSMS go restore database and select "From Device". In the "Locate Backup file-"Server"" dialog box and remove anything in the "Selected Path" field and in the "File Name" field supply full path so "\server\backups\db.bak". At least it worked for me when migrating from 05 to 08. Not the preferred method because any network hiccup can cause an issue with the restore.
EXEC sp_configure 'show advanced options', 1
GO
-- Update currently configured values for advanced options.
RECONFIGURE
GO
-- To enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1
GO
-- Update currently configured values for advanced options.
RECONFIGURE
GO
--This should be run on command prompt (cmd)
NET USE Z: \\172.100.1.100\Shared Password /USER:administrator /Persistent:no
then on SQL Server
EXEC xp_cmdshell 'NET USE Z: \\172.100.1.100\Shared Password /USER:administrator /Persistent:no'
--Afterwards drive Z: will be visible in Server Management studio, or just
RESTORE DATABASE DB FROM DISK = 'Z:\DB.BAK'
WITH REPLACE

Resources