为产品生命周期创建 SQL Server 视图

Posted

技术标签:

【中文标题】为产品生命周期创建 SQL Server 视图【英文标题】:SQL Server View Creation for Product Lifecycle 【发布时间】:2011-08-15 20:38:38 【问题描述】:

[免责声明]:目前我们运行的是旧版 SQL Server 2000,但我们可以在未来 6 个月左右更新到 SQL Server 2008。

在我们的制造环境中,我有一段很长的 C# 代码来确定以下内容:

    哪个员工“拥有”产品(定义为第一个使用该产品的员工),

    该产品的最终Test_Result 是在压力测试站,并且

    该产品的第一个 Test_Result 是在真空测试站。

所有Test_Result 值(存储在字符串值中)都包含在从旧版 Microsoft Excel 电子表格演变而来的平面文件表中。数据库结构不容易修改,因为公司机器和供应商机器都向它们写入数据。

大约一个月左右,管理层会运行一份报告,显示每个员工拥有多少产品,第一次压力测试是否成功,以及最终是否成功strong>真空测试成功。

目前,我执行此操作的技术全部在来自SQL 代码的SQL 调用中:

SELECT DISTINCT Serial_Number WHERE Date_Time BETWEEN @Date1 AND @Date2

在一个月的时间里,我们可以记录 1500 到 3500 个不同的产品 Serial_Number 值。

对于每个Serial_Number,我创建一个自定义Product 类的实例,该类包含PressureEmployeeVacuumEmployee,两者都初始化为NULL

现在,对于每个Product 实例,我选择所有数据并按Date_Time 字段排序以确定哪个员工首先对产品执行了测试操作。

这方面的SQL类似于下面的准代码:

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"));
      
    
  

这实际上还有很多内容,但它应该能够理解总体思路。

我想做的是创建一个可以驻留在服务器上的视图,它只包含每个Serial_NumberPressure_Test 结果、Pressure_Test 日期、Vacuum_Test 结果的列表,以及Vacuum_Test 日期。

如果我的想法是正确的,这将减少服务器上的工作,因为它将始终保持此视图。此外,视图应该执行得更快......对吧?

那么,我该怎么写这样的视图呢?

如果不是更快,有没有办法在查询运行时获取查询状态?显示Cursor = Cursors.WaitCursor 40 分钟并不能让我对我的申请充满信心。

【问题讨论】:

【参考方案1】:

不是 - 默认情况下,SQL Server 不维护视图 - 视图只是将合并到您的查询中的 SQL 语句片段。这里没有性能提升.....

您可以调查确实“维护”的索引视图,因为它们的数据值存储在磁盘上 - 就像一个表一样。

Improving Performance with Indexed Views Indexed views in SQL Server 2000

他们有很长的要求和限制清单 - 但如果你符合这些要求,这可能会更快 - 以使用更多磁盘空间为代价。你也没有免费的午餐……

【讨论】:

我可以在我们的服务器上调用一个快速查询来查看是否启用了索引?我想是的,但我想先检查一下。 @jp2code:我认为不需要显式启用此功能 - 只要您的视图满足所有必要的要求,它应该可以在任何 SQL Server 上使用【参考方案2】:

如果您想传递参数,存储过程可能比视图更适合您。

CREATE PROCEDURE dbo.myProc
(@SN int)
AS
BEGIN
   SELECT 
      Date_Time, 
      Employee, 
      System_ID, 
      Test_Result,
      CASE WHEN CHARINDEX('Pressure', System_ID) > 0 THEN Employee ELSE '' END as PressureEmployee,
      CASE WHEN CHARINDEX('pass', Test_Result) > 0 THEN 1 ELSE 0 END as VacuumPass
   FROM Production
   WHERE Serial_Number = @SN 
   ORDER BY Date_Time
END

您的 C# 可以正常工作(而不是 sqltext,您将使用 sqlcommand)。

【讨论】:

除了在我的应用程序中减少一点文本之外,这有什么好处吗? @jp2code -- 这取决于。一些优点是 1) 它是可重用的,2) 在一定程度上,您可以随着时间的推移更新您的存储过程,而无需修改/重新发布您的 c# 代码,3) 如果有人为您工作,您可以只给他们存储过程的名称,而不是解释/让他们实现某些逻辑等。另外,虽然我最初没有展示它(我会在几分钟内修改答案),你可以移动你的SELECT 语句的评估逻辑也是如此。

以上是关于为产品生命周期创建 SQL Server 视图的主要内容,如果未能解决你的问题,请参考以下文章

Exchange Server 2007的即将生命周期,您的计划是?

ASP.NET页面生命周期包括哪几个阶段

视图控制器的生命周期(精简)

activity的生命周期(day02)

PLM产品全生命周期管理 - 工艺管理

Vue生命周期的理解