加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 为什么TVP必须是READONLY,为什么其他类型的参数不

发布时间:2021-01-15 13:57:28 所属栏目:编程 来源:网络整理
导读:按照 this blog函数或存储进程的参数,假如它们不是OUTPUT参数,则根基上是按值转达,而且假如它们是OUTPUT参数,则根基上被视为更安详的转达版本. 早先我以为逼迫TVP被公布为READONLY的目标是向开拓职员明晰暗示TVP不能用作OUTPUT参数,但必需有更多盼望由于我们

按照 this blog函数或存储进程的参数,假如它们不是OUTPUT参数,则根基上是按值转达,而且假如它们是OUTPUT参数,则根基上被视为更安详的转达版本.

早先我以为逼迫TVP被公布为READONLY的目标是向开拓职员明晰暗示TVP不能用作OUTPUT参数,但必需有更多盼望由于我们不能将非TVP公布为READONLY .譬喻,以下失败:

create procedure [dbo].[test]
@a int readonly
as
    select @a

Msg 346,Level 15,State 1,Procedure test

The parameter “@a” can not be declared READONLY since it is not a table-valued parameter.

>自TV001于statistics aren’t stored开始,防备DML操纵背后的来由是什么?
>出于某种缘故起因,它是否与不但愿TVP成为OUTPUT参数有关?

办理要领

这个表明好像与以下组合有关:a)来自链接博客的细节,这个题目中没有提到,b)TVP的语用切合参数老是收支的方法,c)和性子表变量.

>链接博客文章中包括的缺失细节正是变量怎样传入和传出存储进程和函数(这与“假如它们是OUTPUT参数的更安详版本的转达参数”题目中的语言有关“ ):

TSQL uses a copy-in/copy-out semantics to pass parameters to stored procedures and functions….

…when the stored proc finishes executing (without hitting an error) a copy-out is made which updates the parameter passed in with any changes that were made to it in the stored proc.

The real benefit of this approach is in the error case. If an error occurs in the middle of a stored procedure’s execution,any changes made to parameters will not propagate back to the caller.

If the OUTPUT keyword is not present no copy-out is made.

The bottom line:
Parameters to stored procs never reflect the partial execution of the stored proc if it encountered an error.

这个困难的第1部门是参数老是“按值”转达.而且,仅当参数标志为OUTPUT而且存储进程乐成完成时才会现实发回当前值.假如OUTPUT置魅真正“通过引用”转达,那么指向该变量的内存中的位置的指针将是转达的对象,而不是值自己.假如您传入指针(即内存地点),则纵然存储进程的下一行导致错误而且中止执行,也会当即反应所做的任何变动.

总结第1部门:始终复制变量值;他们的内存地点没有引用它们.
>思量到第1部门,当传入的变量很是大时,始终复制变量值的计策也许会导致资源题目.我还没有测试过如那里理赏罚blob范例(VARCHAR(MAX),NVARCHAR(MAX),VARBINARY(MAX),XML以及那些不该该再行使的那些:TEXT,NTEXT和IMAGE),但它是安详的说任何传入的数据表都也许很是大.对付那些开拓TVP成果的人来说,但愿得到真正的“转达参考”手段以防备他们的酷炫新成果粉碎康健数目的体系(即想要更具可扩展性的要领)是故意义的.正如你在the documentation中看到的那样,他们做了什么:

Transact-SQL passes table-valued parameters to routines by reference to avoid making a copy of the input data.

另外,这种内存打点题目并不是一个新观念,由于它可以在SQL Server 2005中引入的SQLCLR API中找到(TVP在SQL Server 2008中引入).将NVARCHAR和VARBINARY数据转达给SQLCLR代码(即SQLCLR措施齐集.NET要领的输入参数)时,您可以选择行使SqlString或SqlBinary别离行使“by value”要领,可能可以选择别离行使SqlChars或SqlBytes的“按引用”要领. SqlChars和SqlBytes范例应承将数据完全流式传输到.NET CLR,这样您就可以提取大块的大值,而不是复制整个200 MB(最多2 GB,右)值.

总结第2部门:TVP,就其本质而言,假如留在“永久复制代价”模子中,就会倾向于耗损大量内存(从而恶化机能).因此,TVP做了一个真正的“通过参考转达”.
>最后一部门是为什么第2部门很重要:为什么真正“通过引用”转达TVP而不是建造它的副本改变任何对象.这可以通过作为第1部门基本的计划方针来办理:未乐成完成的存储进程不该以任何方法改变任何输入参数,无论它们是否标志为OUTPUT.应承DML操纵会当即影响TVP的值,由于它存在于挪用上下文中(由于通过引用转达意味着您正在变动传入的内容,而不是传入的内容的副本).

此刻,某小我私人,某个处所,也许正在与他们的监督器措辞,“好吧,只需构建一个自动化办法,用于回滚对TVP参数所做的任何变动,假若有任何传入存储进程的话.杜.题目办理了.”没那么快.这就是表变量的性子地址:对表变量的变动不受事宜束缚!以是没有步伐回滚变革.现实上,假如必要回滚,这是用于生涯事宜中天生的信息的能力:-).

总结第3部门:表变量不应承在导致存储进程中止的错误的环境下“除掉”对它们所做的变动.这违背了计划方针,即让参数永久不会反应部门执行(第1部门).

Ergo:必要READONLY要害字来防备对TVP的DML操纵,由于它们是现实通过“引用”转达的表变量,因此纵然存储进程碰着错误,也会当即反应对它们的任何修改,而且别无他法.

另外,其他数据范例的参数不能行使READONLY,由于它们已经是传入内容的副本,因此它不会掩护任何尚未受掩护的内容.谁人,以及其他数据范例的参数的事变方法是读写的,因此将API改为此刻包括只读观念也许会越发有用.

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读