尝试在sql server中将'NULL'的所有字符串值更新为NULL

时间:2013-01-24 21:50:09

标签: sql sql-server

我有一个从csv文件导入的数据库表,其中包含NULL,因此当导入它而不是字段为NULL时,它们包含字符串值'NULL'

CSV文件很大,可以在文本编辑器中打开以编辑所有NULL,所以我试图创建一个SQL查询来更新表的每一列。

到目前为止,我有这个

Alter PROCEDURE [dbo].[sp_fixnulls]
     @column nvarchar(100) 
AS
BEGIN
     SET NOCOUNT ON;
     UPDATE my_table
     SET @column=''
     WHERE @column = 'NULL'
END 

---------------

sp_fixnulls (SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME  ='my_table')

但这不起作用。我收到错误消息

  

Msg 201,Level 16,State 4,Procedure sp_fixnulls,Line 0
  过程或函数'sp_fixnulls'需要参数'@column',这是未提供的。

2 个答案:

答案 0 :(得分:7)

@column是一个变量。它无法将其内容动态交换为SQL。您需要使用TSQL来完成此任务,从而将SQL生成为字符串然后执行它。如:

DECLARE @sql VARCHAR(MAX)
SET @sql = '
UPDATE my_table
SET ' + @column + '=''''
WHERE ' + @column + ' = ''NULL''
'

EXEC (@sql) -- don't forget the parentheses

一个小注释,我的代码将列设置为空字符串,这与NULL不同。我选择了你现有的例子。如果你想要NULL,那么

SET ' + @column + '= NULL

答案 1 :(得分:4)

  

'消息201,级别16,状态4,过程sp_fixnulls,行0过程或函数'sp_fixnulls'需要参数'@column',这是未提供的。'

您得到的错误是因为您尝试将select语句作为参数传递给存储过程。如果您只将一列的名称传递给存储过程,则会超过该错误。

然后你不会得到另一个错误,但你不会得到你想要的结果。如果您按照Eli推荐的那样修复存储过程(在@sql语句中添加括号EXEC,就像我评论的那样),它将起作用。

然后你需要用光标包装你的存储过程(大多数人不推荐,但在需要时工作)。或者,您可以只选择所有列名并生成一堆执行语句,然后运行语句。

SELECT 'EXECUTE sp_fixnulls N''' + column_name + ''';'
        FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'my_table';

这将生成如下语句(假设该表包含idnamedate列。

EXECUTE sp_fixnulls N'id';
EXECUTE sp_fixnulls N'name';
EXECUTE sp_fixnulls N'date';

另一种选择是完全放弃存储过程。

SELECT 'UPDATE my_table SET ' + column_name
        + ' = NULL WHERE ' + column_name + ' = ''NULL'';'
        FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'my_table';

这将生成如下语句。

UPDATE my_table SET id = NULL WHERE id = 'NULL';
UPDATE my_table SET name = NULL WHERE name = 'NULL';
UPDATE my_table SET date = NULL WHERE date = 'NULL';