I have to connect to many Foxpro databases that have a connection string like:
Data Source=\\All Users\\DB0009\db1.dbc;User ID=xxx;Password=yyy;Provider=VFPOLEDB.1;Persist Security Info=True;
where the folder DB0009 can be any integer from 0000 to 0100 and the db1.dbc can be either db1.dbc or db2.dbc for each folder.
For each connection string, I need to build a simple SQL statement that is identical for every database except for a hardcoded year. So the sql is: select *, '2012' from table
I'd like to be able to store both the connection string AND the year for each connection string in a sql table that can be looked up at run time.
I am using SSIS 2008. I'm guessing based on what i've seen that i can use the foreach loop with the enumerator set as the ADO Enumerator (though i wouldn't mind confirmation there), but how can i pull the year off of that same table and put it into the sql query i have inside a data flow task?
Thanks for any help!
Kary
You could do the following steps:
Create the foreach loop to get the connection string and year values into variables.
create a connection manager and, using an expression, set the connection string property to your connection string variable.
Create another variable with an expression that creates your SQL command with the year variable (dynamic SQL command string).
use the execute SQL task to execute this within your foreach.
Here's a link to a blog on mapping the parameter inside the Execute SQL Task that should be helpful. http://www.rafael-salas.com/2007/11/ssis-mapping-parameter-inside-of.html
Related
I'm trying to map a parameter and variables to a SQL statement within a SQL Task
I'm connecting to an oracle DB - the connection is working fine.
My SQL Statement is:
insert into ? values(?,?)
I map package parameter: Param1 to (parametername) 0 in the mapping screen
variable1 to (parametername) 1 in the mapping screen and variable2 to (parametername) 3
Both the parameter and variables are datatype VARCHAR, and values are:
p1 = 'TEST_TABLE
v1 = 'TEST'
v2 = 'TEST'
However, I get an error "parameters no mapped correctly"
If I enter a sql statement like: insert into TEST_TABLE values('TEST','TEST') the record is inserted into the oracle database successfully.
Any ideas?
None of the connection managers available to the Execute SQL Task support parameterizing the table name, which is what you're trying to do with the first "parameter" in your query insert into ? values(?,?) (For further details, see "Using Parameter Names and Markers" in the MSDN article Parameters and Return Codes in the Execute SQL Task.)
The generally acceptend solution is to build the insert string on the fly and execute it. Here's an example: Using Tablename as variable in ssis
Can i do something like below, let me know
IF #parameter=1 BEGIN ...query... END IF #parameter=2
Need the correct syntax if it is possible.
It's OLE DB connection.
Not a Stored Proc. just a sql query
DECLARE #param AS INT = ?;
IF #param = 1
BEGIN
SELECT 1 AS Y;
END
ELSE IF #param = 2
BEGIN
SELECT 2 AS Y;
END
There are two question marks in your query and probably you were passing only one variable. I have seen code where developers pass the same value twice (or multiple) times. This is inefficient. A better way is to receive the passed parameters in SSIS variables. Advantages:
1. You need to pass one value only once.
2. More importantly, if you change the order in which the passed parameters are used in the sql, you do not need to change their order on the user-interface of Execute SQL Task Editor//Parameters. This is what Andy Leonard has suggested later in his response.
You can. Assuming you are referring to an Execute SQL Task, the parameters in an Execute SQL Task using an OLE DB connection utilize question marks (?) as parameter placeholders. You map the placeholders to SSIS variables on the Parameter Mapping page of the Execute SQL Task. In the SQLStatement property you would enter:
If (?=1)
begin
... {some T-SQL here} ...
end
If (?=2)
begin
... {some T-SQL here} ...
end
That's one way to accomplish what I think you are asking.
Another way is to create an Execute SQL Task to read the value of #parameter from the database into an SSIS variable. Then you can build two Execute SQL Tasks - one with each option for T-SQL as the SQLStatement property - and use expressions on precedent constraints to determine which Execute SQL Task to execute.
Hope this helps,
:{>
You cannot use Execute SQL Task to run Transact-SQL statements.
For setting conditional SQL Statement based on what you are trying to achieve.
In Execute SQL Task editor
In general tab, leave the SQLStatement blank.
In parameter mapping tab, add parameter and map User::Parameter variable to Parameter Name 0.
In Expression tab, set the SQLStatementSource to
(DT_NUMERIC, 18, 0) #[User::Parameter]==1 ? ...query 1... : ...query 2...
I am having an issue programmatically setting connection strings.
Here is an overview of my project. I am using 2012 SSIS and have two connections in my connection managers (Source and Destination and both are OLE DB connections). I have multiple packages I want to run. Each of these packages only contain Execute SQL tasks. Each task I have the SQL Statement connection type set to OLE DB, the connection is Destination, the SQL Source Type is a File Connection, and the File Connection is a file located on my C drive that is a script file that I generate in my program.
I have these packages deployed on my server which is a 2012 instance. The source and destination connections are also on my server but on a 2008 R2 instance.
I loop through N number of databases. In each loop I can set the Connection String and IntialCatalog properties by executing a SQL statement:
DECLARE #var sql_variant = N'Data Source=MyServerName\SQL2008R2;Initial Catalog=DatabaseName1;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;'
EXEC [SSISDB].[catalog].[set_object_parameter_value] #object_type=20, #parameter_name=N'CM.Destination.ConnectionString', #object_name=N'MAC', #folder_name=N'MAC', #project_name=N'MAC', #value_type=V, #parameter_value=#var
This does work since I can open up the configure option on my project and see that the connection string and initial catalog values change while I am stepping through the program. (I didn't include the SQL for the initial catalog but it is similar to the connection string)
Now when I execute this through my program, I the following errors:
The connection "{9C2C8088-CE67-4D93-81B8-EC364D6E78D1}" is not found. This error is thrown by Connections collection when the specified connection element is not found.
Is there a way to update the package so the Execute SQL Tasks have an updated connection?
As a side note, if I open the packages in Visual Studio and modify the connections, the packages execute. It is when I try to programmatically change the connections and execute or if I try to execute the packages that are deployed on the server when it errors.
I did see this question and although it is similar, I think it varies enough to have a separate question.
SSIS Connection not found in package. I have found a lot of great info here, just not what I am looking for yet.
Any help/advice is greatly appreciated!
Thanks
Mark
My suggestion would be to move your database looping and connection string setting inside your packages by taking advantage of SSIS's Foreach Loop container.
Create a new string variable in your package. Call it "User::DestinationConnectionString".
Right-click on your Destination connection and choose Properties.
Create an Expression for your connection's ConnectionString property and set to your User:DestinationConnectionString variable.
Put all of your connection strings in a table. Let's call it ConnectionStrings.
Create an Execute SQL task at the beginning of your package. Let's call it "Get Connection Strings."
Set the connection to where your ConnectionStrings table is.
Write a query to retrieve the connection strings.
Set the ResultSet to Full Result Set.
Set your Result Set to a variable of type Object. Let's call it User::ConnectionStrings. (The Result Name should be 0.)
Create a ForEach Loop Container. Name it "For Each Connection String."
Set the Collection Enumerator to Foreach ADO ENumerator.
Set the ADO Object Source variable to User::ConnectionStrings.
In the Variable Mappings tab, map Index 0 to your User::DestinationConnectionString variable.
Place your Execute SQL tasks inside your foreach loop.
Now when the package runs, it will loop through each connection string, assign it to the variable, which the connection uses to get its connection, which the SQL task then runs against.
If you don't know your database connection strings until runtime, you can just write them into the table then and then kick off your package.
I have declared a variable at the package level compdate and am testing data flow to the variable by droping an Execute SQL Task in the Control Flow of the package.
In the task,
SQL Statement:
select ? = (getdate() - 1)
Parameter Mappings:
Variable Name: User::compdate
Direction: Output
Data Type: DATE
Parameter Name: 0
Parameter Size: -1.
Why am i getting error:
[Execute SQL Task] Error: Executing the query "declare #compdate date
set #compdate = (getdate() ..." failed with the following error: "Syntax error or access violation". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
I do not see why you need to execute an SQL statement to get the previous day as this can be done in various other ways.
To answer your question though, since you are trying to store the result of the SQL query from your Execute SQL Task you have to change the SQL statement that you have provided.
Your new query:
SELECT (GETDATE() - 1) AS DateVar
Where DateVar will be the single parameter that is returned which you need to map to your variable.
You need to delete your Parameter Mappings as they are not needed. Open up the Result Set tab and Add a new result. Set the Result Name to be DateVar and set the Variable Name to be your variable User::compdate
You then need to set up your Execute SQL Task to return a Single Row result set in the General tab, mapped to your variable. Select Single row for the ResultSet option.
Working with result sets is explained in great details here. Scroll down to the 'Working with a Single-Row Result Set' section, it has a great example which you can follow.
If you want to use without using the result set. try with following steps.
Create the stored procedure in your respective database. Following
code is an example.
CREATE proc GetYesterDay(#yesterday datetime output)
as
Select #yesterday=getdate()-1
Create the ADO.NET connection to run the stored procedure. In which, you can mention the direction of the input and output of the parameters.
Create the execute task and configure it as following screenshot.
Click on Parameter Mapping and configure as following screenshot.
Now SSISCompletedDate variable will be filled with respective data.
Hope this helps!
I have a variable #csv which hold a comma separated value such as:
-a
-a,b
-a,b,c
I need to pass it in a query in my OLE DB source in a data flow to create a query such as:
SELECT COUNT(1) FROM table WHERE col1 IN #csv
So if #csv="a,b" then internally it should resolve into
SELECT COUNT(1) FROM table WHERE col1 IN 'a','b'
How can this be best achieved in SSIS 2008? Can I avoid the script component to create a dynamic query and storing it in a variable?
How can this be best achieved in SSIS
2008? Can I avoid the script component
to create a dynamic query and storing
it in a variable?
The easiest/best way would still be with a script component.
Otherwise you could:
use the csv as data source and select your result
use the and "add column" tool to add the rest of your SQL query around the result
store the result into a variable
Then use a the OLE DB datasource with "query from variable"
You can create a variable to store the query and compose its value using an expression, like:
List of Variables:
Option 1: In case of using OLE DB, select SQL Command from variable and bind the variable #sqlQuery:
Option 2: In case of using ADO.NET, Go to properties of Data Flow Task and expand Expressions and bind the ADO.NET Source > SqlCommand with the variable #sqlQuery + Make sure that ADO.NET Source > Data access mode is a SQL Command:
Option 3: In case of using Execute SQL Task, expand Expressions and bind the SqlStatementSource with the variable #sqlQuery + Make sure that SQL Source Type is a Direct Input: