当前位置: 首页 > 面试题库 >

在状态字段中获取空值,任何人都可以解释我在做什么错吗?

蒋正平
2023-03-14
问题内容

我想根据情况来确定状态字段,但是我得到的是空值。

Declare @Status NVarchar(20);
Set @Status = Case When Exists ( Select GunSerialNo
                                 From   dbo.ArmouryIssueGun
                                 Where  ModifiedOn != Null
                                        And CreatedOn != Null ) Then 'In Field'
                   When Exists ( Select GunSerialNo
                                 From   dbo.ArmouryIssueGun
                                 Where  ModifiedOn = Null
                                        And CreatedOn != Null ) Then 'In Armory'
              End;
   -- Insert statements for procedure here

Select  (Select BranchName
         From   Branch
         Where  BranchId = gun.BranchId
        ) As BranchName
      , gun.SerialNo As GunSerialNo
      , gun.GunType
      , gun.ModelNo
      , gun.GunId
      , Convert(Varchar(12), aig.CreatedOn, 103) IssueDate
      , Substring(Convert(Varchar(20), aig.CreatedOn, 9), 13, 5) + ' ' + Substring(Convert(Varchar(30), aig.CreatedOn, 9), 25, 2) As IssueTime
      , cl.LicenceHolderName As CarriedBy
      , (Select TypeName
         From   dbo.CommonValues
         Where  ID = aig.Purpose
        ) As Purpose
      , @Status As status
      , Convert(Varchar(12), aig.ModifiedOn, 103) As CollectedDate
      , Substring(Convert(Varchar(20), aig.ModifiedOn, 9), 13, 5) + ' ' + Substring(Convert(Varchar(30), aig.ModifiedOn, 9), 25, 2) As TimeIn
From    dbo.CarryAndUseLicence cl
Join    dbo.Branch b
        On b.BranchId = cl.BranchId
Join    dbo.Gun gun
        On cl.GunSerialNo = gun.SerialNo
Join    dbo.ArmouryIssueGun aig
        On aig.StaffId = cl.StaffId;

问题答案:

您的子查询没有关联子句!他们所做的只是查询查询表中是否有任何一行不为null。

如果您对特定状态感兴趣,则GunSerialNo必须查询该状态,例如:

SELECT
FROM dbo.ArmouryIssueGun
WHERE
   ModifiedOn IS NOT NULL
   AND CreatedOn IS NOT Null
   AND GunSerialNo = @GunSerialNo -- A specific GunSerialNo
;

但是,我怀疑您对 单个 项目的状态不感兴趣。相反,您想知道一堆行的状态。在这种情况下,将 单个
值存储在@Status变量中将无济于事。您需要将其合并到查询中,并将子查询与外部查询相关联,如下所示(请参见Status =表达式):

Select  (Select BranchName
      From   Branch
      Where  BranchId = gun.BranchId
     ) As BranchName
   , gun.SerialNo As GunSerialNo
   , gun.GunType
   , gun.ModelNo
   , gun.GunId
   , Convert(Varchar(12), aig.CreatedOn, 103) IssueDate
   , Substring(Convert(Varchar(20), aig.CreatedOn, 9), 13, 5) + ' ' + Substring(Convert(Varchar(30), aig.CreatedOn, 9), 25, 2) As IssueTime
   , cl.LicenceHolderName As CarriedBy
   , (Select TypeName
      From   dbo.CommonValues
      Where  ID = aig.Purpose
     ) As Purpose
   , Status =
      Case When Exists (
         Select *
         From dbo.ArmouryIssueGun aig
         Where
            gun.SerialNo = aig.GunSerialNo // correlate to outer query
            AND aig.ModifiedOn != Null
            AND aig.CreatedOn != Null
      ) Then 'In Field'
      When Exists (
         Select * 
         From dbo.ArmouryIssueGun aig
         Where
            gun.SerialNo = aig.GunSerialNo // correlate to outer query
            AND aig.ModifiedOn = Null
            AND aig.CreatedOn != Null
      ) Then 'In Armory'
      End
   , Convert(Varchar(12), aig.ModifiedOn, 103) As CollectedDate
   , Substring(Convert(Varchar(20), aig.ModifiedOn, 9), 13, 5) + ' ' + Substring(Convert(Varchar(30), aig.ModifiedOn, 9), 25, 2) As TimeIn
From    dbo.CarryAndUseLicence cl
Join    dbo.Branch b
     On b.BranchId = cl.BranchId
Join    dbo.Gun gun
     On cl.GunSerialNo = gun.SerialNo
Join    dbo.ArmouryIssueGun aig
     On aig.StaffId = cl.StaffId;

另外,请注意这些可能对您有帮助的其他注释:

  • 与进行比较时NULL无法 使用=!=<>。答案将始终是NULL,这既不是错误的,也不是正确的。您无能为力。x.Column != NULL将被视为false,将被视为false NOT (x.Column != NULL)。您必须执行x.Column IS NULLx.Column IS NOT NULLNOT (x.Column IS NULL)

  • 似乎数据库设计可能存在严重的数据一致性错误。用ModifiedOn代理来判断是否检出枪支是 完全不安全的 。该设计假定一条“快乐之路”,在该枪支被检出之前,枪支不能被修改(很可能被违反),并且一旦被修改,它就不能仍然留在军械库中(例如,被检入)。如果您不立即通过某些实际状态栏或其他机制来指示喷枪的当前状态来纠正此问题,则系统可能会遇到 严重 问题。

  • 如果ArmouryIssueGun表与每把枪具有一一对应的关系,那么出了点问题,除非绝对,总是,在每种情况下每把枪只能一次发行的所有情况都是100%可靠。这似乎极不可能。这 可能ArmouryIssueGun真的不是一个历史表,但表示的部分Gun表(如在C#中的部分类),并且因此是正确1- TO-(0或)1.在这种情况下,我的有关使用评论ModifiedOn将绝对不可靠,无法判断枪支是否已送出战场。

  • 如果我怀疑(并且应该是)一对多关系,那么使用相当于历史日志表的值来检测事物的当前状态通常不是最佳设计。可能会犯错误。日志条目可能无法插入。应该有一个规范的地方,每个地方都在同一行中GunSerialNo。使用历史表可以使不知道您在此查询中使用过奇怪的代理依赖关系的以后的人有可能认为仅插入另一ArmoryIssueGun行即可解决问题,但是您的查询假定仅具有一个ModifiedOn值证明它 目前 在现场,而不仅仅是 过去某个时候 的现场。

  • 每个表中的列名都应该相同。你应该 不会 有一个名为一列SerialNo,另一个叫相同的含义GunSerialNo

  • 我可以看到枪的序列号如何为您的数据库提供一个相当不错的自然/业务密钥。但是,我怀疑在某些情况下对于所有表来说,它都不是一个很好的钥匙。序列号多少个字符?一个int仅使用4个字节,但是如果您的序列号是20个字符,那么每一行将占用该序列号5倍的空间。请记住,在每个非聚集索引中都会重复聚集索引列。我不知道您的数据库的大小,但是例如,如果您要创建一个服务于整个国家陆军的数据库,那么理论上可能有数百万个条目!到那时,性能才真正开始变得重要,列占用的空间也变得很大。

  • 两次连接到同一张表不是最佳选择。您可以像上面那样更改上面的查询,以使连接仅发生一次,并且还允许SELECT子句甚至包含找到的最新行中的列:

    OUTER APPLY (
    SELECT TOP 1
       aig.*
    FROM
       dbo.ArmoryIssueGun aig
    WHERE
       gun.SerialNo = aig.GunSerialNo
    ORDER BY
       aig.ModifiedOn DESC
    

    ) aig

  • 也没有理由进行子查询,例如您已经完成的子查询BranchName。它会使查询混乱,并且不一致。相反,请始终使用JOIN:

    LEFT JOIN Branch b
    

    ON gun.BranchId = b.BranchId

然后,您可以简单地b.BranchNameSELECT子句中使用,还可以从Branch表中拉出其他列。根据我的经验,使用这样的子查询会导致某些思考习惯,这些习惯会产生次优的组织且难以理解的查询,有时甚至会对性能产生负面影响(例如,如果您要从Branch表中查找另一列,而您又抛出了另一个子查询,那么您不必要地将获取数据的成本增加了一倍)。



 类似资料:
  • 从Web API 2的模板中,post方法总是这样的: 我不理解这个< code>CreatedAtRoute()方法。有人能给我解释一下吗?

  • 问题内容: 有人可以在hibernate状态下向我解释吗?我很难理解它。 如果可以举一个例子来解释它,那就最棒了,并且它在哪种用例中最适用? 问题答案: 这是Object DB的一个很好的解释。 指定ManyToOne或OneToOne关系属性,该属性提供EmbeddedId主键,EmbeddedId主键内的属性或父实体的简单主键的映射。value元素指定关系属性所对应的组合键中的属性。如果实体的

  • 问题内容: 需要使用一对多和多对一关系。这是我对象中的双向关系,因此我可以从任一方向来回移动。是推荐的解决方法,但是,我听不懂。有人可以解释: 推荐的使用方式是什么? 它解决什么目的? 就我的示例而言,这是带有注释的类: 拥有许多 许多 属于一个 A 航空公司: 航空公司航班: 编辑: 数据库模式: AirlineFlights具有idAirline作为ForeignKey,而Airline没有i

  • 我无法从它告诉我的内容中找到错误: 244错误有点奇怪,因为他说如果我用查询替换路径,我应该使用一个有效的语句,在错误代码中写的是then而不是查询路径。 如果我有<code>IstGeloescht</code>参数,就会出现这个错误。当我移除整个块时,它是好的,但据我所知,它应该是正确的。由于我看到一些错误是隐藏的,只有在我们修复其他错误时才会出现,所以我决定向您展示所有的代码。 路径: /v

  • 问题内容: 我注意到JLS谈论5.1.10捕获转换,但是我不明白它们是什么。 谁能向我解释/举一些例子? 问题答案: 捕获转换旨在使通配符(通用)有用。 假设我们有以下课程: 在我们代码的某个地方, 因为不是原始值,并且因为在“ hindsight”中返回a ,所以编译器知道有一个充当的类型参数。这是针对未知的,因此编译器会擦除未知类型(对于通配符,它​​将替换为),因此返回。 但是如果有的话 编

  • 我使用的是Liferay 6.1 CE版本。我在控制面板的用户实体中添加了自定义属性。我想在create_account中添加这个自定义字段。jsp钩子页。我是这样加的。 之后,我尝试在UserLocalService钩子类中获取这个值,该类扩展了UserLocalServiceWrapper类-(钩子)。我从中找到每个值,但无法获得自定义字段值。 我正试图获得这样的自定义字段值。 但我得到的是空