我收到此错误"错误将数据类型NVARCHAR转换为INT"当我尝试执行一个准备好的Statement时,将一个String CSV(@selectedResources)传递给SQL Server存储过程中的VARCHAR参数:
Java代码:
public void setFields(IEntity argEntity, StormPS pstmt) throws SQLException {
IMeal t_Meal = (IMeal) argEntity;
pstmt.setInt(1, t_Meal.getTourId());
pstmt
.setTimestamp(2, StormContext
.dateToTimestamp(t_Meal.getDateTimeStartActual()));
pstmt.setTimestamp(3, StormContext.dateToTimestamp(t_Meal.getDateTimeEndActual()));
pstmt.setInt(4, t_Meal.getJobElementId());
pstmt.setBoolean(5, t_Meal.getOTE());
pstmt.setBoolean(6, t_Meal.getBillable());
pstmt.setBoolean(7, t_Meal.getAutoAdd());
pstmt.setInt(8, t_Meal.getUpdatingUserId());
pstmt.setString(9, t_Meal.getIpAddress());
pstmt.setString(10, t_Meal.getSelectedResources());
}
存储过程的参数:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MealUpdate]
@@TourId INT,
@@DateTimeStartActual DATETIME,
@@DateTimeEndActual DATETIME,
@@JobElementId INT,
@@OTE BIT,
@@Billable BIT,
@@AutoAdd BIT,
@@UpdatingUserId INT,
@@IPAddress VARCHAR(20),
@@SelectedResources VARCHAR(300)
起初我觉得我的preparedStatement已经定义了这样的参数[9105267,2016-05-18 04:30:00.0,2016-05-18 05:30:00.0,0,false,false,false,23939 ,127.0.0.1, 8224483,8149293,8149281,8149272 ](值' 8224483,8149293,8149281,8149272'是@selectedResources String参数)。然后我决定在这个字符串中添加单引号[9105267,2016-05-18 04:30:00.0,2016-05-18 05:30:00.0,0,false,false,false,23939,127.0.0.1 ,' 8224483,8149293,8149281,8149272' ],但同样的错误仍然显示。
我希望我的问题足够明确。
完整的存储过程:
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MealUpdate]
@@TourId INT,
@@DateTimeStartActual DATETIME,
@@DateTimeEndActual DATETIME,
@@JobElementId INT,
@@OTE BIT,
@@Billable BIT,
@@AutoAdd BIT,
@@UpdatingUserId INT,
@@IPAddress VARCHAR(20),
@@SelectedResources VARCHAR(300),
@@Id INT,
@@UpdatingDateTime DATETIME = NULL
AS
SET NOCOUNT ON
SET XACT_ABORT ON
BEGIN TRY
BEGIN TRANSACTION
DECLARE @ErrCode INT
DECLARE @contractRuleId int
DECLARE @OldMealLenght int
DECLARE @OldDateTimeStartActual DATETIME
DECLARE @NewMealLenght int
IF @@UpdatingDateTime IS NULL
SET @@UpdatingDateTime = GETDATE()
BEGIN TRY
EXEC MealValidate @@TourId,
@@DateTimeStartActual,
@@DateTimeEndActual,
@@JobElementId OUTPUT,
@@Id
END TRY
BEGIN CATCH
DECLARE @message as varchar(200)
DECLARE @severity as int
DECLARE @state as int
DECLARE @number as int
set @message = ERROR_MESSAGE()
set @severity = ERROR_SEVERITY()
set @state = ERROR_STATE()
set @number = ERROR_NUMBER()
if @number = 50000
RAISERROR(@message,@severity,@state)
else
RAISERROR('Error in Meals. Unknown code. Please contact STORM administrator',16,1)
RETURN
END CATCH
select @contractRuleId = ContractRuleId from tours WITH(NOLOCK) where id = @@TourId and isdisabled = 0
select @OldDateTimeStartActual = M.DateTimeStartActual,
@OldMealLenght = datediff(minute,M.DateTimeStartActual,M.DateTimeEndActual)
from MEALS M with(nolock)
where M.id = @@Id
set @NewMealLenght = datediff(minute,@@DateTimeStartActual,@@DateTimeEndActual)
if(@OldDateTimeStartActual <> @@DateTimeStartActual or @OldMealLenght <> @NewMealLenght)
begin
EXEC TourIndicatorsDeleteFromMealEvent @contractRuleId,@@TourId,@@UpdatingUserId
EXEC TourIndicatorsCreateFromPayTransaction @contractRuleId,@@TourId,@@UpdatingUserId
end
UPDATE MEALS
SET [TourId] =@@TourId,
[DateTimeStartActual] =@@DateTimeStartActual,
[DateTimeEndActual] =@@DateTimeEndActual,
JobElementId =@@JobElementId,
OTE =@@OTE,
Billable =@@Billable,
AutoAdd =0,
UpdatingDateTime =@@UpdatingDateTime,
UpdatingUserId =@@UpdatingUserId,
IPAddress =@@IPAddress,
DoLog =1
WHERE [Id] =@@Id
**INSERT INTO dbo.table_fab SELECT * FROM [dbo].[CSVToTable](@@SelectedResources)**
/* Tests how many rows effected, and returns an error if no rows were found
for update.
*/
IF @@ROWCOUNT = 0
BEGIN
RAISERROR(' There was no meal to update.',15,1)
----WITH LOG
END
EXEC TourIndicatorsCreateFromMealEvent @contractRuleId,@@TourId,@@UpdatingUserId
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Test XACT_STATE:
-- If 1, the transaction is committable.
-- If -1, the transaction is uncommittable and should
-- be rolled back.
-- XACT_STATE = 0 means that there is no transaction and
-- a commit or rollback operation would generate an error.
-- Test whether the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
ROLLBACK TRANSACTION
END
-- Test whether the transaction is committable.
IF (XACT_STATE()) = 1
BEGIN
COMMIT TRANSACTION
END
DECLARE @ErrorMessage NVARCHAR(4000)
DECLARE @ErrorSeverity INT
DECLARE @ErrorState INT
DECLARE @ErrorNumber INT
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE(),
@ErrorNumber = ERROR_NUMBER()
-- Only log non-user defined errors
IF (@ErrorNumber <> 50000)
BEGIN
-- Execute error retrieval routine.
EXECUTE [dba_admin].[dbo].[s_LogSQLError]
END
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
)
END CATCH
CSVToTable功能:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX))
RETURNS @TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET @InStr = REPLACE(@InStr + ',', ',,', ',')
DECLARE @SP INT
DECLARE @VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', @INSTR ) <> 0
BEGIN
SELECT @SP = PATINDEX('%,%',@INSTR)
SELECT @VALUE = LEFT(@INSTR , @SP - 1)
SELECT @INSTR = STUFF(@INSTR, 1, @SP, '')
INSERT INTO @TempTab(id) VALUES (@VALUE)
END
RETURN
END
GO
更新(解决方案):
在执行preparedStatement的Java类中,有一个常量,它定义将作为参数发送的字段数,此常量在9中定义:
private final static int FIELDS_NUMBER = 9;
当我添加一个新参数(selectedResources)时,我需要将此常量重新定义为10.我将@selectedResouces发送到@Id(其类型为int)的位置。这基本上是我收到此错误的原因。一种初学者的错误。