在SQL Server中,如果我有两个表,每个表有(25)列,如何通过SELECT更新表?
查询是:
UPDATE
Table1
SET
Table1.col1 = Table2.col1,
Table1.col2 = Table2.col2,
...
...
...
Table1.col25 = Table2.col25,
FROM
Table1
INNER JOIN
Table2
ON
Table1.id = Table2.id
但有没有办法更新所有列,而不像上面的例子那样编写所有25列?
答案 0 :(得分:6)
在SSMS中使用对象资源管理器,找到有问题的表并展开节点,以便您看到列,键,约束,触发器,索引和统计信息
将Columns文件夹拖到查询窗口窗格中。这会在一行中生成以列空格分隔的列列表。
我们将使用正则表达式将数据转换为所需的格式。
要知道的事情。
\n
是换行符/回车/输入
^
匹配行的开头
.
一次匹配任何东西
*
就会重复比赛
我会标记我们匹配的单词,以便我们可以使用它。这是通过大括号{}
来实现的。当事情被括号括起来时,我们对序数的引用会增加。在这里,我们只使用一个,/1
就足够了。
正则表达式是贪婪的,这意味着它将尽可能匹配,这不是我们想要的。不幸的是,仅SSMS 支持贪婪匹配,所以我们必须进行多次传递
https://www.simple-talk.com/sql/sql-training/regex-based-finding-and-replacing-of-text-in-ssms/
理论发现:{.*?},
(注意上面的尾随空格)
\n, T1.\1 = T2.\1
在此步骤中,我们将强制所有列都存在于一行
重要说明:查找内容中包含一个尾随空格
,
\n
Current Document
Regular expressions
开始
environment_id, environment_name, folder_id, description, created_by_sid, created_by_name, created_time
结果
environment_id
environment_name
folder_id
description
created_by_sid
created_by_name
created_time
我们现在已经占据了所有列,并将它们展平在左边缘。
我们将采用所有单词并用T1 = T2
包装它们我将使我的输出看起来与你的相似,除非我是一个领先的逗号人。
^{.*}
, T1.\1 = T2.\1
Current Document
Regular expressions
开始 environment_id environment_name folder_id 描述 created_by_sid created_by_name CREATED_TIME
结果
, T1.environment_id = T2.environment_id
, T1.environment_name = T2.environment_name
, T1.folder_id = T2.folder_id
, T1.description = T2.description
, T1.created_by_sid = T2.created_by_sid
, T1.created_by_name = T2.created_by_name
, T1.created_time = T2.created_time
现在你有一个很好的,几乎干净的列翻译列表。修剪第一个逗号并将其打入UPDATE语句
答案 1 :(得分:2)
通过一个示例来显示如何你可以完成这个 kind 的东西,我把以下的T-SQL放在一起。
USE tempdb;
CREATE TABLE T1
(
ID INT
, Field1 INT
, Field2 INT
);
CREATE TABLE T2
(
ID INT
, Field1 INT
, Field2 INT
);
GO
INSERT INTO T1 (ID, Field1, Field2) VALUES (1, 2, 3);
INSERT INTO T2 (ID, Field1, Field2) VALUES (1, 4, 5);
DECLARE @TableName1 SYSNAME;
DECLARE @TableName2 SYSNAME;
DECLARE @cmd NVARCHAR(max);
SET @TableName1 = 'T1';
SET @TableName2 = 'T2';
SET @cmd = '';
SELECT @cmd = @cmd + CASE WHEN @cmd = '' THEN '' ELSE ', ' END +
T1.TableName + '.' + T1.FieldName + ' = ' + T2.TableName + '.' + T2.FieldName
FROM (
SELECT t1.name AS TableName, c1.name AS FieldName
FROM sys.tables t1
INNER JOIN sys.columns c1 ON t1.object_id = c1.object_id
WHERE t1.name = @TableName1 AND c1.name <> 'ID'
) T1
INNER JOIN (
SELECT t2.name AS TableName, c2.name AS FieldName
FROM sys.tables t2
INNER JOIN sys.columns c2 ON t2.object_id = c2.object_id
WHERE t2.name = @TableName2 AND c2.name <> 'ID'
) T2 ON T1.FieldName = T2.FieldName
SET @cmd = 'UPDATE ' + QUOTENAME(@TableName1) +
' SET ' + @cmd +
' FROM ' + QUOTENAME(@TableName1) +
' INNER JOIN ' + QUOTENAME(@TableName2) +
' ON ' + QUOTENAME(@TableName1) + '.id = ' + QUOTENAME(@TableName2) + '.id;';
SELECT @cmd;
EXEC sp_executesql @cmd;
这要求两个表具有完全相同的结构;字段名称和数据类型必须完全匹配。我没有在输出的动态SQL中处理模式,因此您必须确保表名仅存在于单个模式中;或修改代码以处理所需的架构。
出于多种原因,我强烈建议使用此类构造 。第一;你真的要节省多少打字?第二;确保生成的UPDATE
语句完全您打算充满危险。第三;动态SQL并不完全是过程缓存友好的。我可以继续谈论为什么这是一个坏主意。
答案 2 :(得分:-4)
只需遵循以下代码syntex
即可 UPDATE Table1 SET
Table1.col1 = (SELECT col1 FROM table2 Where Table2.id=table1.id),
Table1.col2 = (SELECT col2 FROM table2 Where Table2.id=table1.id),
...
...
...
Table1.col25 = (SELECT col25 FROM table2 Where Table2.id=table1.id) FROM table1