I know there are quite a few other posts and articles on this but I have been searching for a solution hours now and nothing has worked for me. I have a query that generates a listing of all SQL Reporting Services (SSRS) reports listed on a given server with their associated parameters and valid values:
;WITH XMLNAMESPACES (
DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition',
'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd --ReportDefinition
)
SELECT
NAME as Name
, PATH as Path
, x.value ('@Name', 'VARCHAR(100)') AS ReportParameterName
, x.value ('DataType[1]', 'VARCHAR(100)') AS DataType
, x.value ('AllowBlank[1]', 'VARCHAR(50)') AS AllowBlank
, x.value ('Prompt[1]', 'VARCHAR(100)') AS Prompt
, x.value ('Hidden[1]', 'VARCHAR(100)') AS Hidden
, x.value ('data(DefaultValue/Values/Value)[1]', 'VARCHAR(100)') AS DefaultValue
, y.value ('Value[1]','VARCHAR(100)') AS VaildValues
, y.value ('Label[1]','VARCHAR(100)') AS VaildValuesLabel
FROM (
SELECT PATH
, NAME
, CAST(CAST(content AS VARBINARY(MAX)) AS XML) AS ReportXML
FROM Catalog
WHERE CONTENT IS NOT NULL AND TYPE = 2
) A
CROSS APPLY ReportXML.nodes('/Report/ReportParameters/ReportParameter') R(x)
OUTER APPLY R.x.nodes('ValidValues/ParameterValues/ParameterValue') P(y)
ORDER BY NAME
This query takes about 4 and a half minutes to run in SSMS. I want to take the results of this query in the form of a C# DataTable, to use as the parameter for a stored procedure that runs on a different server. Unfortunately when running the SQL script through my C# code the takes at least 3 hours to run, assuming it would ever finish at all (gave up after 3 hours).
I know the SET options are different when running from SSMS and from application so, I tried to manually make the settings the same as they are in SSMS. Here is a snippet of the code:
DataSet ds = new DataSet();
string SQL_Script = File.ReadAllText(runRdlQueryFilePath);
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
{
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = SQL_Script;
da.SelectCommand = cmd;
conn.Open();
Console.WriteLine("setting QUOTED_IDENTIFIER on...");
using (SqlCommand comm = new SqlCommand("SET QUOTED_IDENTIFIER ON", conn))
{
comm.ExecuteNonQuery();
}
Console.WriteLine("setting ANSI_NULLS on...");
using (SqlCommand comm = new SqlCommand("SET ANSI_NULLS ON", conn))
{
comm.ExecuteNonQuery();
}
Console.WriteLine("setting ARITHABORT on...");
using (SqlCommand comm = new SqlCommand("SET ARITHABORT ON", conn))
{
comm.ExecuteNonQuery();
}
//this one will not run for some reason but I think it is the default when running from C# client anyways
//using (SqlCommand comm = new SqlCommand("SET CONCAT_NULL_YEILDS_NULL ON", conn))
//{
// comm.ExecuteNonQuery();
//}
Console.WriteLine("setting XACT_ABORT on...");
using (SqlCommand comm = new SqlCommand("SET XACT_ABORT ON", conn))
{
comm.ExecuteNonQuery();
}
Console.WriteLine("setting LOCK_TIMEOUT -1...");
using (SqlCommand comm = new SqlCommand("SET LOCK_TIMEOUT -1", conn))
{
comm.ExecuteNonQuery();
}
Console.WriteLine("Executing get rdl info query, this may take some time...");
da.Fill(ds);
//I have also tried this method of filling the DataSet...
/*
Server server = new Server(new ServerConnection(conn));
//bool queryRan = true;
//read sql file
string script = File.ReadAllText(runRdlQueryFilePath);
Console.WriteLine("Executing get rdl info query, this may take some time...");
ds = server.ConnectionContext.ExecuteWithResults(script);
*/
}
I don't see how parameter sniffing would be an issue here as the query takes no parameters, but I tried putting an
OPTION (RECOMPILE)
on my query just for fun and had no success with this either. Unfortunately I am not the owner of this database and do not have permissions to create a stored procedure on it, so I have not tried converting the query to a stored procedure.
Any ideas what else could be stopping the query from executing efficiently in the application?
Thanks for any help!