过程:转换失败

时间:2017-06-13 09:33:50

标签: sql-server

这是我的程序:

ALTER PROCEDURE [Ac].[SAVE]     
    @P_LIST VARCHAR(MAX) = '', 
    @P_USER_ID INT
AS
    DECLARE @ID INT;
BEGIN
    SET @ID = (NEXT VALUE FOR  Ac.SEQ)

    INSERT INTO Ac.Parameter (ID, NAME, VALUE, MODIFIED_BY, MODIFIED_ON)
    VALUES (@ID, 'LIST', @P_LIST, @P_USER_ID, GETDATE())

    SELECT @ID AS ID;       
END

使用以下值执行此过程时:

   exec [Ac].[SAVE] @P_LIST ='6854,6891', @P_USER_ID  = 2965

我收到此错误:

  

将varchar值'6854,6891'转换为数据类型int。

时转换失败

但是当我执行下面的操作时,没有问题:

exec [Ac].[SAVE] @P_LIST ='6854', @P_USER_ID  = 2965

如果我只是执行插入查询而不使用这样的过程:

INSERT INTO Ac.Parameter(ID, NAME, VALUE, MODIFIED_BY, MODIFIED_ON)
VALUES (1, 'LIST', '6854,6891', 2965, GETDATE())

它也很好并且插入成功。

列数据类型:

  • ID int
  • NAME varchar(64)
  • VALUE varchar(8000)
  • MODIFIED_BY int
  • MODIFIED_ON datetime

3 个答案:

答案 0 :(得分:0)

Ac.Parameter表中的值列似乎是一个int - 您正在尝试插入一个不可转换为int的字符串。您的过程显然只有在值可转换为1时才有效,如您的示例所示(SQL Server正在为您转换字符串)。

据推测,你真正想要做的就是将整个过程转换为多个值 - 这里没有任何神奇的子弹可以让它现在起作用,你还没有编写大部分程序来处理多个值。

假设您重写业务逻辑以处理多个值,您需要:

  • 创建一个表类型参数,填充它,并将其传递给存储过程(假设SQL Server 2008+ - 这是最佳选择)
  • 将参数字符串拆分为具有单独整数值的表
  • 其他方法 - 共享处理表,将字符串作为XML传递等等 - 请参阅http://sommarskog.se/share_data.html了解每个
  • 的优缺点

答案 1 :(得分:0)

您应该将字符串拆分为单独的值,然后使用这些值进行进一步处理。以下示例使用单个int值填充变量@t。如果在程序中使用它,则可以循环所有结果并根据需要插入它们。

DECLARE @t TABLE(tVal int);

DECLARE @P_LIST VARCHAR(MAX)='6854,6891'

IF CHARINDEX(',', @P_LIST) = 0
  INSERT INTO @t VALUES (CONVERT(int, @P_LIST));
ELSE
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(',', @P_LIST) 
    WHILE @start < LEN(@P_LIST) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@P_LIST) + 1

        INSERT INTO @t
        VALUES(SUBSTRING(@P_LIST, @start, @end - @start)) 
        SET @start = @end + 1 
        SET @end = CHARINDEX(',', @P_LIST, @start)

    END 
END

SELECT *
  FROM @t

答案 2 :(得分:-1)

Ac.Parameter中的列值必须是整数列。你试图在那里插入'6854,6891'。它会导致错误。并且'6854'是整数,这就是它工作的原因。如果您想在插入之前进行Int转换,请使用:

ALTER PROCEDURE [Ac].[SAVE]     
@P_LIST VARCHAR(MAX)=''     
AS
DECLARE @ID INT;
BEGIN
SET @ID = (NEXT VALUE FOR  Ac.SEQ)

INSERT INTO Ac.Parameter
    (ID, NAME, VALUE, MODIFIED_BY, MODIFIED_ON)
VALUES                      
    (@ID, 'LIST', CONVERT(INT, @P_LIST), @P_USER_ID, GETDATE()),          

SELECT @ID AS ID;       
END