所有字段都复制过去, 能不能写一个类似update A set * (select * from B)的语句
可以实现替换, 又不用在sql语句列举所有的字段。
20 个解决方案
#1
不能吧,必须指明字段吧
#2
那字段太多了,几百个呢, 有什么宏可以代替么, 或者能自动生成如下的字段列表
"a.col1 = b.col1 a.col2 = b.col2 ......a.col100 = b.col100"...
"a.col1 = b.col1 a.col2 = b.col2 ......a.col100 = b.col100"...
#3
或者有什么sqlserver本身配备的功能, 可以直接使用来实现这个功能:
表B是表A前段时间的备份, 现在要用表B里指定的一条记录恢复到表A里面对应的位置
表B是表A前段时间的备份, 现在要用表B里指定的一条记录恢复到表A里面对应的位置
#4
update必须指明列名
#5
declare @s varchar(8000)
set @s = ''
declare @i int
set @i = 0
while @i<100
begin
set @s = ',' + 'a.col'+convert(varchar(3),@I)+' = 'b.col'+ convert(varchar(3),@I)
set @i = @I +1
end
set @s = stuff(@s,1,1,'')
print @s
set @s = ''
declare @i int
set @i = 0
while @i<100
begin
set @s = ',' + 'a.col'+convert(varchar(3),@I)+' = 'b.col'+ convert(varchar(3),@I)
set @i = @I +1
end
set @s = stuff(@s,1,1,'')
print @s
#6
表A
field0 field1 field2
表B
field1 field2 field3
select [field0],[field1],[field2] from [表A]
replace(replace('select [field0],[field1],[field2] from [表A]','[field0]','[field3]'),'[表A]','[表B]')
field0 field1 field2
表B
field1 field2 field3
select [field0],[field1],[field2] from [表A]
replace(replace('select [field0],[field1],[field2] from [表A]','[field0]','[field3]'),'[表A]','[表B]')
#7
当然, 可以通过读系统表自动生成update语句
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=b.'+quotename(name)
from syscolumns
where id=object_id('表A')
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from 表A a, 表B b where 条件')
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=b.'+quotename(name)
from syscolumns
where id=object_id('表A')
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from 表A a, 表B b where 条件')
#8
谢谢楼上的脚本,不过...
col1, col2 只是代号, 实际上都是有特别的字段名:
表A, 表B
cha_id cha_name icon_id score level .....100来个...., cha_id是主键, cha_name不可重复
col1, col2 只是代号, 实际上都是有特别的字段名:
表A, 表B
cha_id cha_name icon_id score level .....100来个...., cha_id是主键, cha_name不可重复
#9
我的脚本是直接从系统表获取列名, 所以你的表是什么列, 则会自动取出什么列名, 不会限制于col1之类
#10
嗯, 我正在测试zjcxc提供的脚本, 再请教一下,如果
表A数据库名是"DB1", 表B的数据库名是"DB2", 那SQL语法上如何体现呢,能实现么?
表A数据库名是"DB1", 表B的数据库名是"DB2", 那SQL语法上如何体现呢,能实现么?
#11
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
from DB1.syscolumns c, DB2.sysobjects o
where c.id=o.id and c.name = '表A'
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from db1..表A a, db2..表B b where 条件')
set @s=''
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
from DB1.syscolumns c, DB2.sysobjects o
where c.id=o.id and c.name = '表A'
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from db1..表A a, db2..表B b where 条件')
#12
执行sql的时候, 有些语法错误,
下面这条语句
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
'=b.', b就是表B的名字么, 但是会有语法错误, 比如表B的名字是'abc'
下面这条语句
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
'=b.', b就是表B的名字么, 但是会有语法错误, 比如表B的名字是'abc'
#13
表A的名字是character, 表B的名字是abc, 两张表都在同一个DB, 执行如下的脚本
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update character set '+@s+' where cha_id = 1')
----------------------------------------------------
输出
服务器: 消息 107,级别 16,状态 3,行 1
列前缀 'abc' 与查询中所用的表名或别名不匹配。
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update character set '+@s+' where cha_id = 1')
----------------------------------------------------
输出
服务器: 消息 107,级别 16,状态 3,行 1
列前缀 'abc' 与查询中所用的表名或别名不匹配。
#14
-- 楼主没有做过两个表连接的update ???. 显然是楼主的语法搞错了
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
#15
嗯, 谢谢, 搞定了,但现在还有一个特别的需求
因为表中 cha_id 字段和cha_name不让修改'唯一标识'
怎样在自动成生字段的脚本中就把这两个字段给屏蔽掉呢
因为表中 cha_id 字段和cha_name不让修改'唯一标识'
怎样在自动成生字段的脚本中就把这两个字段给屏蔽掉呢
#16
-- 加过滤条件嘛
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
#17
SET IDENTITY_INSERT
允许将显式值插入表的标识列中。
语法
SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }
参数
database
是指定的表所驻留的数据库名称。
owner
是表所有者的名称。
table
是含有标识列的表名。
注释
任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。
允许将显式值插入表的标识列中。
语法
SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }
参数
database
是指定的表所驻留的数据库名称。
owner
是表所有者的名称。
table
是含有标识列的表名。
注释
任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。
#18
哈哈,搞定!,马上给分,再来最后一个完美性的问题, 怎么把这个过程封装成一个函数来调用
参数是两个表名和条件字符串, 类似于
function REPLACE_REC(tab1, tab2, condition_str)
.....
end
REPLACE_REC('character', 'abc', 'cha_id = 1')
ps : 回佛来德, SET IDENTITY_INSERT 好像不起作用
参数是两个表名和条件字符串, 类似于
function REPLACE_REC(tab1, tab2, condition_str)
.....
end
REPLACE_REC('character', 'abc', 'cha_id = 1')
ps : 回佛来德, SET IDENTITY_INSERT 好像不起作用
#19
set identity_insert 是针对插入时, 强制插入标识列的, 对于update当然无效.
#20
函数只能生成sql语句, 不能执行. 所以可以写到生成sql语句这一层
create function f_sql(
@stb sysname,
@dtb sysname,
@where nvarchar(1000)
) returns varchar(8000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id(@stb)
and status & 0x80 = 0
-- and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
set @s = 'update a set '+@s+' from '+@stb+' a, '+@dtb+' b where '+@where
return(@s)
end
create function f_sql(
@stb sysname,
@dtb sysname,
@where nvarchar(1000)
) returns varchar(8000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id(@stb)
and status & 0x80 = 0
-- and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
set @s = 'update a set '+@s+' from '+@stb+' a, '+@dtb+' b where '+@where
return(@s)
end
#21
#1
不能吧,必须指明字段吧
#2
那字段太多了,几百个呢, 有什么宏可以代替么, 或者能自动生成如下的字段列表
"a.col1 = b.col1 a.col2 = b.col2 ......a.col100 = b.col100"...
"a.col1 = b.col1 a.col2 = b.col2 ......a.col100 = b.col100"...
#3
或者有什么sqlserver本身配备的功能, 可以直接使用来实现这个功能:
表B是表A前段时间的备份, 现在要用表B里指定的一条记录恢复到表A里面对应的位置
表B是表A前段时间的备份, 现在要用表B里指定的一条记录恢复到表A里面对应的位置
#4
update必须指明列名
#5
declare @s varchar(8000)
set @s = ''
declare @i int
set @i = 0
while @i<100
begin
set @s = ',' + 'a.col'+convert(varchar(3),@I)+' = 'b.col'+ convert(varchar(3),@I)
set @i = @I +1
end
set @s = stuff(@s,1,1,'')
print @s
set @s = ''
declare @i int
set @i = 0
while @i<100
begin
set @s = ',' + 'a.col'+convert(varchar(3),@I)+' = 'b.col'+ convert(varchar(3),@I)
set @i = @I +1
end
set @s = stuff(@s,1,1,'')
print @s
#6
表A
field0 field1 field2
表B
field1 field2 field3
select [field0],[field1],[field2] from [表A]
replace(replace('select [field0],[field1],[field2] from [表A]','[field0]','[field3]'),'[表A]','[表B]')
field0 field1 field2
表B
field1 field2 field3
select [field0],[field1],[field2] from [表A]
replace(replace('select [field0],[field1],[field2] from [表A]','[field0]','[field3]'),'[表A]','[表B]')
#7
当然, 可以通过读系统表自动生成update语句
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=b.'+quotename(name)
from syscolumns
where id=object_id('表A')
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from 表A a, 表B b where 条件')
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=b.'+quotename(name)
from syscolumns
where id=object_id('表A')
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from 表A a, 表B b where 条件')
#8
谢谢楼上的脚本,不过...
col1, col2 只是代号, 实际上都是有特别的字段名:
表A, 表B
cha_id cha_name icon_id score level .....100来个...., cha_id是主键, cha_name不可重复
col1, col2 只是代号, 实际上都是有特别的字段名:
表A, 表B
cha_id cha_name icon_id score level .....100来个...., cha_id是主键, cha_name不可重复
#9
我的脚本是直接从系统表获取列名, 所以你的表是什么列, 则会自动取出什么列名, 不会限制于col1之类
#10
嗯, 我正在测试zjcxc提供的脚本, 再请教一下,如果
表A数据库名是"DB1", 表B的数据库名是"DB2", 那SQL语法上如何体现呢,能实现么?
表A数据库名是"DB1", 表B的数据库名是"DB2", 那SQL语法上如何体现呢,能实现么?
#11
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
from DB1.syscolumns c, DB2.sysobjects o
where c.id=o.id and c.name = '表A'
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from db1..表A a, db2..表B b where 条件')
set @s=''
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
from DB1.syscolumns c, DB2.sysobjects o
where c.id=o.id and c.name = '表A'
set @s=stuff(@s,1,1,'')
exec('update a set '+@s+' from db1..表A a, db2..表B b where 条件')
#12
执行sql的时候, 有些语法错误,
下面这条语句
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
'=b.', b就是表B的名字么, 但是会有语法错误, 比如表B的名字是'abc'
下面这条语句
select @s=@s+','+quotename(c.name)+'=b.'+quotename(c.name)
'=b.', b就是表B的名字么, 但是会有语法错误, 比如表B的名字是'abc'
#13
表A的名字是character, 表B的名字是abc, 两张表都在同一个DB, 执行如下的脚本
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update character set '+@s+' where cha_id = 1')
----------------------------------------------------
输出
服务器: 消息 107,级别 16,状态 3,行 1
列前缀 'abc' 与查询中所用的表名或别名不匹配。
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update character set '+@s+' where cha_id = 1')
----------------------------------------------------
输出
服务器: 消息 107,级别 16,状态 3,行 1
列前缀 'abc' 与查询中所用的表名或别名不匹配。
#14
-- 楼主没有做过两个表连接的update ???. 显然是楼主的语法搞错了
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
#15
嗯, 谢谢, 搞定了,但现在还有一个特别的需求
因为表中 cha_id 字段和cha_name不让修改'唯一标识'
怎样在自动成生字段的脚本中就把这两个字段给屏蔽掉呢
因为表中 cha_id 字段和cha_name不让修改'唯一标识'
怎样在自动成生字段的脚本中就把这两个字段给屏蔽掉呢
#16
-- 加过滤条件嘛
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id('character')
and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
print @s
exec('update a set '+@s+' from character a, abc b where cha_id = 1') -- 别名及from
#17
SET IDENTITY_INSERT
允许将显式值插入表的标识列中。
语法
SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }
参数
database
是指定的表所驻留的数据库名称。
owner
是表所有者的名称。
table
是含有标识列的表名。
注释
任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。
允许将显式值插入表的标识列中。
语法
SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }
参数
database
是指定的表所驻留的数据库名称。
owner
是表所有者的名称。
table
是含有标识列的表名。
注释
任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。
#18
哈哈,搞定!,马上给分,再来最后一个完美性的问题, 怎么把这个过程封装成一个函数来调用
参数是两个表名和条件字符串, 类似于
function REPLACE_REC(tab1, tab2, condition_str)
.....
end
REPLACE_REC('character', 'abc', 'cha_id = 1')
ps : 回佛来德, SET IDENTITY_INSERT 好像不起作用
参数是两个表名和条件字符串, 类似于
function REPLACE_REC(tab1, tab2, condition_str)
.....
end
REPLACE_REC('character', 'abc', 'cha_id = 1')
ps : 回佛来德, SET IDENTITY_INSERT 好像不起作用
#19
set identity_insert 是针对插入时, 强制插入标识列的, 对于update当然无效.
#20
函数只能生成sql语句, 不能执行. 所以可以写到生成sql语句这一层
create function f_sql(
@stb sysname,
@dtb sysname,
@where nvarchar(1000)
) returns varchar(8000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id(@stb)
and status & 0x80 = 0
-- and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
set @s = 'update a set '+@s+' from '+@stb+' a, '+@dtb+' b where '+@where
return(@s)
end
create function f_sql(
@stb sysname,
@dtb sysname,
@where nvarchar(1000)
) returns varchar(8000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s=@s+','+quotename(name)+'=abc.'+quotename(name)
from syscolumns
where id=object_id(@stb)
and status & 0x80 = 0
-- and name not in('cha_id', 'cha_name')
set @s=stuff(@s,1,1,'')
set @s = 'update a set '+@s+' from '+@stb+' a, '+@dtb+' b where '+@where
return(@s)
end