您可以清楚地看到,如果传递的字符串长度大于所允许的长度,则会出现以下错误,并执行事务回滚:
消息8152,级别16,状态30,第18行字符串或二进制数据将
截断的
DROP TABLE IF EXISTS [dbo].[DataSource];
CREATE TABLE [dbo].[DataSource]
(
[value] VARCHAR(8)
);
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO [dbo].[DataSource] ([value])
VALUES ('123');
INSERT INTO [dbo].[DataSource] ([value])
VALUES ('very large string');
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN;
ROLLBACK TRANSACTION;
END;
THROW;
END CATCH
SELECT *
FROM [dbo].[DataSource];
所以,你的代码没有问题。但是您正在通过变量传递字符串,并且该值会自动截断以适应变量的长度。
因此,请检查以下内容:
DROP TABLE IF EXISTS [dbo].[DataSource];
CREATE TABLE [dbo].[DataSource]
(
[value] VARCHAR(8)
);
DECLARE @values VARCHAR(8) = 'very large string';
SELECT @values;
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO [dbo].[DataSource] ([value])
VALUES ('123');
INSERT INTO [dbo].[DataSource] ([value])
VALUES (@values);
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN;
ROLLBACK TRANSACTION;
END;
THROW;
END CATCH
SELECT *
FROM [dbo].[DataSource];
因此,您可以在调用存储过程之前检查输入参数是否有效,或者增加输入参数的值并依赖于引擎。不管怎样,我更喜欢在使用前验证数据——这对我来说似乎更清楚了(如果不允许,为什么我们允许用户输入长度更大的名称?).