无法将CSV值(java preparedStatement)传递给SQL存储过程

时间:2016-06-03 17:45:41

标签: java sql-server csv

我收到此错误"错误将数据类型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)的位置。这基本上是我收到此错误的原因。一种初学者的错误。

0 个答案:

没有答案