如何检测 SELECT 中的列是不是可以为空?

Posted

技术标签:

【中文标题】如何检测 SELECT 中的列是不是可以为空?【英文标题】:How to detect if column in SELECT can be null?如何检测 SELECT 中的列是否可以为空? 【发布时间】:2015-05-14 14:11:58 【问题描述】:

我在设计时使用 DacFx 创建从 SSDT 数据库项目中的 sql 文件生成的 C# 数据层。看看我的SqlSharpener project on Github 看看我在说什么。

我正在生成代表从存储过程的 SELECT 语句返回的行的 DTO 对象。为了确定 DTO 上的属性是否应该是可为空的值类型,我正在检查该列在它来自的表中是否可以为空。如果您对它的外观感到好奇,这里是代码。 (这里的tSqlObject是存储过程的TSqlObject的实例)

var bodyColumnTypes = tSqlObject.GetReferenced(dac.Procedure.BodyDependencies)
    .Where(x => x.ObjectType.Name == "Column")
    .GroupBy(bd => string.Join(".", bd.Name.Parts))
    .Select(grp => grp.First())
    .ToDictionary(
        key => string.Join(".", key.Name.Parts),
        val => new DataType
        
            Map = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, val.GetReferenced(dac.Column.DataType).First().Name.Parts.Last()),
            Nullable = dac.Column.Nullable.GetValue<bool>(val)
        ,
        StringComparer.InvariantCultureIgnoreCase);

问题是我没有考虑左外连接或右外连接,这也可能使值为空。

如何确定 SELECT 语句中的列是否可以为空?或者,如果这个问题过于宽泛,我如何确定该列是否来自一个左外连接的表?

【问题讨论】:

老实说,我认为您永远无法做到 100% 正确。对于仅选择语句,您可能可以,但由于这是一个数据层,您将如何处理存储过程?如果这些过程包含对其他过程的调用或包含动态 sql 怎么办? 表格不代表不同的对象吗?如果是这样,那么您的选择不应该返回 2 个单独的对象(其中一个可以为空)而不是一个代表查询中所有字段的对象吗? @SeanLange,你提出了一些好的观点。我还没有测试过这些场景。我想我可以解决嵌套的过程问题。动态 sql 可能会更棘手。但我认为我不需要解决所有可能的情况,我的项目才能对人们有用。我允许通过使我的所有类部分化来扩展它,并且我将virtual 添加到所有方法中。这可能是某些人可能不得不手动编写代码的例外情况之一,但他们仍然可以使用生成的其余代码。 @KyleW,我想我按照你的意思说,但即使我确实更改了实现以按它们来自的表将列分组为对象,问题仍然是如何确定是否这些表是否保持连接,因为我仍然需要知道是否要实例化对象,不是吗? @adam0101 好吧,如果表中需要一个列并且在结果集中为空(并且该表中的所有列都为空),那么该对象应该为空 【参考方案1】:

我想我找到了答案。给定 SELECT 语句的 QuerySpecification,我可以使用以下方法获取连接列表:

var joins = querySpecification.FromClause.TableReferences.OfType<QualifiedJoin>();

每个 QualifiedJoin 对象都有一个 QualifiedJoinType 属性,该属性是一个枚举,将设置为 Inner、LeftOuter、RightOuter 或 FullOuter。

【讨论】:

以上是关于如何检测 SELECT 中的列是不是可以为空?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测文件夹是不是为空(Windows 批处理文件)?

检测图像像素的列或行是不是为线

django表如何检测表是不是为空

检测 pandas.DataFrame 中的列是不是是分类的有啥好的启发式方法?

如何检测 Vue $router.back() 是不是已完成,而不是历史堆栈为空的情况?

如何检测变量是不是为数组