栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

如果您对特定状态感兴趣,则

GunSerialNo
必须查询该状态,例如:

SELECtFROM dbo.ArmouryIssueGunWHERe   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 TimeInFrom    dbo.CarryAndUseLicence clJoin    dbo.Branch b     On b.BranchId = cl.BranchIdJoin    dbo.Gun gun     On cl.GunSerialNo = gun.SerialNoJoin    dbo.ArmouryIssueGun aig     On aig.StaffId = cl.StaffId;

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

  • 与进行比较时

    NULL
    无法 使用
    =
    !=
    <>
    。答案将始终是
    NULL
    ,这既不是错误的,也不是正确的。您无能为力。
    x.Column != NULL
    将被视为false,将被视为false
    NOT (x.Column != NULL)
    。您必须执行
    x.Column IS NULL
    x.Column IS NOT NULL
    NOT (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 aigWHERe   gun.SerialNo = aig.GunSerialNoORDER BY   aig.ModifiedOn DESC

    ) aig

  • 也没有理由进行子查询,例如您已经完成的子查询

    BranchName
    。它会使查询混乱,并且不一致。相反,请始终使用JOIN:

    LEFT JOIN Branch b

    ON gun.BranchId = b.BranchId

然后,您可以简单地

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



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/514635.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号