How to read SQL Server Report history programatically? - sql-server

a SQL Reporting Services Question - for SQL Server 2008.
Given that SQL Server Reporting Services features a Scheduler which can be used to schedule the running of SQL Reports, does anyone know a way to programatically (via C#) read a report's history from the Report Server (and then perhaps retrieve the results of the report)?
So after some more digging, it looks like I need to generate a WSDL for the Report Server and then access information by using the ReportingService object - has anyone done this before (with 2008) and can provide some pointers?
Note: looks like (according to SQL 2008 books online) the WSDL address for SQL 2008 is:
http://server/reportserver/ReportService2005.asmx?wsdl
If I can get this working, I'll post an answer up with the basic steps to implementing it :) It's a little confusing as the documentation is a mixture of SQL 2000 and SQL 2005 references!

OK, so I've actually figured out how to accomplish this seemigly impossible task.
Before I begin, let me just say that if you are working with SQL Server Reporting Services 2008 (SSRS 08) and have (i.e. you have no choice) to use something like Basic auth, you'll only find a world of hurt with the WCF based Service Stubs & IIS. I'm going to blog about the configuration later.
The short answer is as follows:
Connect (e.g. new ReportingService2005() or ReportingService2005SoapClient())
Note: It's easier to use the old (pre-WCF) ASMX service, but not impossible to use the new CF version. The Authentication takes some configuring. There are also some slight syntactic changes between versions.
Find the report history you are looking for, e.g. ReportHistorySnapshot[] history = reportServer.ListReportHistory(#"/Reports/MyHandyReport");
Get the HistoryID from whichever snapshot you want (returned from the ListHistoryReport)
Now, use a ReportViewer to render the historic report, much like you would any other report, e.g.:
ReportViewer rv = new ReportViewer();
rv.ProcessingMode = ProcessingMode.Remote;
rv.ServerReport.ReportServerUrl = new Uri(#"http://localhost/reportserver");
rv.ServerReport.ReportPath = #"/Reports/MyHandyReport";
rv.ServerReport.HistoryId = historyId;
//...snip
byte[] bytes = rv.ServerReport.Render("Excel", null, out mimeType, out encoding, out extension, out streamids, out warnings);
Note: you can also use the second WCF Web Service (ReportExecution2005.asmx?wsdl) as well for Report Execution

Well it has soap and extensibility API, perhaps they can be used?

Related

Database and Dataset data is empty [duplicate]

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?
Thanks for your explanation.
Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.
This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):
Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.
Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).
Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."
Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.
Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.
EDIT: I've blogged about this here:
Bad Habits : Using AttachDBFileName
In case someone had the problem.
When attaching the database with a connection string containing AttachDBFile
with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.
In order to assure the connection to be shareable with other processes
instead use DataBase to specify the database name in your connection string
Example or connection string :
Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30
,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.
By connecting to the data base with AttachDBFile giving the path to the .mdf file
(namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

Generate reports that query data from MS SQL database on Linux/CentOS?

I'm trying FastReport.Mono on Linux (CentOS 7) to see if I can make an app to generate reports. Example Mono app seems to work fine with PDF and JPG export from custom dataset.
Now I need to query data from MS SQL database. I have a sample report that works well under Windows, but fails on Linux:
private static void ReportExportJPG()
{
Report report = new Report();
report.Load(#"sql-report.frx");
report.Prepare(); // <<<--- Error here
...
}
Error message is:
Cant find object MsSqlDataConnection
Feature table says that MS SQL connectivity (nor ODBC, nor many others) is not available in FastReport.Mono. Does this mean it's entirely missing or I should use other ways and provide ready-made connection to FastReport somehow? If so - How?
P.S. Running Windows report generator with MS SQL connection under Wine works well, so I assume connecting to MS SQL from CentOS is somehow viable.
I was able to resolve this by adding the following to my project source:
using FastReport.Data;
using FastReport.Utils;
...
RegisteredObjects.AddConnection(typeof(MsSqlDataConnection));

call webservice with SQL Server 2012

We have a webservice with these methods :
NOCR_Send(datatable personInfo, string code, string username, string password) returns GUID;
NOCR_Get(GUID code, string code, string username, string password) returns DataTable;
I want to consume these methods in sql server. Is it a way to create datatable in TSQL?
SQLCLR isn't really meant for this - it's ok for simple functions that are better done in CLR (like needing to run a RegEx on something for example), but even then it creates dependencies and management issues it shouldn't have to (your DBA shouldn't need to know .NET, your .NET developer shouldn't have to be a DBA, etc.).
What you should do here is create an ADO.NET application that consumes the webservice and then passes the relevant data to SQL server, or consumes data from SQL server and passes the relevant data to your web service. You want to keep your web service abstracted from SQL Server and vice versa - don't try to make SQL Server a WCF client (it will do poorly), just give it the data from a well written WCF client.
In other words: let SQL Server handle data and .NET handle WCF.

file share error if Sql Compact 4 in windows application

I am sorry but I want a final answer about that.
First I used SQL compact 3.5 for long time and it take from me long time to make tables and it is work good per one user application but now I have customer who want to run my soft on 8 computer by local network so I said ok then I try to share data file .sdf on server and use it but I get an error I don't remember it so I am searched on the internet and I saw that I must update to SQL compact 4 so update it and after that I get this Stupid error
I can’t Believe that this data don't support this type of use and it take too long time to make tables and other things on SQL compact database and the my customer will not wait me so what is the Reason
My SQL statement is this:
dt = New SqlCeConnection("Data Source=" & dpaa & "\MoveData.sdf;Encrypt Database=True;Password=123cdswdaas;File Mode=Read Write;Persist Security Info=False")
I think that previous answer is slightly misleading - you are definitely able use SQL Server CE 4.0 with database file located on network share. In fact, I am using this functionality in one of my active projects right now. "File Mode=Exclusive" parameter is not necessary - exclusive mode is the only available mode in such case.
The major drawback of this approach is that only one client is able to read from or write to database file at a given time, due to exclusive locking of entire SDF file. But there a circumstances when it is not possible to have full-featured SQL server in your environment (domain policy etc.). In such case shared database file is the only solution available.
Accessing SQL Compact database .sdf file on a network share by multiple users is not supported. You should use SQL Server Express edition for this. There are also multiple posts on stackoverflow on this subject. The version 3.5 supports opening .sdf file exclusively from a network share but 4.0 does not. But no SQL CE version supports shared access of multiple network users to 1 .sdf file.
But upgrading your application to support both SQL Express and SQL Compact databases could be relatively easy task. It depends on how your application access data. For example using Entity Framework your queries could be generated depending on your actual database connection.
You can also use generic classes DbConnection, DbCommand etc. instead of SqlCeConnection, SqlCeCommand etc. - thus you can change used database type without having to maintain two separate versions of your project.
Download SQL Express 2014 with Tools SQLEXPRWT http://msdn.microsoft.com/cs-cz/evalcenter/dn434042.aspx. (You can eventually use also older versions e.g. 2008) SQL Server has a lot more SQL features and data types than SQL CE, so watch that you use only stuff that is compatible with SQL CE.
In your app.config have you can have two connection strings:
<add name="CompactDBConnection" connectionString="data source=|DataDirectory|\CE.sdf; password=xxxxxx; SSCE:Max Buffer Size=16384; temp file max size=256; ssce:autoshrink threshold=100; ssce:max database size=4091" providerName="System.Data.SqlServerCe.4.0" />
<add name="ExpressDBConnection" connectionString="Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername; Password=myPassword;" providerName="System.Data.SqlClient" />
You can chose then which one to use at the app startup
For creating DbConnection check this C# Retrieving correct DbConnection object by connection string.
Here is a small example of calling stored procedure using DbCommand instead of SqlCeCommand:
DbConnection dbConn = GetConnection(connStr);
DbProviderFactory sqlF = DbProviderFactories.GetFactory(dbConn);
using (DbCommand b2bcmd = sqlF.CreateCommand())
{
DbParameter msg = sqlF.CreateParameter();
msg.ParameterName = "#errorMessage";
msg.Direction = ParameterDirection.Output;
msg.DbType = DbType.String;
msg.Value = string.Empty;
msg.Size = 2048;
b2bcmd.Connection = dbConn;
b2bcmd.CommandType = CommandType.StoredProcedure;
b2bcmd.CommandText = "PB2BImport";
b2bcmd.Parameters.Add(msg);
b2bcmd.ExecuteNonQuery();
result = Convert.IsDBNull(msg.Value) ? "N/A" : (string)msg.Value;
}
I presume you do not use Entity framework - but it would be much easier with it.

How to invoke webservice from SQL Server stored procedure

I would like to know how to use a web service from a SQL Server stored procedure. I have a table in which the columns specify the city and state of the user. I want to pass this address as a parameter to Google Geocoding API web service and get the latitude and longitude.
I have successfully made use of this geocoding api in c#. But now, I want to use it in a stored procedure.
Can any one please suggest how to get this done? Or please provide me any links?
Any help will be appreciated!!
Thanks.
For something like this, you don't need a full web service implementation. You can use SQLCLR (SQL Server's .NET Integration) to submit the request to the URL, get the response back in XML (unless you can find a JSON library that will work without being set to UNSAFE), and then parse that response.
Look at the following MSDN pages:
HttpWebRequest
HttpWebResponse
XmlDocument
To escape the address:
If you are using SQL Server 2005, 2008, or 2008 R2, then use Uri.EscapeDataString as it was available prior to .NET Framework v4.5
If you are using SQL Server 2012, 2014, or newer, then you can use either Uri.EscapeDataString or, if the server has been updated to at least .NET Framework v4.5, then you can alternatively use WebUtility.UrlEncode
According to the Google Geocoding API documentation, the API URI should be formatted similarly to the following:
https://maps.googleapis.com/maps/api/geocode/xml?address={EscapedAddress}&key={API_KEY}
Just submit that with those 2 variables substituted with their proper values via HttpWebRequest, then call HttpWebRequest.GetResponse, then call HttpWebResponse.GetResponseStream. And do not forget to call the Close and Dispose methods of HttpWebResponse (or instantiate it in a using block)!!
Additional notes:
If not already done, you will have to enable (one time) "CLR Integration" at the server level: Enabling CLR Integration
Do not take the easy road and set the database to TRUSTWORTHY ON. Just sign the assembly with a password, then create an asymmetric key in the master database by pointing to your signed DLL, then create a login from that asymmetric key, and finally grant that login the UNSAFE ASSEMBLY permission. Then you can set the assembly WITH PERMISSION_SET = EXTERNAL_ACCESS.
Do not use the SP_OA* procedures as advocated by user3469363. Those OLE Automation procedures have been deprecated since SQL Server 2005 and will (hopefully) be removed someday (hopefully soon). They are also less efficient and less secure than SQLCLR.
Even more notes can be found in my answer to a similar question on DBA.StackExchange: Bringing web service data into SQL server
Omar Frometa has an example on how to do this. go this link
http://www.codeproject.com/Articles/428200/How-to-invoke-a-Web-Service-from-a-Stored-Procedur
In summary, use these extended stored procedures: SP_OACreate and SP_OAMethod to access objects such as MSXML2.ServerXMLHttp.

Resources