Is there a way in SSRS to create a snapshot for a report that uses a shared dataset? We are looking for a way to dynamically set the server and credentials in SSRS, but it seems when the shared dataset is used there is no way to cache a report.
Two things that I think may help you:
You can create a dynamic connection string from parameters you pass in. However you lose intellisense when creating this so generally I use an actual database first to do my dataset then change the connection string later:
A. Create a variable #Server, set it to text:
B. Create a local DataSource, this must be local as you cannot share a data source that is dynamic, to my knowledge as it has no input to go on thus a shared must have set inputs.
C. On the side of 'Connection string:' hit the 'fx' button to get a dynamic connection string. Build a connection string of text with your parameter being an input:
="Data Source=" & Parameters!Server.Value & ";Initial Catalog=(DBName)"
D. You NOW have to set up a dataset to bind to #Server variable or else someone just needs to do plain text to guess at a server. For this reason I usually create a dataset like
select 'Server1' as Server
union
select 'Server2'
union
select 'Server3'
You can handle the cache aspect COMPLETELY from the hosted end and not worry about the report stuff. Just go to a report once deployed and choose 'Manage'>'Snapshot Options'> Set your preferences.
EDIT: You probably want another variable for the database or else you will assume a same database structure all the time.
Related
My team and I are in the process of migrating from Crystal Reports to SQL Server Reporting Services. A handful of our reports involve what my team refer to as "dynamic external images". What this means is that in the report we would have this default blank image object, and then in the Graphic Location setting we would have the following function:
Trim({rpt_StoredProc;1.SignaturePath}) + Trim({rpt_StoredProc;1.SignatureId}) + ".jpg"
This way, we could pass through the directory path and the file name (minus the file extension) via the stored procedure.
I'm now trying to replicate this in SQL Server Reporting Services Report Builder and I'm running into a brick wall.
Your data relating to dynamic external images having been imported in SSRS should be accessible in a table using the data type varbinary(max). This can be accessed and utilised in an SSRS report either as a single field (ie in a header/title) or in matrix a field.
Both usages require you use the toolbox, (view and select toolbox) and left mouse click , drag "image" to your report, image source "database", use the field (select varbinary(max) field) , MIME type try "image/bmp" first, select the size to suit your needs.
and you should be good to go.
Best of luck.
I finally found the answer!
="file://" & First(Fields!SignaturePath.Value, "rpt_StoredProc") & "\" & First(Fields!SignatureId.Value, "rpt_StoredProc") & ".JPG"
I thought I had already tried this and that it didn't work, but I guess not.
My purpose is I want to change the value of this Application Scope Connection String using Code.
So, I have this dataset database for my vb.net project. and it's fully working
(fully rendered) when we're running the app.
If you open the project setting, it is stored on Connection String.
It is using Applicatio Scope. Not user Scope. ANd it's
saved with its value ; "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ProgramData\RK-Medis\db-used.mdb"
My questions are:
Can we change that variable value of Connection String before its
called / rendered on its GUI?
WHat are the code for changing it?
If no we can't change it, then what are the alternative for using
dataset + its Connection String that automatically used in almost
many tables (GUI) i have...?
Perhaps you need a tableConnectionString for example, to store the CS for each user. Then use a property of string(or maybe const variable) to store your connection string for that particular user during user login. Substitude the CS to your application. Then each of the user will be able to have different CS.
Hope its give you the idea.
I am working with SSIS 2008. I have a select query name sqlquery1 that returns some rows:
aq
dr
tb
This query is not implemented on the SSIS at the moment.
I am calling a stored procedure from an OLE DB Source within a Data Flow Task. I would like to pass the data obtained from the query to the stored procedure parameter.
Example:
I would like to call the stored procedure by passing the first value aq
storedProdecure1 'aq'
then pass the second value dr
storedProdecure1 'dr'
I guess it would be something like a cycle. I need this because the data generated by the OLE DB Source through the stored procedure needs to be sent to another destination and this must be done for each record of the sqlquery1.
I would like to know how to call the query sqlquery1 and pass its output to call another stored procedure.
How do I need to do this in SSIS?
Conceptually, what your solution will look like is an execute your source query to generate your result set. Store that into a variable and then you'll need to do iterate through those results and for each row, you'll want to call your stored procedure with that row's value and send the results into a new Excel file.
I'd envision your package looking something like this
An Execute SQL Task, named "SQL Load Recordset", attached to a Foreach Loop Container, named "FELC Shred Recordset". Nested inside there I have a File System Task, named "FST Copy Template" which is a precedence for a Data Flow Task, named "DFT Generate Output".
Set up
As you're a beginner, I'm going to try and explain in detail. To save yourself some hassle, grab a copy of BIDSHelper. It's a free, open source tool that improves the design experience in BIDS/SSDT.
Variables
Click on the background of your Control Flow. With nothing selected, right-click and select Variables. In the new window that pops up, click the button that creates a New Variable 4 times. The reason for clicking on nothing is that until SQL Server 2012, the default behaviour of variable creation is to create them at the scope of the current object. This has resulted in many lost hairs for new and experienced developers alike. Variable names are case sensitive so be aware of that as well.
Rename Variable to RecordSet. Change the Data type from Int32 to Object
Rename Variable1 to ParameterValue. Change the data type from Int32 to String
Rename Variable2 to TemplateFile. Change the data type from Int32 to String. Set the value to the path of your output Excel File. I used C:\ssisdata\ShredRecordset.xlsx
Rename Variable 4 to OutputFileName. Change the data type from Int32 to String. Here we're going to do something slightly advanced. Click on the variable and hit F4 to bring up the Properties window. Change the value of EvaluateAsExpression to True. In Expression, set it to "C:\\ssisdata\\ShredRecordset." + #[User::ParameterValue] + ".xlsx" (or whatever your file and path are). What this does, is configures a variable to change as the value of ParameterValue changes. This helps ensure we get a unique file name. You're welcome to change naming convention as needed. Note that you need to escape the \ any time you are in an expression.
Connection Managers
I have made the assumption you are using an OLE DB connection manager. Mine is named FOO. If you are using ADO.NET the concepts will be similar but there will be nuances pertaining to parameters and such.
You will also need a second Connection Manager to handle Excel. If SSIS is temperamental about data types, Excel is flat out psychotic-stab-you-in-the-back-with-a-fork-while-you're-sleeping about data types. We're going to wait and let the data flow actually create this Connection Manager to ensure our types are good.
Source Query to Result Set
The SQL Load Recordset is an instance of the Execute SQL Task. Here I have a simple query to mimic your source.
SELECT 'aq' AS parameterValue
UNION ALL SELECT 'dr'
UNION ALL SELECT 'tb'
What's important to note on the General tab is that I have switched my ResultSet from None to Full result set. Doing this makes the Result Set tab go from being greyed out to usable.
You can observe that I have assigned the Variable Name to the variable we created above (User::RecordSet) and I the Result Name is 0. That is important as the default value, NewResultName doesn't work.
FELC Shred Recordset
Grab a Foreach Loop Container and we will use that to "shred" the results that were generated in the preceding step.
Configure the enumerator as a Foreach ADO Enumerator Use User::RecordSet as your ADO object source variable. Select rows in the first table as your Enumeration mode
On the Variable Mappings tab, you will need to select your variable User::ParameterValue and assign it the Index of 0. This will result in the zerotth element in your recordset object being assigned to the variable ParameterValue. It is important that you have data type agreement as SSIS won't do implicit conversions here.
FST Copy Template
This a File System Task. We are going to copy our template Excel File so that we have a well named output file (has the parameter name in it). Configure it as
IsDestinationPathVariable: True
DestinationVarible: User::OutputFileName
OverwriteDestination: True
Operation: Copy File
IsSourcePathVariable: True
SourceVariable: User::TemplateFile
DFT Generate Output
This is a Data Flow Task. I'm assuming you're just dumping results straight to a file so we'll just need an OLE DB Source and an Excel Destination
OLEDB dbo_storedProcedure1
This is where your data is pulled from your source system with the parameter we shredded in the Control Flow. I am going to write my query in here and use the ? to indicate it has a parameter.
Change your Data access mode to "SQL Command" and in the SQL command text that is available, put your query
EXECUTE dbo.storedProcedure1 ?
I click the Parameters... button and fill it out as shown
Parameters: #parameterValue
Variables: User::ParameterValue
Param direction: Input
Connect an Excel Destination to the OLE DB Source. Double click and in the Excel Connection Manager section, click New... Determine if you're needing 2003 or 2007 format (.xls vs .xlsx) and whether you want your file to have header rows. For you File Path, put in the same value you used for your #User::TemplatePath variable and click OK.
We now need to populate the name of the Excel Sheet. Click that New... button and it may bark that there is not sufficient information about mapping data types. Don't worry, that's semi-standard. It will then pop up a table definition something like
CREATE TABLE `Excel Destination` (
`name` NVARCHAR(35),
`number` INT,
`type` NVARCHAR(3),
`low` INT,
`high` INT,
`status` INT
)
The "table" name is going to be the worksheet name, or precisely, the named data set in the worksheet. I made mine Sheet1 and clicked OK. Now that the sheet exists, select it in the drop down. I went with the Sheet1$ as the target sheet name. Not sure if it makes a difference.
Click the Mappings tab and things should auto-map just fine so click OK.
Finally
At this point, if we ran the package it would overwrite the template file every time. The secret is we need to tell that Excel Connection Manager we just made that it needs to not have a hard coded name.
Click once on the Excel Connection Manager in the Connection Managers tab. In the Properties window, find the Expressions section and click the ellipses ... Here we will configure the Property ExcelFilePath and the Expression we will use is
#[User::OutputFileName]
If your icons and such look different, that's to be expected. This was documented using SSIS 2012. Your work flow will be the same in 2005 and 2008/2008R2 just the skin is different.
If you run this package and it doesn't even start and there is an error about the ACE 12 or Jet 4.0 something not available, then you are on a 64bit machine and need to tell BIDS/SSDT that you want to run in 32 bit mode.
Ensure the Run64BitRuntime value is False. This project setting can be found by right clicking on the project, expand the Configuration Properties and it will be an option under Debugging.
Further reading
A different example of shredding a recordset object can be found on How to automate the execution of a stored procedure with an SSIS package?
Anyone have any idea how do we specify different connection strings in SSIS for different environments - like system integration test environment, user acceptance test environment and production environment?
Is it done by defining multiple connection managers or we can define multiple configuration files and point our connection string to?
You do not need to have multiple connections for the same database.
In SSIS 2008:
It's a good idea to have your connection strings defined using an expression. This is how you can do it:
Suppose you have added a anew OLEDB connection in your connection manager. Copy the value of the ConnectionString property. IT would look like this:
Data Source=(local);Initial Catalog=Learn;Provider=SQLNCLI10.1;Integrated Security=SSPI;Application Name=SSIS-RaggedFile-{03053F2E-8101-4985-9F2B-8C2DDE510065}(local).Learn;Auto Translate=False;
Remove the non-essentials:
Data Source=(local);Initial Catalog=Learn;Provider=SQLNCLI10.1;Integrated Security=SSPI;
Now create three new variables at the control surface level: sServer, sDb, sProvider. Type for all these three varaibles will be string. Their values - using this example - will be (local), Learn, and SQLNCLI10.1.
Go back to the ConnectionString property of your connection. and set its value to
"Data Source=(local);Initial Catalog=Learn;Provider=SQLNCLI10.1;Integrated Security=SSPI;"
Now, replace the server, db, and provider with the variables you have created to make your expression look like this:
"Data Source=" + #[User::sServer] + ";Initial Catalog=" + #[User::sDb] + ";Provider=" + #[User::sProvider] + ";Integrated Security=SSPI;"
When we move from one environment to another, we may encounter different versions of the databases - hence it is helpful to have a variable for provider as well.
Now, these values can be changed at the time of deployment.
In SSIS 2012 -
This method would still work with a little bit of change. Change these three variables to parameters and make them required. That way, at the time of deployment of deployment, you will be forced to change the values. This is just a starting point. Read up on server environment.
Note: I opine that a variable should have atomic value. This helps in avoiding any error due to mistyping. That's why I have created three separate variables as opposed to having one variable called sCnxn (for example) and have someone change a portion of that variable at the time of deployment.
I have a 'Product' parameter in my report. Depending on the product the user chooses, it will call the report generator stored procedure from a different data source. Looking at this article, I've found how to do the first part of this solution. I've created two internal parameters, Server and Database, and the connection string will use them to connect to the right database.
But I need to set this two parameters when the user chooses a product. How could I do this?
(If #Product = X) => #Server = Y, #Database = Z
How did I resolve this:
I didn't do the way the article suggested. Instead, I threw away this two additional parameters and just put a big Switch expression at the connection string definition. Depending on the #Product value, the switch returns a different value. It may sound uglier, but at least it works.