我的一个DB-fields是不是NULL?

时间:2009-06-22 15:15:42

标签: sql select null

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

看起来有点像这样:

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

5 个答案:

答案 0 :(得分:2)

这是我能想到的最清晰的解决方案。您需要为每个数据元素(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

答案 1 :(得分:1)

我修改了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用另一种输出格式说的。

答案 2 :(得分:1)

这是一个简单的查询:

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE COALESCE(t.newFirstName,t.newLastName) IS NOT NULL
       AND t.refID = 1

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

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

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

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE CASE 
           WHEN t.newFirstName IS NOT NULL THEN 1
           WHEN t.newLastName  IS NOT NULL THEN 1
           ELSE NULL
           END IS NOT NULL
       AND t.refID = 1

答案 3 :(得分:0)

此架构是否已定义并正在生产中?如果不是,我强烈建议单独使用某些描述的“更改”表 - 也许使用fieldname,fieldvalue where fieldvalue是sql_variant。

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

答案 4 :(得分:0)

无法测试,但可能:

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