具有可变列名的动态更新语句

时间:2012-10-11 19:04:36

标签: sql sql-server tsql

我们希望在多个SQL Server数据库中进行更新,以将某个表中的所有NULL值更改为空字符串而不是NULL。我们可能会在数百个数据库中执行此操作。表名总是相同的,但是列名是根据前端应用程序的配置方式而变化的(不要判断......我没有创建这个系统)。

有没有办法在不知道列名的情况下对所有这些列进行更新?

6 个答案:

答案 0 :(得分:15)

您可以在动态sql中传递列的名称:

declare @sql nvarchar (1000);
set @sql = N'update table set ' + @column_name + '= ''''';

exec sp_executesql @sql;

答案 1 :(得分:3)

您可以查看sys.columns表并加入表名或object_id。

 DECLARE @OBJ_ID INT

 SELECT @OBJ_ID = OBJECT_ID
 FROM SYS.tables
 WHERE name = 'YOURTABLE'

 SELECT * FROM SYS.columns
 WHERE OBJECT_ID = @OBJ_ID

您可以使用sys.columns查询中的name字段作为执行更新的基础。

答案 2 :(得分:2)

假设您只需要varchar / char类型的所有列(或将类型过滤器更改为您需要的任何类型):

DECLARE @tableName varchar(10)
SET @tableName = 'yourtablenamehere'

DECLARE @sql VARCHAR(MAX)
SET @sql = ''

SELECT @sql = @sql + 'UPDATE ' + @tableName + ' SET ' + c.name + ' = '''' WHERE ' + c.name + ' IS NULL ;'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE t.name = @tableName AND y.name IN ('varchar', 'nvarchar', 'char', 'nchar')

EXEC (@sql)

答案 3 :(得分:0)

这可以通过游标来实现。首先,选择列名,例如@Darren,然后使用这些值设置游标并循环:

Open oColumnsCursor
Fetch Next From oColumnscursor
    Into @ColumnName

While @@FETCH_STATUS=0
    Begin
        Set @oQuery = 'Update [DB]..[Table] Set [' + @ColumnName + '] = ''NewValue'' Where [' + @ColumnName + '] = ''OldValue'''
        Execute(@oQuery)
        Fetch Next From oColumnscursor Into @ColumnName
        Set @oCount = @oCount + 1
    End

Close oColumnsCursor;
Deallocate oColumnsCursor;

答案 4 :(得分:0)

当您知道表名称时,它将起作用:

DECLARE @tableName varchar(10)
SET @tableName = 'Customers'

DECLARE @sql VARCHAR(MAX)
SET @sql = ''

SELECT @sql = @sql + 'UPDATE ' + @tableName + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar')
AND t.name = @tableName;

EXEC(@sql);

这将迭代Db中的所有表和所有列:

DECLARE @sql VARCHAR(MAX)
SET @sql = ''

SELECT @sql = @sql + 'UPDATE ' + t.name + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar');

EXEC(@sql); 

答案 5 :(得分:0)

下面是过程。

ALTER   PROCEDURE [dbo].[util_db_updateRow]
-- Add the parameters for the stored procedure here
@colval_name  NVARCHAR (30), --culumn and values e.g. tax='5.50'
@idf_name  NVARCHAR (300), --column name
@idn_name  NVARCHAR (300), --column value
@tbl_name  NVARCHAR (100) --table name
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE 
@sql NVARCHAR(MAX)
-- construct SQL
SET @sql = 'UPDATE '+@tbl_name+'  SET '+@colval_name+' WHERE 
'+@idf_name+'='+@idn_name;
-- execute the SQL
EXEC sp_executesql @sql
SET NOCOUNT OFF  
RETURN
END