使用列级WHERE子句更新多列中的所有SQL NULL值?

时间:2010-10-15 02:02:47

标签: sql sql-server tsql sql-server-2005 sql-update

我们有一个包含大量宽表(每个40-80列)的数据库,并且发现了一个将NULL值引入大约500条记录的错误。 NULL值可以出现在任何列中(都是整数列,请参见下图)但这些NULL值导致我们的报告系统之一无法轻易更改。我们需要用特定的静态值(在本例中为99)替换NULL值,但由于这个更改必须基于每列超过250个不同的列,我宁愿不编写更新每个列的单个TSQL脚本一个人。

我的大脑现在太过于思考一个聪明的解决方案,所以我的问题是如何使用简单易读的SQL查询在表(或更好的多个表)上的所有列上执行此任务。我可以使用WHERE (Answer_1 IS NULL) OR (Answer_2 IS NULL) OR ...链甚至每个表的AdministrationID编号轻松地隔离记录,但是当更新为where子句是每行而不是每列时,这个技巧将不起作用。有什么建议吗?

以下示例查询显示了4个不同表中的一些记录: Sample

4 个答案:

答案 0 :(得分:21)

没有任何约定 - 如果你只想处理各列为NULL的记录,你需要使用:

WHERE Answer_1 IS NULL 
   OR Answer_2 IS NULL 
   OR ...

但你可以在UPDATE语句中使用它:

UPDATE YOUR_TABLE
   SET col1 = COALESCE(col1, 99),
       col2 = COALESCE(col2, 99),
       col3 = ...

逻辑是,只有当列值为NULL时,该值才会更新为99,因为COALESCE的工作原理 - 返回第一个非NULL值(处理从左到右提供的列表)。

答案 1 :(得分:4)

因为你必须在所有地方这样做我写了一些javascript来帮助你构建sql。将其剪切并粘贴到您的浏览器地址栏中以获取您的sql。

javascript:sql='update your table set ';x=0;while(x <= 40){sql += 'answer_'+x+ ' = coalesce(answer_'+x+',99),\n';x++;};alert(sql);

答案 2 :(得分:3)

只需轮询每个表的sys.columns表并创建一些动态的sql ......这是一种蛮力,但它可以让你不必编写所有的t-sql。

例如:

DECLARE @TABLENAME AS VARCHAR(255)

SET @TABLENAME = 'ReplaceWithYourTableName'

SELECT 'UPDATE ' + @TableName  + ' SET ' + CAST(Name AS VARCHAR(255)) + ' = 99 
 WHERE ' + CAST(Name AS VARCHAR(255)) + ' IS NULL'
FROM sys.columns 
WHERE object_id = OBJECT_ID(@TABLENAME)
    AND system_type_id = 56 -- int's only

答案 3 :(得分:2)

我不喜欢为了报告而操纵数据本身的想法。如果您将NULL值更改为99只是为了使报告更容易,那么我认为数据已损坏。如果除了报告之外还有其他消费者需要真实数据会怎样?

我宁愿为报告编写一个智能查询。例如,如果使用ISNULL(columnname,99),只要列值为NULL,它就会返回99.