view SqlXmlCommand.ExecuteCommand() on SQL server - c#

I am having an issue where I am looking at a legacy application that is using SqlXmlCommand objects to get data from the database. There is an .xsd file that has the tables that are being used, and what fields, their relationships etc. The issue that we are having is it works most of the time, but not all. I am wondering if there is a way to check what is actually being run on Sql Server. I don't have the SQL profiler installed so that option is out.
the code looks like:
SqlXmlCommand xcmd = new SqlXmlCommand(DataAccess.OleDbConnectionString);
xcmd.CommandType = SqlXmlCommandType.XPath;
xcmd.SchemaPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"myXsd.xsd"));
xcmd.XslPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, String.Format(#"myXsl.xsl", ReportType)));
xcmd.CommandText = "id[#PK=$PK]";
SqlXmlParameter p = xcmd.CreateParameter();
p.Name = "#PK";
p.Value = Id;
using (Stream s = xcmd.ExecuteStream()) { ... }
This blows up at the ExectureStream() with the error:
SQLXML: error loading XML result (XML document must have a top level element.)
We believe that there is some data abnormality that is causing the xml to not generate properly, and that is why we want to see what is exactly run.
Cheers

You can try the below two queries, you might need to tweak it a little, but to give you an idea, the first gives you a list of all requests, and the second will give you the detail of the request by its request id (session_id)
SELECT *
FROM sys.dm_exec_requests
DBCC INPUTBUFFER (12345)
Although I would personally rather try and debug the C# app first and view what's being sent over to the server from the VS debugger before bothering with checking what's being run on SQL Server
Also, DBCC INPUTBUFFER might give you something like EXECUTE dbo.MyStoredProc 'params...', to dig deeper, or otherwise a more straightforward query, you can run this
SELECT r.session_id, r.[status], r.command, t.[text]
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.[sql_handle]) t

Related

Oracle parameter with Dapper issue

I am struggling with using ORACLE parameters via DAPPER. The error message received is "ORA-00942: table or view does not exist".
However the code works without the parameter, and I suspect that this is a simple Oracle parameter syntax issue. The code follows:
public List<ForecastData>GetByFiscalYear(string fiscalYear)
{
List<ForecastData> queryResults = new List<ForecastData>();
String sqlQuery = #"SELECT RES.FISCALYEAR year FROM RESOURCE_AVAILABILITY RES WHERE RES.FISCALYEAR = :p_fiscalYear";
using (var oraCon = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Oracle_HRZD"].ToString()))
{
oraCon.Open();
queryResults = oraCon.Query<ForecastData>(sqlQuery, new { p_fiscalYear = fiscalYear }).ToList();
}
return new List<ForecastData>(queryResults);
}
Any assistance will be greatly appreciated...
Usually, ORA-00942 is exactly what it says, it can't find the table/view (RESOURCE_AVAILABILITY) you are selecting from. So it's not in the schema for the user you log on as or the user has not been granted SELECT on the table/view if it's another schema.
But you say that if you remove WHERE RES.FISCAL_YEAR :p_fiscalyear, then it works. So it seems like you have select permissions on the table. Do you mean remove the whole where selection or have you tested enter a fixed string, as in WHERE RES.FISCAL_YEAR='2016'?
My other top tip is to run Wireshark and look at what really is sent to the database, usually you connect on port 1521 filter on that.
The answer was to use the fully-qualified database-object name, including the schema. Thanks for your assistance.

SqlDataAdapter.Fill populate no rows in given DataTable

all.
Here is my code.
private void FillData(DataTable data, FilterModel filter){
var cmdStr = MySqlCmdGenerator.Generate(filter);
using (var cmd = new SqlCommand(cmdStr, connection_))
using (var da = new SqlDataAdapter(cmd)){
da.Fill(data);
}
}
public DataTable GetData(IEnumerable<FilterModel> filters){
var data = new DataTable("mydata");
foreach (var filter in filters){
FillData(data);
}
return data;
}
It's a very simple code, which just use SqlDataAdapter to Fill datatable according to the filters.
The problem is that sometimes GetData method returns empty datatable.
First I execute the generated query on SQL Server Management Studio, and it returns correct result (it contains about 100,000 records).
Then I have used Sql Server Profiler to profile what happened in server, and get some errors:
Sort Warnings
RPC:Completed (TextData: Query with a given filter)
Hash Warning
Sort Warnings
RPC:Completed (TextData: Query with a given filter)
User Error Message (TextData: The statement has been terminated.)
Attention
Audit Logout
RPC:Completed (TextData: sp_reset_connection)
(occurs in this order)
After google the error but I could not figure out what is exactly happen in server and application.
Any advice will be appreciated.
Thanks!
Differences between results from a .NET application and those from SQL Server Management Studio are often due to different configuration of ANSI settings for the SQL Server connection.
This assumes you've eliminated the obvious error causes, e.g. you're inadvertently connection to different databases from the two environments.
You can see the settings used by SQL Server Management Studio in Tools / Options / Query Execution / SQL Server / ANSI. On my installation they default to:
SET ANSI_NULL_DFLT_ON ON
SET ANSI_PADDING ON
SET ANSI_NULLS ON
I suggest you try switching these OFF one by one in Management Studio to attempt to reproduce the configuration used by .NET. Once you understand what's happening, you can do one of:
Add SET statements to your .NET query
Modify your query so it isn't dependent on these settings (may need to add ISNULL or explicit tests for NULL).

How to remotely collect windows performance counters through sql server

I'd like my application (which is deployed to thousands of locations) to be able to monitor its own environment, in particular the sql server box. When the SQL Server is local, this is easy to do as I can use the System.Diagnostics library and collect the windows performance counters through that. When the SQL server is remote however I have a problem because I cannot guarantee that my c# application (a windows service in this case) has access to the remote sql server machine OTHER THAN the fact that I know it can access the SQL Server.
Any ideas on how I can collect the windows performance counters off that machine through SQL?
One way I've thought of is to use SQL CLR, but it seems to require UNSAFE access, which I'm pretty sure I don't want.
Thanks
Mark as you stated in the comments
"i can't guarantee that I will have the proper privileges"
Either you have to write some kind of functionality into your installer that is going to make sure you have the proper privileges (maybe won't install without admin setting privileges) for remote perf. counters access.
You didn't state exactly what you were trying to monitor, however, might I suggest using the built int SQL Server Dynamic Management Views (DMV's)
MSDN
Good Articles Videos
Very Useful Examples
these have become very robust in recent releases of SQL server and allow you to monitor the majority of the stats you would work with in perfmon (CPU, IO, MEMORY, many more). Perhaps not as much granularity as perfmon but usually I find them to be more useful then perfmon nowadays for quick pertinent data. And as long as your connection string user has admin rights you don't have to worry about server privileges. And this functionality is allready built into sql-server Give it a look see.
Edit ...
#Mark Here are some DMV scripts I use to get IO time on a database, not as exact as PerfMon however it allows you to focus in on a specific database file.
Check out the "dm_io_virtual_file_stats" DMV
select
read_stall_ms = case when num_of_reads = 0 then 0 else (io_stall_read_ms/num_of_reads) end,
write_stall_ms = case when io_stall_write_ms = 0 then 0 else (io_stall_write_ms/num_of_writes) end,
total_stall_ms = case when (num_of_reads = 0 and num_of_writes = 0) then 0 else (io_stall/(num_of_reads + num_of_writes)) end,
db = db_name(vfs.database_id),
mf.physical_name,
vfs.*
from sys.dm_io_virtual_file_stats(null, null) as vfs
join sys.master_files as mf on vfs.database_id = mf.database_id and vfs.file_id = mf.file_id
order by total_stall_ms desc
select m.database_id,
db_name(m.database_id) as database_name,
m.file_id,
m.name as file_name,
m.physical_name,
m.type_desc,
fs.num_of_reads,
fs.num_of_bytes_read,
fs.io_stall_read_ms,
fs.num_of_writes,
fs.num_of_bytes_written,
fs.io_stall_write_ms
from sys.dm_io_virtual_file_stats(NULL, NULL) fs
join sys.master_files m on fs.database_id = m.database_id and fs.file_id = m.file_id
Something a little fancier ...
select db_name(d.database_id) as database_name,
quotename(object_schema_name(d.object_id, d.database_id)) + N'.' + quotename(object_name(d.object_id, d.database_id)) as object_name,
d.database_id,
d.object_id,
d.page_io_latch_wait_count,
d.page_io_latch_wait_in_ms,
d.range_scans,
d.index_lookups,
case when mid.database_id is null then 'N' else 'Y' end as missing_index_identified
from (select
database_id,
object_id,
row_number() over (partition by database_id order by sum(page_io_latch_wait_in_ms) desc) as row_number,
sum(page_io_latch_wait_count) as page_io_latch_wait_count,
sum(page_io_latch_wait_in_ms) as page_io_latch_wait_in_ms,
sum(range_scan_count) as range_scans,
sum(singleton_lookup_count) as index_lookups
from sys.dm_db_index_operational_stats(NULL, NULL, NULL, NULL)
where page_io_latch_wait_count > 0
group by database_id, object_id ) as d
left join (select distinct database_id, object_id from sys.dm_db_missing_index_details) as mid on mid.database_id = d.database_id and mid.object_id = d.object_id
If you sign your assembly, you can create a login from the assembly, grant it the server-level permission to run unsafe assemblies, and create the assembly from the dll. This allows you to run unsafe assemblies w/o having to turn the trustworthy flag on the database on.
I would think you need something more robust than self-rolled SQL CLR for this. MS has a tool for precisly this called SCOM.
I have had very good results in envs with 50 servers.
You collect loads of configurable data with built in point in time reports, data warehousing and alerts.
good wikipedia article
technet

SQL Server perform backup with C#

I've investigated the possibilities of creating database backups through SMO with C#.
The task is quite easy and code straightforward. I've got only one question: how can I check if the backup was really created?
SqlBackup.SqlBackup method returns no parameters and I don't even know if it throws any exceptions. (the only thing that I know is that it is blocking, because there's also SqlBackupAsync method)
I would appreciate any help.
you can and its very possible to do what you asked for,
but doing the backup it self using SMO its not very hard, but the hard part is managing the backup and the restore.
it would be hard to put all the code here, but its wont fit. so I will try my best to put the lines you need.
SqlBackup.SqlBackup doesn't return any value, its a void function.
but it takes one parameter which is "Server", try out the following code:
Server srvSql;
//Connect to Server using your authentication method and load the databases in srvSql
// THEN
Backup bkpDatabase = new Backup();
bkpDatabase.Action = BackupActionType.Database;
bkpDatabase.Incremental = true; // will take an incemental backup
bkpDatabase.Incremental = false; // will take a Full backup
bkpDatabase.Database = "your DB name";
BackupDeviceItem bDevice = new BackupDeviceItem("Backup.bak", DeviceType.File);
bkpDatabase.Devices.Add(bDevice );
bkpDatabase.PercentCompleteNotification = 1;// this for progress
bkpDatabase.SqlBackup(srvSql);
bkpDatabase.Devices.Clear();
I've investigated the problem using Reflector.NET (I suppose this is legal since RedGate is Ms Gold Certified Partner and Reflector.NET opens .NET libraries out of the box). As I found out the method throws two types of exceptions:
FailedOperationException - in most cases, other exceptions are "translated" (I suppose translating means creating new FailedOperationException and setting InnerException to what was actually thrown)
UnsupportedVersionException - in one case when log truncation is set to TruncateOnly and server major version is more or equal to 10 (which is sql server 2008?)
This solves my problem partially, because I'm not 100% sure that if something goes wrong those exceptions will actually be thrown.

How might I set up data plumbing for Silverlight to MySQL in my situation?

In short: What is a good method for setting up read-only data access from Silverlight to a MySQL database?
Here are the details of my situation:
I'm currently trying to set up a Silverlight application to present data from a MySQL database. Currently, I need to set-up read-only access to the MySQL database (I may set up other tables for complete CRUD functionality at a later, date, but for these particular tables, I'm only ever going to be concerned with the retrieve aspect).
I tried setting it up using RIA Services (CTP July 2009) with Entity Framework, but I had trouble debugging it and ended up trying to recompile the source code from the MySQL ADO.NET connector in order to install custom DLLs into the GAC. I wasn't able to get any of this stuff to work correctly.
My problem was that I had date values stored as 0000-00-00 in lots of my MySQL tables. The MySQL ADO.NET Connector throws an exception everytime it tries to bring down a row with an invalid date in it. I would try to recompile the connector (see links above), but that's feeling very much like a hack. I would try to update the values in the MySQL database to be within the appropriate spec for dates, but our IT manager (and effectively our DBA) does not want to do it.
I don't mind learning to work with LINQ (LINQ-to-what?), but I want to avoid concatenating my own strings of SQL commands. Because of the Date restrictions, I need a way to specify Case When orders.OrderDate = '0000-00-00' Then '0001-01-01' Else orders.OrderDate End for pretty much every date instance.
I'm especially interested to hear from folks who have worked with .NET and MySQL together. What will work in my situation?
Why has no one suggested using a ORM to hide the mySQL details? Both NHibernate and Subsonic support mySQL. Both are very customisable in how they interact with the database and should allow you to cater for malformed dates.
By using an ORM your data objects are now POCOs, and you can use whatever you want to get the data to the Silverlight client. Vanilla web services or WCF should be fine. RIA services if you want to try out the bleeding edge.
IMHO, this will be simpler than setting up a mysql->php->xml->asp.net->silverlight chain.
My problem was that I had date values stored as 0000-00-00 in lots of my MySQL tables.
Can you just write Select NullIf( SomeDate, '0000-00-00') As SomeDate From SomeTable in your SQL queries? I don't know MySQL, but that's what I would do in T-SQL.
Here is what I did for a similar problem I was facing.
I used php to get data from the MySQL database and turned it into an XML file. I called that file from my silverlight app and used LINQtoXML to parse the data and make it available in my XAML controls. I am not a programmer by trade so maybe there is a better way to do it but this works for my app. Hope this helps. LINQ ROCKS!
Here is a portion of the code:
< ?php
header("Content-type: text/xml");
$grb_hostname = "host";
$grb_database = "dbName";
$grb_username = "dbUser";
$grb_password = "dbPwd";
$grb = mysql_connect($grb_hostname, $grb_username, $grb_password);
mysql_select_db($grb_database, $grb);
$results = mysql_query("SELECT * FROM bursts ORDER BY bursts.id DESC");
$xmlOutput = "<?xml version=\"1.0\"?>\n";
$xmlOutput .= "<grbs>\n";
while($row = mysql_fetch_array($results)) {
$xmlOutput .= "\t<grb id=\"".$row['id']."\" trigger=\"".$row['trigger']."\">\n";
$xmlOutput .= "\t\t<grb_id>".$row['grb_id']."</grb_id>\n";
$xmlOutput .= "\t\t<burst_ra>".$row['burst_ra']."</burst_ra>\n";
$xmlOutput .= "\t\t<burst_dec>".$row['burst_dec']."</burst_dec>\n";
$xmlOutput .= "\t</grb>\n";
}
$xmlOutput .= " < /grbs>"; // no space before /
echo $xmlOutput;
?>
then in my Silverlight I have the following:
private void LoadGrbs()
{
WebClient grbXmlFile = new WebClient();
// Make sure the crossdomainpolicy.xml file exists on the remote server.
grbXmlFile.DownloadStringAsync(new Uri("url_xml_generating_php_file", UriKind.Absolute));
grbXmlFile.DownloadStringCompleted += new DownloadStringCompletedEventHandler(grbsXmlLoaded);
}
private void grbsXmlLoaded(object sender, DownloadStringCompletedEventArgs e)
{
processGrbXml(e.Result);
}
private void processGrbXml(string grbData)
{
XDocument grbs = XDocument.Parse(grbData);
var query = from g in grbs.Descendants("grb")
select new
{
grbId = (string)g.Element("grb_id"),
grbDec = (string)g.Element("burst_dec")
};
foreach (var grb in query)
{
grbListbox.Items.Add(grb.grbId);
}
}
grbListbox is a Listbox control in my Silverlight app.
You should use RIA Services, the newest version came out last week, and it's included in the silverlight 4 beta now.
http://silverlight.net/getstarted/silverlight-4-beta/
You don't have to use the entity framework with RIA, there are other options. We do, but we use SQL Server so that might not be your favorite.
They have changed the errors some in the new RIA Stuff, so I'd recommend taking a 2nd look. Here's Brad Abrams' example from last week:
http://microsoftpdc.com/Sessions/CL21
Finally, if you're having a lot of trouble debugging, you could take a look at Fiddler. It's a program that watches the traffic and it can display you the errors you're having in a more obvious fashion.

Categories