用了十年的SQL Server,现在连最简单的Update都不会写了,特来求教!

xiangsu 2017-09-13 02:51:29
在本机编译的存储过程中,两表关联更新。
用方法一:

Update tb1 set C1=0
from tb1 t1,tb2 t2
where t1.ID=t2.ID and t2.C2>0

报错:本机编译的模块 不支持在 UPDATE 语句中使用 FROM 子句或在 DELETE 语句中指定表源。

用方法二:

Update tb1 set C1=0 where exists (select 1 from tb2 where ID=tb1.ID and C2>0)

报错:仅包含 本机编译的模块 的 SELECT 语句支持子查询(即,嵌套在其他查询内的查询)。

哪位道友你给我个不会报错的方法三
...全文
842 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
繁花尽流年 2017-09-14
  • 打赏
  • 举报
回复
引用 37 楼 xiangsu 的回复:
本次技术尝鲜以失败告终! Sql2016,一年后再见! Sql2008,我又回来了!
都换到16了何苦还换回去
OwenZeng_DBA 2017-09-14
  • 打赏
  • 举报
回复
引用 39 楼 yenange 的回复:
以前测试过一下: http://blog.csdn.net/yenange/article/details/32705347 感觉还是不好用, 限制太多。 非常特殊的场合还是适用的, 比如抢购之类的。
限制是挺多,不过如果能用上速度还是不错
吉普赛的歌 版主 2017-09-14
  • 打赏
  • 举报
回复
以前测试过一下: http://blog.csdn.net/yenange/article/details/32705347 感觉还是不好用, 限制太多。 非常特殊的场合还是适用的, 比如抢购之类的。
zfjclark 2017-09-14
  • 打赏
  • 举报
回复

Update t1 set t1.C1=0
from tb1 t1,tb2 t2
where t1.ID=t2.ID and t2.C2>0
OwenZeng_DBA 2017-09-13
  • 打赏
  • 举报
回复
引用 37 楼 xiangsu 的回复:
本次技术尝鲜以失败告终! Sql2016,一年后再见! Sql2008,我又回来了!
ni 你这个是因为内存优化表的限制,,,2016限制已经比2014少很多了
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
本次技术尝鲜以失败告终! Sql2016,一年后再见! Sql2008,我又回来了!
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
就是太麻烦了,而且还不支持Max(),Min() ,只能用top 1 取最大值
繁花尽流年 2017-09-13
  • 打赏
  • 举报
回复
引用 33 楼 xiangsu 的回复:
[quote=引用 30 楼 zengertao 的回复:] [quote=引用 26 楼 xiangsu 的回复:] 没有更好的方法了吗? 非逼我出杀手锏?????
杀手锏是啥[/quote] 就是Update的本质:delete + Insert[/quote] 等版本更新吧,目前看来只有select可能好用些。
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
引用 31 楼 qq_37170555 的回复:
[quote=引用 29 楼 xiangsu 的回复:] [quote=引用 28 楼 qq_37170555 的回复:] [quote=引用 26 楼 xiangsu 的回复:] 没有更好的方法了吗? 非逼我出杀手锏?????

CREATE TYPE dbo.Type1 AS TABLE 
(
    Id INT NOT NULL,
    C2 INT NOT NULL,
    RowID INT NOT NULL IDENTITY,
    INDEX ix_RowID HASH(RowID) WITH (BUCKET_COUNT = 1024)
)   
WITH (MEMORY_OPTIMIZED = ON);  
GO  
DECLARE @tabvar1 dbo.Type1;  

INSERT @tabvar1
  (
    Id,
    c2
  )
SELECT Id,
       c2
FROM   tb2
WHERE C2=0;  

DECLARE @i       INT = 1,
        @Id      INT,
        @max     INT  
select @max=max(RowID) from @tabvar1
WHILE @i <= @max
BEGIN
    SELECT @Id = Id
    FROM   @tabvar1
    WHERE  RowID = @i;  
    
    UPDATE tb1
    SET    c1     = 0
    WHERE  Id     = @Id;  
    
    SET @i += 1;
END  
[/quote] 报这个错: Cannot schema bind procedure 'dbo.sp_Hekaton' because name 'tb2' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself. 你测试能通过?

ALTER proc [dbo].[sp_Hekaton]
WITH NATIVE_COMPILATION,SCHEMABINDING,EXECUTE AS OWNER
AS
BEGIN
	ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
       -- 你把代码写在里面试试?
END
[/quote] 上面那些是我从https://docs.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/implementing-update-with-from-or-subqueries看到的,然后我改了下,应该是可以得啊。还有你上面这句

ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
,我也看到了这个,但是不知道是干嘛用的,就删除了。上面这句是干嘛用的,加上上面那句也不行吗?没有道理的啊。按照微软说的,这样是可以的啊[/quote] 表名前加上dbo.就不会报错了。 这个方法可行,就是zengertao(繁花尽流年)说的循环逐条更新。
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
引用 30 楼 zengertao 的回复:
[quote=引用 26 楼 xiangsu 的回复:] 没有更好的方法了吗? 非逼我出杀手锏?????
杀手锏是啥[/quote] 就是Update的本质:delete + Insert
听雨停了 2017-09-13
  • 打赏
  • 举报
回复
引用 29 楼 xiangsu 的回复:
我没有2016,测试补了,不过按照微软上面说的这个逻辑,确实是可以行的通的,这样
听雨停了 2017-09-13
  • 打赏
  • 举报
回复
引用 29 楼 xiangsu 的回复:
[quote=引用 28 楼 qq_37170555 的回复:] [quote=引用 26 楼 xiangsu 的回复:] 没有更好的方法了吗? 非逼我出杀手锏?????

CREATE TYPE dbo.Type1 AS TABLE 
(
    Id INT NOT NULL,
    C2 INT NOT NULL,
    RowID INT NOT NULL IDENTITY,
    INDEX ix_RowID HASH(RowID) WITH (BUCKET_COUNT = 1024)
)   
WITH (MEMORY_OPTIMIZED = ON);  
GO  
DECLARE @tabvar1 dbo.Type1;  

INSERT @tabvar1
  (
    Id,
    c2
  )
SELECT Id,
       c2
FROM   tb2
WHERE C2=0;  

DECLARE @i       INT = 1,
        @Id      INT,
        @max     INT  
select @max=max(RowID) from @tabvar1
WHILE @i <= @max
BEGIN
    SELECT @Id = Id
    FROM   @tabvar1
    WHERE  RowID = @i;  
    
    UPDATE tb1
    SET    c1     = 0
    WHERE  Id     = @Id;  
    
    SET @i += 1;
END  
[/quote] 报这个错: Cannot schema bind procedure 'dbo.sp_Hekaton' because name 'tb2' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself. 你测试能通过?

ALTER proc [dbo].[sp_Hekaton]
WITH NATIVE_COMPILATION,SCHEMABINDING,EXECUTE AS OWNER
AS
BEGIN
	ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
       -- 你把代码写在里面试试?
END
[/quote] 上面那些是我从https://docs.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/implementing-update-with-from-or-subqueries看到的,然后我改了下,应该是可以得啊。还有你上面这句

ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
,我也看到了这个,但是不知道是干嘛用的,就删除了。上面这句是干嘛用的,加上上面那句也不行吗?没有道理的啊。按照微软说的,这样是可以的啊
繁花尽流年 2017-09-13
  • 打赏
  • 举报
回复
引用 26 楼 xiangsu 的回复:
没有更好的方法了吗? 非逼我出杀手锏?????
杀手锏是啥
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
引用 28 楼 qq_37170555 的回复:
[quote=引用 26 楼 xiangsu 的回复:] 没有更好的方法了吗? 非逼我出杀手锏?????

CREATE TYPE dbo.Type1 AS TABLE 
(
    Id INT NOT NULL,
    C2 INT NOT NULL,
    RowID INT NOT NULL IDENTITY,
    INDEX ix_RowID HASH(RowID) WITH (BUCKET_COUNT = 1024)
)   
WITH (MEMORY_OPTIMIZED = ON);  
GO  
DECLARE @tabvar1 dbo.Type1;  

INSERT @tabvar1
  (
    Id,
    c2
  )
SELECT Id,
       c2
FROM   tb2
WHERE C2=0;  

DECLARE @i       INT = 1,
        @Id      INT,
        @max     INT  
select @max=max(RowID) from @tabvar1
WHILE @i <= @max
BEGIN
    SELECT @Id = Id
    FROM   @tabvar1
    WHERE  RowID = @i;  
    
    UPDATE tb1
    SET    c1     = 0
    WHERE  Id     = @Id;  
    
    SET @i += 1;
END  
[/quote] 报这个错: Cannot schema bind procedure 'dbo.sp_Hekaton' because name 'tb2' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself. 你测试能通过?

ALTER proc [dbo].[sp_Hekaton]
WITH NATIVE_COMPILATION,SCHEMABINDING,EXECUTE AS OWNER
AS
BEGIN
	ATOMIC WITH(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')
       -- 你把代码写在里面试试?
END
听雨停了 2017-09-13
  • 打赏
  • 举报
回复
引用 26 楼 xiangsu 的回复:
没有更好的方法了吗? 非逼我出杀手锏?????

CREATE TYPE dbo.Type1 AS TABLE 
(
    Id INT NOT NULL,
    C2 INT NOT NULL,
    RowID INT NOT NULL IDENTITY,
    INDEX ix_RowID HASH(RowID) WITH (BUCKET_COUNT = 1024)
)   
WITH (MEMORY_OPTIMIZED = ON);  
GO  
DECLARE @tabvar1 dbo.Type1;  

INSERT @tabvar1
  (
    Id,
    c2
  )
SELECT Id,
       c2
FROM   tb2
WHERE C2=0;  

DECLARE @i       INT = 1,
        @Id      INT,
        @max     INT  
SELECT 
WHILE @i <= @max
BEGIN
    SELECT @Id = Id
    FROM   @tabvar1
    WHERE  RowID = @i;  
    
    UPDATE tb1
    SET    c1     = 0
    WHERE  Id     = @Id;  
    
    SET @i += 1;
END  
听雨停了 2017-09-13
  • 打赏
  • 举报
回复
引用 26 楼 xiangsu 的回复:
没有更好的方法了吗? 非逼我出杀手锏?????
CREATE TYPE dbo.Type1 AS TABLE ( Id INT NOT NULL, C2 INT NOT NULL, RowID INT NOT NULL IDENTITY, INDEX ix_RowID HASH(RowID) WITH (BUCKET_COUNT = 1024) ) WITH (MEMORY_OPTIMIZED = ON); GO DECLARE @tabvar1 dbo.Type1; INSERT @tabvar1 ( Id, c2 ) SELECT Id, c2 FROM tb2 WHERE C2=0; DECLARE @i INT = 1, @Id INT, @max INT SELECT WHILE @i <= @max BEGIN SELECT @Id = Id FROM @tabvar1 WHERE RowID = @i; UPDATE tb1 SET c1 = 0 WHERE Id = @Id; SET @i += 1; END 这样试试看
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
没有更好的方法了吗? 非逼我出杀手锏?????
xiangsu 2017-09-13
  • 打赏
  • 举报
回复
引用 21 楼 z10843087 的回复:
[quote=引用 20 楼 听雨停了的回复:][quote=引用 12 楼 xiangsu 的回复:] [quote=引用 9 楼 sinat_28984567 的回复:] [quote=引用 8 楼 xiangsu 的回复:] [quote=引用 5 楼 sinat_28984567 的回复:] 什么版本的数据库?
Sql Server 2016[/quote] 感觉你用了一个假sql server……[/quote] 各位大大:是本机编译的存储过程!![/quote] 刚百度了解了下本机编译存储过程。确实很多东西用不了。我想了个办法不知道行不行哈,就是用动态sql去执行。[/quote] 你用的是内存优化表吗[/quote] 对,全部用的是内存优化表
顺势而为1 2017-09-13
  • 打赏
  • 举报
回复
是否SQL SERVER 2016没有真正安装成功 ? 否则不应该的.....
繁花尽流年 2017-09-13
  • 打赏
  • 举报
回复
引用 17 楼 xiangsu 的回复:
[quote=引用 15 楼 zengertao 的回复:] [quote=引用 11 楼 xiangsu 的回复:] [quote=引用 3 楼 zengertao 的回复:] [quote=引用 2 楼 xiangsu 的回复:] [quote=引用 1 楼 zengertao 的回复:]
UPDATE a SET a.c1=0
FROM tb1 a
INNER JOIN tb2 b ON a.id=b.id AND b.c2>0
一样报错:本机编译的模块 不支持在 UPDATE 语句中使用 FROM 子句或在 DELETE 语句中指定表源。[/quote]

UPDATE tb1 SET c1=0
FROM tb2
where  tb1.id=tb2.id AND tb2.c2>0
试试[/quote] 还是不行,一样的错误:本机编译的模块 不支持在 UPDATE 语句中使用 FROM 子句或在 DELETE 语句中指定表源。[/quote]

UPDATE tb1 SET c1=0
where exists (select 1 from tb2 where tb1.id=tb2.id and tb2.c2>0)
again?[/quote] 这个就是我的方法二,报错:仅包含 本机编译的模块 的 SELECT 语句支持子查询(即,嵌套在其他查询内的查询)。[/quote] 那想开吧意味着目前不支持批量update,只能逐条update
加载更多回复(22)
本课程根据讲师十多年在世界500强外企的生产环境中的SQL Serer数据库管理和项目实施经验倾心打造。课程系统性强,知识体系完整,覆盖90%以上的企业环境下SQL Server高可用场景,课程中不仅演示详细的操作步骤,更加突出最常见的故障和问题,让学员少走“弯路”,不只是让学员学会“操作”更能让学员“操作”的规范,满满的干货分享,一些课程资料(架构图、部署规划表格等)不仅可以帮助学员掌握技能,也可以作为学员在企业生产环境中实施SQL Server高可用的配置文档、操作手册等。课程的实验环境介绍:1)全部基于微软域环境和企业版SQL Server AOAG - 95%以上的企业环境都是在域环境中,不介绍非域环境和标准版的SQL Server高可用性组,这的配置在企业中较罕见,没有实践意义,不浪费学员时间。2)相应域环境已提前部署和配置好 - 学员导入虚拟机即可开始实验,无需从零开始搭建域环境,所有实验中SQL Server均已加域,直入主题,节省大量时间。3)最新的Windows Server故障转移集群(WS2016、WS2019)和最新版本的SQL ServerSQL2017、SQL2019) -  WS2016-SQL2017与WS2019-SQL2019是目前大多数企业SQL Server高可用的主要平台,基于微软产品生命周期现在一些企业也在讲早期的AOAG向这两个版本迁移,掌握这两种组合不仅让学员学会,更能学有所用。本课程为后续SQL Server进阶课程铺垫,是通向SQL Server DBA 专家的必经之路,讲师每周答疑两次。所有课程资料包括:课程PPT、架构图、部署规划表格、各类脚本学员均可下载。     

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧