我有一个从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',这是未提供的。
答案 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';
这将生成如下语句(假设该表包含id
,name
和date
列。
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';