I am trying to use Execute SQL task in SSIS. but its not accepting variable value in path? The file name is dynamic so, it has to come from variable. The below code is direct input in Execute SQL task.
USE [master]
go
RESTORE DATABASE MyDb FROM
DISK = N'c:\DBRestores\?'
WITH REPLACE
go
then I used, Parameter Mapping to map that value but the task is failing.
Any help? Thanks
You can set dynamic parameter in the Expressions.
In Execute SQL Task Editor, goto Expressions -> Property -> SQLStatementSource -> Expression and put below SQL there, replace your dynamic variable name in it and click on Evaluate Expression and check the Evaluated Value.
"USE [master]
go
RESTORE DATABASE MyDb FROM
DISK = N'c:\\DBRestores\\" + #[User::VariableParameter] + "'
WITH REPLACE
go"
If the evaluated value is as expected, then the script would accept dynamic file names from variable.
Related
I am trying to create an SSIS package for Stored Procedure Deployment and Backup for our project.
I have some .sql file, each file contains one stored procedure definition and the name of the file is the stored procedure name itself.
I am trying to do the following by using SSIS
Read all files names one by one
Find the definition of each stored procedure if it exists in the database
If exists, then save the definition with the same name in a different folder (In my case it's a ROLLBACK folder)
For all new SP it save in a same file named DropNewSp.sql with DROP STORED PROCEDURE command.
After completing the backup process, execute all files in the destination database.
I am able to generate the desire .sql files, but I am faceing the following problem
1. The package also generated unwanted blank .sql file for all new Stored Procedure
2. The execution process failed if the stored procedure has some dependency on subsequent stored proc
In this answer, I will provide the main steps with some references to get more information on how to achieve each step. Even if I agree with the comments mentioned above that this is not the job of SSIS.
Add a foreach loop container that loop over .sql files and store the file name inside a variable:
Looping over files with the Foreach Loop
Lesson 2-2: Add and configure the Foreach Loop container
Load multiple source files
Add an Expression Task to retrieve the file name from the File Full Path (variable)
#{User::FileNameWithoutExtension] = SUBSTRING (#[User::FullFilePath], LEN( #[User::FullFilePath] ) - FINDSTRING( REVERSE( #[User::FullFilePath] ), "\\", 1) + 2, LEN (RIGHT( #[User::FullFilePath], FINDSTRING( REVERSE( #[User::FullFilePath] ), "\\", 1 ) - 1 ) ) - FINDSTRING( REVERSE( #[User::FullFilePath] ), ".", 1 ) )
Add an Execute SQL Task inside the foreach loop container to check if the stored procedure is found in the database:
SELECT COUNT(*) FROM sys.objects WHERE type = 'P' AND name = ?)
Pass the procedure name as parameter to the execute sql task:
Passing Variables to and from an SSIS task
Store the count result inside a variable of type integer using Resultsets:
SSIS Basics: Using the Execute SQL Task to Generate Result Sets
Using precedence constraints with expressions add 2 paths from the execute sql task
the first using expression #[User::Count] == 0
the second using expression #[User::Count] > 0
Other references:
Working with Precedence Constraints in SQL Server Integration Services
Defining Workflow in SSIS using Precedence Constraints
On the second path add an Execute SQL Task to get the procedure definition using the same approach above:
SELECT OBJECT_DEFINITION (OBJECT_ID(N'<databasename>.<schemaname>.' + CAST(? as VARCHAR(100))));
And store the result inside a variable using a result set.
Add a Script Task to write the procedure definition into the destination file
On the first path add a File system task to move the file into the directory specified
Add another foreach loop to read new files and execute the content.
I want to execute this (simplified) query using node-mssql that executes in SQL Server 2017 fine:
USE [Journal]
[GO]
CREATE PROCEDURE [dbo].[EventDelete]
#NotificationID INT
AS
DELETE Notification
WHERE NotificationID = #NotificationID
[GO]
node-mssql declares syntax error using [GO] and requires semicolon, therefore I try this:
USE [Journal];
CREATE PROCEDURE [dbo].[EventDelete]
#NotificationID INT
AS
DELETE Notification
WHERE NotificationID = #NotificationID;
Now we get error:
CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
So let's try this:
CREATE PROCEDURE [Journal].[dbo].[EventDelete]
#NotificationID INT
AS
DELETE Notification
WHERE NotificationID = #NotificationID;
Now we get
RequestError: 'CREATE/ALTER PROCEDURE' does not allow specifying the database name as a prefix to the object name.
Naturally without any DB declaration it attempts to attach to the master error:
CREATE PROCEDURE permission denied in database 'master'.
So writing the question really works at setting one's thoughts straight.
The reason is the stored procedure requires to be created in one batch, which [GO] signifies, with nothing else.
Execute USE [Journal] as one batch using the .batch('USE [Journal]') method and then the SQL to CREATE PROCEDUCE as a new .batch(...) execution, sequentially.
Unless there is another method within node-mssql which allows for multi-batch executions?
I edited the question based on the solution that Hadi gave.
I am using SSIS in VS 2013.
I have a user variable called MyVariableList and Query.
This is Expression in user variable Query: "SELECT cola, colB FROM myTable WHERE myID IN (" + #[User::MyVariableList] + ")"
I have a Script Task that set the value of #[User::MyVariableList].
Dts.Variables["User::MyVariableList"].Value = sList;
After that, I have A Data Flow Task with OLE DB Source (from 1 database) to another OLE DB Destination (another database on another server).
In the OLE DB Source Editor, I set
Data access mode: SQL Command from variable
Variable name: User:: Query
In the OLE DB Source connection, I have set the DelayValidation to True
Before I even can run the package, I am getting this error
How can I fix this issue ? Thank you
First of all, you are working with a project parameter not a project variable
You cannot achieve this using a parameterized sql command, you have to build the whole query inside a variable, and use it as source (SQL Command from variable)
Parameters are used to specify a single value, not concatenating the query string
Create a SSIS variable (User::Query), change the variable Evaluate As Expression property to True and write the expression in the variable Expression property. Like the following
"SELECT cola, colB FROM myTable WHERE myID IN (" + #[$Project::MyProjectVariable] + ")"
Note: to use a project parameter inside an expression use the following syntax : #[$Project::MyProjectVariable]
I'm busy setting up an SSIS package that takes a flat file and loads its content into a staging table. From there it needs to take the file name of that file and save it into a field on another table, along with one of the lines of data. The loading of the data I do by using an execute SQL task that executes a stored procedure. This procedure takes the file name as input parameter (just so I can write it to that table)... I added a Script task before the execute SQL Task that does the following:
public void Main()
{
string inputFolder;
string fileName;
inputFolder = Dts.Variables["SourceFolder"].Value.ToString();
// MessageBox.Show(inputFolder);
string[] foundFiles = null;
foundFiles = System.IO.Directory.GetFiles(inputFolder);
if (foundFiles.Length > 0)
{
fileName = foundFiles[0];
Dts.Variables["ProcessedFileName"].Value = System.IO.Path.GetFileName(fileName);
// MessageBox.Show(fileName);
// MessageBox.Show(System.IO.Path.GetFileName(fileName));
}
Dts.TaskResult = (int)ScriptResults.Success;
}
The "ProcessedFileName" variable is a global variable in the SSIS package, as well as the "SourceFolder" variable.
The execute SQL task I set up using Direct input executing:
DECLARE #StoredProcedure varchar(100) = ?;
DECLARE #ProcessedFileName varchar(100) = ?;
EXEC ? ?;
The parameter mapping is to variables StoredProcedure and ProcessedFileName.
The problem is when I run this it tells me "No value given for one or more required parameters." Why could this be?
You cannot dynamically change a stored procedure name in an Execute SQL Task using parameters. That is what EXEC ? ?; is doing.
If you need to change the procedure name at run-time then you'll need to use string concatenation via expressions to build our your query.
Bigger picture, it seems that you are using a script task where a For Each (file) Enumerator task would suffice. There are reasons to use a script task over foreach (like if you need to process in order, etc) but it doesn't read like you're doing that.
Assorted answers that may be of help on how to accomplish expressions and foreach enumerator
SSIS: Get any flat file source from folder and cache the name as a super global variable
Passing a variable through DTEXEC with xp_cmdshell (SQL Server 2008)
Import most recent csv file to sql server in ssis
fetching data from multiple file and loading it into raw file destination(raw file should be dynamic) in ssis
I have placed a execute sql task inside the foreach loop container , where i want to execute the stored procedure name obtaining from the ssis user defined variable
But i am not finding a right syntax to execute stored procedure name from variable. and i want to pass input parameter to execute the stored procedure which is also a another dts variable
Please can any one help to figure out the right syntax
Lets say you have two variables StoredProcedureName and ParameterValue
Create a new variable called QueryString. Open up the properties window by pressing F4 and then click on the variable name in the window that has list of variables. Set the EvaluateAsExpression property of your QueryString variable to True.
Then click the elliptical in Expression to open up the Expression Builder. Type the following expression
"Execute " + #[User::StoredProcedureName] + " #ParameterName = '" + #[User::ParameterValue]+ "'"
Click on Evaluate Expression and you should see
Execute MyProcedure #ParameterName = 'SomeValue'
Assign this variable to your SourceVariable for the Execute SQL Task.
You can build your string out as provided above but I would not start with it. For one, it assumes everything is string and second it could conceivably open you up to sql injection (highly improbable, I agree)
To actually use the native parameter mapping for ADO.NET you need to use the #PlaceHolder for your variable substitution. Based on your screenshot, the value of #[User::StoredProcedureName] would need to have the format of EXECUTE schema.ProcName #ParameterName Otherwise, you're looking at cobbling the expression from #Raj More's example without the =... piece
Mapping is as simple as the following. Ensure you select the correct Data Types and Parameter Names to correlate with your query.