【问题标题】:Is one of my DB-fields NOT NULL?我的数据库字段之一不为空吗?
【发布时间】:2009-06-22 15:15:41
【问题描述】:

我必须处理一个表,其中有一组字段,每个字段后跟第二个字段,该字段将保存建议的新值,直到确认此更改。

看起来有点像这样:

refID    field1    newField1    field2    newField2   ... 

refID 是链接到主表的 ID 值。主表中的一行在我的明细表中可以有 n 行。数据类型包括整数、字符串和日期时间。

现在,我希望有一个查询告诉我,给定一个 refID,如果在详细信息表中有任何建议的更改。

我正在玩一些 UNION 选择,使用 COALESCE() 和 ISNULL() ......但所有这些尝试充其量看起来有点奇怪。数据库是 MS-SQL-Server 2005。

为了澄清我的问题:

--this is a simplification of the details table in question
CREATE TABLE [dbo].[TEST_TABLE](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [refID] [int] NOT NULL,
    [firstName] [varchar](50) NULL,
    [newFirstName] [varchar](50) NULL,
    [lastName] [varchar](50) NULL,
    [newLastName] [varchar](50) NULL
)

--here we insert a detail row ... one of many that might exist for the master table (e.g. data about the company)
insert into TEST_TABLE(refID, firstName, lastName) values(666, 'Bill', 'Ballmer')
--this is what happens when a user saves a suggested change
update TEST_TABLE SET newLastName = 'Gates' where ID = 1
--and this is what happens when this suggestion is accepted by a second user
update TEST_TABLE set lastName=newLastName, newLastName = NULL where ID = 1

【问题讨论】:

  • 您可以为小样本发布一些 DDL 吗?我不清楚你到底想要什么。

标签: sql select null


【解决方案1】:

这是我能想到的最干净的解决方案。您需要为每个数据元素(col1、col2 等)重复逻辑:

DECLARE @RefID int, @Changes bit

SET @Changes = 0 --No changes by default

SET @RefID = 42 --Your RefID

IF EXISTS(SELECT * FROM MyDetailTable
          WHERE RefID = @RefID
          AND (
          (Col1 IS NULL AND NewCol1 IS NOT NULL)
          OR 
          (Col1 IS NOT NULL AND NewCol1 IS NULL)
          OR
          (Col1 <> Col2)
          ))
   SET @Changes = 1

【讨论】:

    【解决方案2】:

    我修改了 randolphos 溶液。

     select 
            refID ,
            case when 
                newField1 is not null or
                newField2 is not null or
                ...
            then 1 else 0 end  haschanged
        from myTable
        where refID = @refID
    

    更新:基本上是 Aron Aalton 所说的另一种输出格式。

    【讨论】:

      【解决方案3】:

      这是一个简单的查询:

      SELECT TOP 1 1 找到 FROM [dbo].[TEST_TABLE] t COALESCE(t.newFirstName,t.newLastName) 不为空 AND t.refID = 1

      如果对给定的refID 有任何建议的更改,此查询将返回一行(基于您问题中的示例。)

      当然,对于您的实际表格,您需要在 COALESCE 函数中将每个 'newValue' 列作为参数列出。 (在合并列表中,我建议将任何非 VARCHAR 显式转换为 VARCHAR,以明确列表中的每个表达式都是相同的数据类型。

      如果您更喜欢使用 CASE 表达式而不是 COALESCE:

      SELECT TOP 1 1 找到 FROM [dbo].[TEST_TABLE] t 案例 当 t.newFirstName 不为 NULL THEN 1 当 t.newLastName 不为 NULL THEN 1 否则为空 结束不为空 AND t.refID = 1

      【讨论】:

        【解决方案4】:

        此架构是否已定义并已投入生产?如果不是,我强烈建议有一个单独的“更改”表,其中包含一些描述 - 可能使用字段名、字段值,其中字段值是 sql_variant。

        我认为当值被“接受”(我假设为空)时,您现有的结构看起来不会很好,尤其是因为您不会使用这种方法保留任何审计历史记录。

        【讨论】:

        • 我不会想出这样的设计。 :) 它已投入生产多年,现在无需重新设计结构即可实现一些附加功能。
        【解决方案5】:

        无法测试,但也许:

        select (field1 is not null and field2 is not null) as ChangesMade where refID = @id
        

        【讨论】:

        • 不幸的是,这不起作用:(我收到一条错误消息:“关键字'is'附近的语法不正确。”
        • SQL 服务器不允许你用布尔值做一些事情。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 2016-06-26
        • 1970-01-01
        相关资源
        最近更新 更多