我的数据库字段之一不为空吗?

发布于 2024-07-25 08:24:45 字数 1218 浏览 3 评论 0原文

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

它看起来有点像这样:

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

I have to deal with a table where there is a set of fields each followed by a second field that will hold a suggested new value until this change is confirmed.

It looks a little like this:

refID    field1    newField1    field2    newField2   ... 

refID is an ID value that links to a master table. One row in the master table can have n rows in my detail table. The data-types include ints, strings and dateTimes.

Now, i'm looking to have a query that tells me, given a refID, if there are any suggested changes in the detail table.

I was playing around a little with some UNION selects, with COALESCE() and ISNULL() ... but all those attempts looked a little weird at best. The DB is MS-SQL-Server 2005.

For clarification of my problem:

--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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

愿与i 2024-08-01 08:24:45

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

This is the cleanest solution I can think of off the top of my head. You'd need to repeat the logic for each data element (col1, col2, etc):

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
空袭的梦i 2024-08-01 08:24:45

我修改了兰道磷溶液。

 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

更新:基本上是阿伦·阿尔顿以另一种输出格式所说的。

I modified randolphos solution.

 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

Update: basically what Aron Aalton said in another output format.

小忆控 2024-08-01 08:24:45

这是一个简单的查询:

    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 有任何建议的更改(基于您问题中的示例),此查询将返回一行。

当然,对于您的实际表,您需要将每个 '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

Here's a simple query:

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

This query will return a single row if there are any proposed changes for a given refID (based on the example in your question.)

For your actual table of course, you'd need to list each of the 'newValue' columns as arguments in the COALESCE function. (In the coalesce list, I recommend explicitly casting any non-VARCHAR to VARCHAR, just to make it clear that every expression in the list is of the same data type.

If you prefer to use a CASE expression rather than 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
孤凫 2024-08-01 08:24:45

该模式是否已经定义并投入生产? 如果没有,我强烈建议有一个单独的“更改”表来描述 - 可能使用 fieldname、fieldvalue,其中 fieldvalue 是 sql_variant。

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

Is this schema already defined and in production? If not I would strongly recommend having a separate 'changes' table of some description - maybe use fieldname, fieldvalue where fieldvalue is a sql_variant.

I don't think your existing structure is going to look nice when values are 'accepted' (null'd I assume) especially as you won't retain any auditing history with this approach.

万劫不复 2024-08-01 08:24:45

无法测试这一点,但也许:

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

Can't test this, but perhaps:

select (field1 is not null and field2 is not null) as ChangesMade where refID = @id
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文