如何更新表中的不同列和行?我想做一些类似的事情来替换 SQL Server 中的字符串
我想这样做,但该值存在于同一类型的多个列中。这些值是员工表的外键 varchars。每列代表一个任务,因此同一员工可能被分配到记录中的多个任务,并且这些任务在记录之间会有所不同。我怎样才能有效地做到这一点?基本上可以替换整个表中不同列的所有内容。
感谢您的任何帮助或建议。
干杯,~ck 在圣地亚哥
如何更新表中的不同列和行?我想做一些类似的事情来替换 SQL Server 中的字符串
我想这样做,但该值存在于同一类型的多个列中。这些值是员工表的外键 varchars。每列代表一个任务,因此同一员工可能被分配到记录中的多个任务,并且这些任务在记录之间会有所不同。我怎样才能有效地做到这一点?基本上可以替换整个表中不同列的所有内容。
感谢您的任何帮助或建议。
干杯,~ck 在圣地亚哥
这应该可以解决问题:
UPDATE table1
SET field1 = replace(field1, 'oldstring', 'newstring'),
field2 = replace(field2, 'oldstring2', 'newstring2')
ETC...
主要思想是创建一个SQL Update语句,不管表有多少字段。它是在 SQL Server 2012 上创建的,但我认为它也适用于 2008 年。
样品表:
CREATE TABLE SampleTable
(
Field1 INT,
Field2 VARCHAR(20),
Field3 VARCHAR(20),
Field4 VARCHAR(100),
Field5 DATETIME,
Field6 NVARCHAR(10)
);
仅获取 varchar 和 nvarchar 字段。根据您的要求更改OLD_TEXT和NEW_TEXT。如果您不仅需要匹配 varchar 和 nvarchar 字段,请更改system_type_id值。
SELECT 'UPDATE dbo.SampleTable SET ' + STUFF((SELECT ', [' + name + '] = REPLACE([' + name + '], ''OLD_TEXT'', ''NEW_TEXT'')'
FROM sys.COLUMNS
WHERE
[OBJECT_ID] = OBJECT_ID('SampleTable')
AND [is_identity] = 0 --It's not identity field
AND [system_type_id] in (167, 231) -- varchar, nvarchar
FOR XML PATH('')), 1,1, '')
最后一个查询的结果是:
UPDATE dbo.SampleTable SET
[Field2] = REPLACE([Field2], 'OLD_TEXT', 'NEW_TEXT'),
[Field3] = REPLACE([Field3], 'OLD_TEXT', 'NEW_TEXT'),
[Field4] = REPLACE([Field4], 'OLD_TEXT', 'NEW_TEXT'),
[Field6] = REPLACE([Field6], 'OLD_TEXT', 'NEW_TEXT');
只需复制结果并在 SSMS 中执行。在编写更新语句时,此代码段可为您节省一点时间。
希望能帮助到你。
回答张贴者关于如何规范化此数据结构的补充问题。以下是你的做法:
Project
-------
ProjectID
ProjectName
etc...
Employee
--------
EmployeeID
EmployeeName
etc...
Task
----
TaskID
ProjectID
EmployeeID
TaskDescription
etc...
您当前的结构,在 Project 表中有一堆 Task1、Task2 等...列,显然不是由了解关系数据库的人设计的。
在解雇该人的过程中,您可能会解释他的设计违反了第一范式,同时将他引导至该链接文章的“跨列重复组”部分。
我知道已经 12 年了,但我最近有一个类似的要求,这就是我解决它的方法(在没有运气在任何地方找到合适的完整解决方案之后)。不同之处在于我必须更改所有包含某个字符串值的数据库表中的值。下面的过程比较通用,也可以用于一张表。
CREATE OR ALTER PROCEDURE UPDATE_ALL_COLUMNS
@TableNameSearchFilter NVARCHAR(100),
@TableSchema NVARCHAR(100),
@TestValue NVARCHAR(100),
@NewValue NVARCHAR(100)
AS
BEGIN
DECLARE @NRCOLUMNS INT;
DECLARE @i INT = 0;
DECLARE @COLUMN NVARCHAR(100) = '';
DECLARE @SQL NVARCHAR(MAX) = '';
DECLARE @TableToUpdate NVARCHAR(256) = '';
DECLARE @insertingNULL BIT;
IF (@NewValue IS NULL) SET @insertingNULL = 1
ELSE SET @insertingNULL = 0;
WHILE @TableToUpdate IS NOT NULL
BEGIN
SELECT @TableToUpdate = MIN(TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE @TableNameSearchFilter
AND TABLE_SCHEMA = @TableSchema
AND TABLE_NAME > @TableToUpdate;
WITH CTE1 AS
(
SELECT ROW_NUMBER() OVER (ORDER BY ORDINAL_POSITION) AS RN
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableToUpdate
AND TABLE_SCHEMA = @TableSchema
AND (@insertingNULL = 0 OR (@insertingNULL = 1 AND IS_NULLABLE = 'YES'))
)
SELECT @i = MIN(RN), @NRCOLUMNS = MAX(RN) FROM CTE1;
WHILE (@i <= @NRCOLUMNS AND @TableToUpdate IS NOT NULL)
BEGIN
WITH CTE AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY ORDINAL_POSITION) AS RN
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableToUpdate
AND TABLE_SCHEMA = @TableSchema
AND (@insertingNULL = 0 OR (@insertingNULL = 1 AND IS_NULLABLE = 'YES'))
)
SELECT @COLUMN = COLUMN_NAME
FROM CTE
WHERE RN = @i;
SET @SQL = @SQL +
N'UPDATE D SET ' + @COLUMN + N' = ' + ISNULL(N'''' + @NewValue + N'''', N'NULL')
+ N' FROM ' + @TableSchema + N'.' + @TableToUpdate + N' D WHERE CAST(D.' + @COLUMN + ' AS NVARCHAR) = ' + ISNULL(N'''' + @TestValue + N'''', N'NULL') + ';'
+ NCHAR(13) + NCHAR(10);
SET @i = @i + 1;
END;
END;
--PRINT SUBSTRING(@SQL, 1, 4000)
--PRINT SUBSTRING(@SQL, 4001, 8000)
--PRINT SUBSTRING(@SQL, 8001, 12000)
--PRINT SUBSTRING(@SQL, 12001, 16000)
--PRINT SUBSTRING(@SQL, 16001, 20000)
--PRINT SUBSTRING(@SQL, 20001, 24000)
EXEC (@SQL)
END
GO
作为一个使用示例:
EXEC UPDATE_ALL_COLUMNS '%temp%', 'dbo', '', NULL
参数:
LIKE
运算符一起用于从数据库中查找名称与此值匹配的所有表;解释:
NULL
。EXEC (@SQL)
) 并使用 PRINT 取消注释,只是为了了解该过程的作用以及最终语句的外观。NULL
NULL
WHERE
IS NULL
IS NULL
希望这最终对某人有所帮助。