Calling SSIS package from stored procedure under a different account - sql-server

I have a stored procedure which runs and calls an SSIS pacakge using EXEC SSISDB.CATALOG.start_execution #Execution_Id method.
However I need the package to execute under a service account with more privileges and not the user's account.
using the EXECUTE AS LOGIN = doesn't work. Does anyone know how to accomplish this. The only other way I know involves Agent Jobs and proxy accounts.
Surely there is a simply way to accomplish this on SQL 2012 ?

'EXECUTE AS' works fine for me.
One thing to note is to switch context to the SSIS Catalog database, before calling the execute method. Hence the 'USE ' statement on top.
USE SSISDB;
EXECUTE AS LOGIN = 'domain\user'
DECLARE #execution_id BIGINT
EXEC CATALOG.create_execution #folder_name = 'MyFolder1',
#project_name = 'MyProject', #package_name = 'Package.dtsx',
#use32bitruntime = 1, #execution_id = #execution_id OUTPUT;
EXEC CATALOG.start_execution #execution_id;

Related

How do I look at SQL Agent Job without starting SQL Agent?

I have just set up a new SQL Server instance on a new server and moved our application to use the new server. So I've had to turn SQL Agent off on the old server - turning it on would start the scheduler and start sending out emails and running things that shouldn't be run any more.
However, I need to take a close look at a SQL Agent Job on the old server, and ideally reverse-engineer the code to recreate it so I can modify it and apply it to the new server.
How do I generate the code for that Job on the old server without turning SQL Agent on?
Thanks
Even if SQL server agent is not running, you can see how jobs and schedules were set up by viewing the following system DMVs.
msdb.dbo.sysjobs_view
msdb.dbo.sysjobs
msdb.dbo.sysjobschedules
msdb.dbo.sysschedules
I use preset scripts to create all my jobs and schedules independent of the server. Here is a sample script to create the recycle log job. You can modify this or use any piece of this as you see fit.
DECLARE #sql nvarchar(max)
BEGIN TRY
IF EXISTS (SELECT job_id
FROM msdb.dbo.sysjobs_view
WHERE name = N'Cycle SQL log')
EXEC msdb.dbo.sp_delete_job #job_name=N'Cycle SQL log'
, #delete_unused_schedule=1
EXEC msdb.dbo.sp_add_job
#job_name = N'Cycle SQL log',
#description = N'This job forces SQL to start a new error log (In the Managment node of SSMS)',
#owner_login_name = N'your_sql_login' ;
EXEC msdb.dbo.sp_add_jobstep
#job_name = N'Cycle SQL log',
#step_name = N'sp_cycle_errorlog',
#subsystem = N'TSQL',
#command = N'exec sp_cycle_errorlog' --put your executable code here
--These next two lines set the target server to local, so that the job can be modified if necessary
SET #sql = 'EXEC msdb.dbo.sp_add_jobserver #job_name=N''Cycle SQL Log'', #server_name = N''' + ##SERVERNAME + ''''
EXEC sys.sp_executesql #stmt = #sql
END TRY
BEGIN CATCH
PRINT 'Uh-oh. Something bad happened when creating the Cycle SQL Log job. See the following error.'
PRINT CAST(ERROR_MESSAGE() AS NVARCHAR(1000))
END CATCH
You can use use code to automate the addition of schedules based on values you pull from the DMVs listed above.

Execute package task with external reference to SQL Server

** Edit: Executing the package with T-SQL script causes an authentication problem:
"Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'." **
** Edit 2: This error is caused by Windows credentials performing a double hop. Here is a solution to this problem **
I'm trying to execute an SSIS package that was already deployed to an SQL Server instance before. This SQL Server instance's version is 14.0.3281 (SQL Server 2017).
I can't use project reference as the wanted package is in another project, and I prefer not to upload it to the server's file system.
Is it really a version problem?
How can I execute a deployed package from another project?
I know I can run the a job with this package with T-SQL, but I want the task to continue only after this package has successfully completed its execution.
This is the error I get:
The attempted operation is not supported with this database version.
------------------------------ ADDITIONAL INFORMATION:
The attempted operation is not supported with this database version.
There is a way to run a package via T-SQL and wait for it to finish using built-in procedures.
-- Create the execution object
DECLARE #execution_id BIGINT
EXEC [SSISDB].[catalog].[create_execution]
#package_name = #PackageName
, #project_name = #ProjectName
, #folder_name = #FolderName
, #use32bitruntime = False
, #reference_id = NULL
, #execution_id = #execution_id OUTPUT
-- Configure execution
EXEC [SSISDB].[catalog].[set_execution_parameter_value]
#execution_id
, #object_type = 50 -- System parameter
, #parameter_name = N'SYNCHRONIZED'
, #parameter_value = 1 -- set this to 1 to wait for completion
-- Start the execution
EXEC [SSISDB].[catalog].[start_execution] #execution_id
You could wrap this into a stored procedure like "startPackage" and also include checking for the result using the execution id:
-- Check package status, and fail script if the package failed
IF 7 <> (SELECT [status] FROM [SSISDB].[catalog].[executions] WHERE execution_id = #execution_id) AND #Syncronized = 1
RAISERROR('The package failed!', 16, 1)

How to enable SQL Server Agent job execution from stored procedure

I have an agent job that executes a .dtsx package. It needs to be called from a stored procedure owned by a database user, and used by the app and executes as owner.
Granted
Code:
DECLARE #return_value INT
EXEC #return_value = [dbo].[rscc_drop_off_caller]
SELECT 'Return Value' = #return_value
I gave the user SQLAgentUserRole and confirmed it has execute on sp_start_job.
If I run:
DECLARE #ReturnCode INT;
EXEC #ReturnCode = msdb.dbo.sp_start_job N'RSCC Push CCD To AIM';
PRINT #ReturnCode;
from a window in SSMS, it runs fine.
But if I run:
exec csisql.rscc_drop_off_caller;
it fails with an error:
Msg 229, Level 14, State 5, Procedure sp_start_job, Line 1
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
The 'rscc_drop_off_caller' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.
I even tried to drop and recreate the stored procedure after granting the permission but I get the same error. The stored procedure is pretty simple:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[rscc_drop_off_caller]
WITH EXECUTE AS OWNER
AS
DECLARE #ReturnCode int;
BEGIN
EXEC #ReturnCode = msdb.dbo.sp_start_job N'RSCC Push CCD To AIM';
RETURN (#ReturnCode);
END
Sorry if I provided too much information. I really need to get this working but I'm stumped. Any help would be REALLY appreciated. Thanks in advance.
KT
To summarize: I need to be able to call the agent job from within the stored procedure. That currently fails although calling the job directly (exec...) as the owning user works fine.
Thanks for the help. I resolved the issue. I modified the SP to execute as caller and granted specific permission to that DAimConnUser to execute the stored procedure.

SSIS package execution succeeds but doesn't do its job

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.

Bulk Insert problem

I have a stored procedure that makes bulk insert from some file:
CREATE PROCEDURE [dbo].[SP_BulkInsert] #FileName NVARCHAR(200) AS
BEGIN
DECLARE #bulkinsert NVARCHAR(1000)
SET #bulkinsert = N'BULK INSERT TblTemp FROM ''' + #FileName +
N''' WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = ''\n'')'
EXEC sp_executesql #bulkinsert
RETURN ##ROWCOUNT
END
This stored procedure runs fine when I run it from SQL Server Management Studio, but when I try to run it with ExecuteNonQuery of ADO.NET I get the following error:
"The INSERT permission was denied on the object 'TblTemp', database
'TempDB', schema 'dbo'."
Important: all other stored procedures (that make SELECT/INSERT/DELETE/UPDATE) run fine from ADO.NET.
The user under which all the things are run is a member of the bulkadmin role, and also a member of a custom db_executer role (that has just EXECUTE permission).
The code runs fine for a lot of stored procedures, it's a first time that it fails..
This is the function
public static int BulkInsert(string fileName)
{
SqlParameter paramFileName = new SqlParameter("FileName", fileName);
SqlParameter paramRetValue = new SqlParameter();
paramRetValue.Direction = ParameterDirection.ReturnValue;
SqlParameter[] #parameters = { paramFileName, paramRetValue };
SqlHelper.ExecuteNonQuery(ConnectionSettings.ConnectionString,
CommandType.StoredProcedure, "SP_BulkInsert", parameters, true);
return (int)paramRetValue.Value;
}
I logging into the SSMS with the same username/password that are in the connection string on ADO.NET side..
The bottom question is, why in Management Studio the stored procedure succeed, while via ADO.NET it fails (with the above error message).
Running SQL via the sp_executesql uses different permissions than directly in the stored procedure. I would advise checking that the user which you are running the stored procedure as has (in this instance) INSERT permissions against the table "TblTemp".
To do this in Sql Server Management Studio...
expand the list of tables
right click on the appropriate one and select properties
on the "permissions" tab, click the "Add..." button.
Either type in the user or role, or "Browse..." for it.
with the user or role selected in the top table, tick "Grant" in the appropriate permissions in the "Explicit permissions for {username/role}"
click OK
The Management Studio must be running on the sa account which has all privileges, but the user that you are connecting through ADO.NET may not have the correct privileges set. You need to give the users writing permissions through the Management studio. Look in the users list.

Resources