我的 SQL Server 书说你不能在里面运行一个函数EXEC并展示了一个例子:
DECLARE @NumberOfLetters int = 15;
EXEC(‘SELECT LEFT(Name,’ + CAST(@NumberOfLetters AS varchar)
+ ‘) AS ShortName FROM Production.Product’);
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为该CAST()函数需要EXEC在行之前完全解析,因此我们可以将代码修改为:
DECLARE @NumberOfLetters AS int = 15;
DECLARE @str AS varchar(255);
SET @str = ‘SELECT LEFT(Name,’ + CAST(@NumberOfLetters AS varchar) + ‘) AS ShortName FROM Production.Product’;
EXEC(@str);
Run Code Online (Sandbox Code Playgroud)
这次它起作用了,因为如上所述,该CAST()功能需要EXEC在行之前完全解析。
但我还有一个问题,LEFT()函数呢,为什么可以运行EXEC?
DECLARE @Error int;
INSERT INTO Person.BusinessEntityContact
(BusinessEntityID
,PersonID
,ContactTypeID)
VALUES
(0,0,1);
SELECT @Error = @@ERROR;
PRINT ‘The Value of @Error is ‘ + CONVERT(varchar, @Error);
Run Code Online (Sandbox Code Playgroud)
我有 :
消息 547,级别 16,状态 0,第 4 行 INSERT 语句与 FOREIGN KEY 约束“FK_BusinessEntityContact_Person_PersonID”相冲突......该语句已终止。@Error 的值为 547
这意味着在抛出错误后该过程仍在继续。
但是,如果我尝试创建一个表(运行以下脚本两次以触发错误)为:
CREATE TABLE OurIFTest(
Col1 int PRIMARY KEY
);
IF @@ERROR != 0
PRINT 'Problems!';
ELSE
PRINT 'Everything went OK!';
Run Code Online (Sandbox Code Playgroud)
然后我得到了
消息 2714,级别 16,状态 6,第 2 行 数据库中已经有一个名为“OurIFTest”的对象。
这意味着该进程在抛出错误时终止。
那么为什么该过程因“创建”而终止,而不因“插入”而终止?
假设连接 1 中的事务尝试修改记录 A,然后提交。因为提交仅将缓冲区中的日志记录刷新到磁盘,检查点的工作是将所有脏页刷新到磁盘 (mdf)。并且有一个连接 B 在连接 1 提交后尝试读取记录 A。(因为 A 已经提交,这里没有锁定的东西)
所以我的问题是:
Q1-如果连接B在检查点之前读取记录A,是否意味着它将读取旧值?
Q2-如果连接B在检查点后读取记录A,是否意味着它将读取新值?
Q3-有时连接 B 获得新值,有时获得旧值,这不是很奇怪,解决这个问题的方法是 A 需要手动触发检查点吗?