I want to execute a .exe with sql server. For security reasons I can't use the xp_cmdshell. So I decided to create job with a CmdExec Step.
The .exe file must receive 2 parameters. The problem is I never know the parameter.
Ex : I want to give 2 date, today and today + 1 day.
It is easy to do in T-sql, so it is possible to use t-sql INSIDE a CmdExec step ?
Frist,Create a Job with CmdExec step, command like this.
EXEC test.exe #Parm1, #Parm2
After that, in your code to execute .exe
-- Update Job Step with real parameter
UPDATE msdb.dbo.sysjobsteps
SET command = REPLACE(REPLACE(command,'#Parm1','NewParm1') ,'#Parm2','NewParm2')
WHERE job_id = #YouJobIDHere
AND step_id = #StepId
-- start job
EXEC = msdb.dbo.sp_start_job #job_name = #CustomJobName
Related
Can I make an IF statement that only executes when run manually from SSMS?
I have a SQL Server job that executes TSQL code. That TSQL code is maintained in a separate .sql text file. When it needs to be edited, I edit the text file and copy&paste the final results into the job.
This normally works very well but there is one critical line that is only used for testing (it sets a variable to a specific value). How can I guarantee that line only executes when run manually?
Is there something like If ManualExecution() then Blah?
IF APP_NAME() LIKE 'Microsoft SQL Server Management Studio%'
BEGIN
PRINT 'Running inside SSMS'
END;
If you use SQL Agent to run the job, it's app name should be SQLAgent - TSQL JobStep (Job 0x... : Step ...). If you use some other software, just make sure that it doesn't set its Application Name to "Microsoft SQL Server Management Studio"...
You can use the following code to get the SQL Server Agent JobId of the current process (otherwise NULL):
declare #JobId as UniqueIdentifier;
begin try
-- The executed statement will result in a syntax error if not in a SQL Server Agent job.
execute sp_executesql
#stmt = N'select #JobId = Cast( $(ESCAPE_NONE(JOBID)) as UniqueIdentifier );',
#params = N'#JobId UniqueIdentifier output',
#JobId = #JobId output;
end try
begin catch
if ##Error != 102 -- 102 = Syntax error.
select ##Error; -- Handle unexpected errors here.
end catch
select #JobId as JobId; -- NULL if not running as a SQL Server Agent job.
Note that the JobId can be used to access additional information about the current job in dbo.sysjobs.
I want to schedule a stored procedure once every night. I've followed steps online the outlines the this process:
SQL Sever Agent > Right click jobs & select New Job > Step > New > Select the stored procedure under type
But there is no option for stored procedure under the Type selection.
Just leave the Type drop down set to Transact-SQL script (T-SQL), and set the Command to EXEC [dbo].[YourStoredProcedureName], then click OK. Then go under Shedules and setup the time when you want it to run.
You should type this query in your job
EXEC [schema].[StoredProcedureName]
I have an SSIS job that I would like to run from a procedure, and then, using the job start and job end date execute a select statement.
Getting the job start time is easy- just save the current time from just before you call the job.
How can I get the end tim? Can I use #endTime = GETDATE()? Does starting the job wait for it to end ?
Is it true in general about calls inside SQL procedures?
EDIT:
As people asked, I wanted to call an SSIS job using this code, which I found here:
declare #execution_id bigint
exec ssisdb.catalog.create_execution
#folder_name = 'mssqltips'
,#project_name = 'exec-ssis-stored-proc-ssis-sample'
,#package_name = 'Sample.dtsx'
,#execution_id = #execution_id output
exec ssisdb.catalog.start_execution #execution_id
SSIS already logs package execution durations and events, including step durations. You don't need to use GETDATE().
You can query the catalog.executions view of the SSISDB database to retrieve the execution status, start time and end time, eg:
select status, start_time, end_time,datediff(s,start_time,end_time) as duration
from catalog.executions
where execution_id = #execution_id
Or
select status, start_time, end_time, datediff(s,start_time,end_time) duration
from catalog.executions
where project_name = 'exec-ssis-stored-proc-ssis-sample'
and package_name = 'Sample.dtsx'
order by execution_id
for historical data
It depends on how to you run SSIS via SP. Is it a sql agent job or package execution (catalog)?
If you run it as package, it can be run synchronously or asynchronously.
If it is in asynchronous mode, SP just starts the SSIS package and doesn't wait.
IF it is in synchronous mode, it will wait.
The mode depends on SYNCHRONIZED parameter. This parameter should be set BEFORE execution starts, see the link below how to set it.
https://learn.microsoft.com/en-us/sql/integration-services/system-stored-procedures/catalog-set-execution-parameter-value-ssisdb-database
If you run SQL job from SP and that job executes SSIS package, then SP does not wait, it just activates the SQL Agent Job.
I have a stored procedure USP_A with logic like following:
......
exec dbo.usp_Log 'Start to run job job1'
Exec #intErrorCode = msdb.dbo.sp_start_job 'job1'
IF #intErrorCode <> 0 Goto errorHandling
exec dbo.usp_Log 'End to run job job1'
......
But when I run this stored procedure, it got stuck and when I check log I can only see message 'Start to run job job1'. Also in the SQL Server Agent job monitor I can not see this job get triggered.
But if I manually run
Exec #intErrorCode = msdb.dbo.sp_start_job 'job1'
it works fine.
The SQL Server is Microsoft SQL Server 2005 Enterprise Edition (version 9.00.5000.00)
It turns out to be some kind of SQL Server bug (Maybe the SQL Server 2005 is quite old). The stored procedure just ended unexpectedly and does not return any code.
So the problem is solved by moving all the logic before this msdb.dbo.sp_start_job procedure into a separate stored procedure.
Hope it can help anyone who got this same issue.
Your job is probably failing to start and branching to the errorHandlingsection of your code. If you add ##ERROR_MESSAGE to the log first, then you will see the problem in your log. Something like:
exec dbo.usp_Log 'Start to run job job1'
begin try
Exec #intErrorCode = msdb.dbo.sp_start_job 'job1'
end try
begin catch
exec dbo.usp_Log 'Error: ' + ERROR_MESSAGE()
Goto errorHandling
end catch
exec dbo.usp_Log 'End to run job job1'
UPDATE
I ran a test on my server. I tried to initiate a job that was already running and an error was returned, but did not trigger the catch block. Apparently this is a problem with sp_start_job. This may be the source of some of your confusion. There is a workaround posted here: TRY/CATCH does not work on SQL Server Agent error?
My best guess though is that there is a permission issue when the code is run under a different user context. You could wrap the code to run the job into a procedure that executes under a different security context... like this:
create procedure dbo.sp_RunJob1
with execute as owner
as
exec sp_start_job #job_name = 'job1'
Then call the sp_RunJob1 instead of the sp_start_job statement in your code.
I use SQL Server Agent to fill tables in DataWarehouse. I have about 50 steps in the job and every step is run with a proxy account. And every step works correctly besides one:
SSIS package which contains about 20 Execute SQL Tasks which execute procedure. This is what I have in the Execute SQL Task:
DECLARE #RC int
DECLARE #fordate datetime = null
DECLARE #tablename sysname = 'D_ENTITY'
DECLARE #dataFolder varchar(1024) = 'C:\MountPoints1\src_etl\'
DECLARE #logFolder varchar(1024) = 'C:\MountPoints1\src_etl\'
DECLARE #debug bit = 0
EXECUTE #RC = [dbo].[ETL1A_HR]
#fordate
,#tablename
,#dataFolder
,#logFolder
,#debug
GO
The thing is, that if I execute the package from the SSIS catalog, it works ok. But if it is run by job, it succeeds, but only deletes from tables, but doesn't fill it. It seems like the procedure stops somewhere in the middle.
Any ideas?
Please advise, it took me days trying to solve this...
I think it maybe related to permissions. Executing the SSIS package will use your security context but running it from the agent impersonates the credentials defined in the proxy, and then runs the job step by using that security context.