[Disclaimer]: Currently we are running older SQL Server 2000, but we could update to SQL Server 2008 within the next 6 months or so.
Within our Manufacturing Environment, I have a very long piece of C# code to determine the following:
-
Which Employee “owns” the product (defined as first Employee that works on it),
-
What that product’s eventual
Test_Resultis at a Pressure Test station, and -
What that Product’s first
Test_Resultis at a Vacuum Test station.
All Test_Result values (stored in string values) are contained in a flat file table that evolved from an older Microsoft Excel spreadsheet. The database structure can not be easily modified because company machines and vendor machines alike write data to them.
Once a month or so, Management runs a report to display how many products each Employee owns, if the first Pressure Test was a success, and if an eventual Vacuum Test was a success.
My technique for doing this, currently, is all in SQL calls from C# code:
SELECT DISTINCT Serial_Number WHERE Date_Time BETWEEN @Date1 AND @Date2
During a month’s time, we could log anywhere from 1500 to 3500 different product Serial_Number values.
For each Serial_Number, I create an instance of a custom Product class that contains a PressureEmployee and a VacuumEmployee, both initialized to NULL.
- Now, for each of these
Productinstances, I select all the data and order by theDate_Timefield to determine which Employee performed the test actions first on a product.
The SQL for this is similar to the following quasi-code:
string sqlText = "SELECT Date_Time, Employee, System_ID, Test_Result " +
"FROM Production " +
"WHERE Serial_Number=@SN ORDER BY Date_Time";
using (SqlCommand cmd = new SqlCommand(sqlText, new SqlConnection(connStr))) {
cmd.Parameters.Add("@SN", SqlDbType.NVarChar, 20);
cmd.Connection.Open();
foreach (var item in productList) {
cmd.Parameters["@SN"].Value = item;
SqlDataReader r = cmd.ExecuteReader();
while (r.Read()) {
string systemId = r["System_ID"].ToString();
string testResult = r["Test_Result"].ToString();
if (-1 < systemId.IndexOf("pressure")) {
if (String.IsNullOrEmpty(item.PressureEmployee)) {
item.PressureEmployee = r["Employee"].ToString();
}
// check that product ever passes
if (-1 < testResult.IndexOf("pass")) {
item.VacuumPass = true;
}
}
if ((-1 < systemId.IndexOf("vacuum")) &&
String.IsNullOrEmpty(item.VacuumEmployee)) {
item.VacuumEmployee = r["Employee"].ToString();
// product passes 1st time
item.VacuumPass = (-1 < testResult.IndexOf("pass"));
}
}
}
}
There is actually a lot more to this, but it should get the general idea across.
What I’d like to do is create a view that can reside on the Server that simply contains a list of each Serial_Number, the Pressure_Test result, the Pressure_Test date, the Vacuum_Test result, and the Vacuum_Test date.
If my thinking is correct, this would present less work on the Server because it would maintain this view at all times. Further, the view should execute much faster …right?
So, how would I write such a view?
If it is not faster, is there any way to get the status of the query while it is running? Displaying Cursor = Cursors.WaitCursor for 40 minutes does not instill much confidence in my application.
Not really – by default, views aren’t maintained by SQL Server – views are just SQL statement fragments that will be incorporated into your query. No performance gain here…..
You could investigate indexed views which are indeed “maintained” in that their data values are stored on disk – just like a table.
They have a long laundry list of requirements and limitations – but if you match those, this could be quite a bit faster – at the price of using more disk space. You don’t get any free lunches here, either …