我正在尝试编写一个sp,用于将数据插入到我的表中。在我的sp中,我有一个字段跟踪,没有我实现的大多数代码都与此相关。但我遇到此错误:
将varchar值'SRFCHE-600-R-1000000'转换为数据类型int时转换失败。 tracingno的类型是varchar,但我无法理解为什么会遇到此错误。
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[spInsertRecieptTracing_tblRecieptTracing]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[spInsertRecieptTracing_tblRecieptTracing]
GO
create procedure spInsertRecieptTracing_tblRecieptTracing (
@RecieptTracingID UniqueIdentifier,
@RecieptItemRef UniqueIdentifier,
@TracingNo varchar(4000),
@ExecuteID UniqueIdentifier,
@Quantity Decimal(25,5),
@ExpireDateStr varchar(4000),
@ExpireDate datetime,
@ManufacturingDateStr varchar(4000),
@LotNo varchar(4000),
@IsBarCode Bit,
@ManufacturingDate DateTime,
@PartOptionName varchar(1000) = null,
@partcode varchar (100)
)
with Encryption
as
declare @_tracingno varchar (1000)
if exists (
select *
from ims.tblsettings where IsPartInTracingno = 1
)
begin
if exists (
select top 1 TracingNo
from ims.tblRecieptTracing
where TracingNo like '%-%')
begin
set @_tracingno = (
select max( right(TracingNo, charindex('-', reverse(TracingNo) + '-') - 1))
from ims.tblRecieptTracing
)
end
else
begin
set @_tracingno = 1000000
end
end
else
begin
set @_tracingno=''
end
if(@IsBarCode is null)
set @IsBarCode =0;
if(@IsBarCode =0)
begin
SET @TracingNo = NULL;
end
IF(EXISTS(
SELECT *
FROM IMS.tblRecieptTracing
WHERE RecieptItemRef = @RecieptItemRef
) and @IsBarCode = 0)
update IMS.tblRecieptTracing
set ExecuteID=@ExecuteID,
Quantity = @Quantity,
ExpireDateStr = @ExpireDateStr,
ExpireDate = @ExpireDate,
PartOptionName = @PartOptionName
Where RecieptItemRef = @RecieptItemRef
ELSE
BEGIN
if(@TracingNo is null)
begin
if exists(select * from ims.tblsettings where IsPartInTracingno=1)
begin
SELECT @TracingNo = @partcode + '-' + cast(@_tracingno as varchar)
FROM IMS.tblRecieptTracing ;
IF(@TracingNo IS NULL )
begin
SET @TracingNo = 1000000;
SET @TracingNo = @TracingNo +1 ;
end
SET @TracingNo=cast (@TracingNo as varchar)
end
else
--select
SELECT @TracingNo = cast (max( right(TracingNo, charindex('-', reverse(TracingNo) + '-') - 1))as varchar)
from ims.tblRecieptTracing;
IF(@TracingNo IS NULL )
SET @TracingNo = 1000000;
SET @TracingNo = @TracingNo + 1 ;
end
insert into IMS.tblRecieptTracing (
RecieptTracingID ,
RecieptItemRef ,
TracingNo ,
ExecuteID ,
Quantity ,
ExpireDateStr ,
ExpireDate,
ManufacturingDateStr,
LotNo,
ManufacturingDate,
PartOptionName)
values(
@RecieptTracingID,
@RecieptItemRef,
@TracingNo ,
@ExecuteID ,
@Quantity ,
@ExpireDateStr ,
@ExpireDate,
@ManufacturingDateStr,
@LotNo,
@ManufacturingDate,
@PartOptionName);
END
我认为主要部分在这里:
SELECT @TracingNo=cast (max( right(TracingNo, charindex('-', reverse(TracingNo) + '-') - 1))as varchar) from ims.tblRecieptTracing;
答案 0 :(得分:2)
100中有99次,此错误是由于SQL Server尝试将字符表达式隐式转换为int而引起的。
TL; DR;
您正在代码中的某个位置尝试比较,组合或使用字符值'SRFCHE-600-R-1000000'
填充int值。
摘自Data type conversion (Database Engine)文档:
在以下情况下可以转换数据类型:
- 当将一个对象的数据移动到另一个对象的数据或与之比较时,可能必须将数据从一个对象的数据类型转换为另一个对象的数据类型。
- 将Transact-SQL结果列,返回代码或输出参数中的数据移到程序变量中时,必须将数据从SQL Server系统数据类型转换为变量的数据类型。
然后在同一页面上继续:
数据类型可以隐式或显式转换。
隐式转换对用户不可见。 SQL Server自动将数据从一种数据类型转换为另一种数据类型。例如,当将
smallint
与int
进行比较时,在进行比较之前,smallint
被隐式转换为int
。
Data type precedence (Transact-SQL)中记录了将哪种类型的数据隐式转换为其他类型的数据:
SQL Server对数据类型使用以下优先顺序:
1种用户定义的数据类型(最高)
2 sql_variant
3个xml
4 datetimeoffset
5 datetime2
6 datetime
7 smalldatetime
8日
9次
10浮点数
11真实
12位小数
13钱
14小钱
15 bigint
16 int
17 smallint
18 tinyint
19位
20个ntext
21个文字
22图片
23时间戳
24个Uniqueidentifier
25个nvarchar(包括nvarchar(max))
26个nchar
27个varchar(包括varchar(max))
28个字符
29个varbinary(包括varbinary(max))
30个二进制文件(最低)
答案 1 :(得分:0)
错误是由于以下原因引起的:
SET @TracingNo = @TracingNo + 1 ;
您应该将其更改为
SET @TracingNo = @TracingNo + '1' ;
请查看Zohar Peled的出色答案:nvarchar的优先级(25)比int(16)低。
因此,当您进行计算
@TracingNo + 1
引擎将使用@TracingNo和整数1的nvarchar值。为了将它们相加,它将尝试将优先级较低的数据类型项转换为较高的优先级。因此,它将尝试将@TracingNo转换为int。这正是错误消息的含义:@TracingNo值之一无法转换为int。