SQL Server:函数在存储过程中返回单个char

时间:2014-02-26 17:54:47

标签: sql sql-server-2008 stored-procedures

我正在使用SQL Server 2008

这是函数(拆分字符串并返回int值)

USE [SANNET]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata int 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@string) + 1

        INSERT INTO @output (splitdata)  
        VALUES(CAST(SUBSTRING(@string, @start, @end - @start)AS  int))
        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END 
    RETURN 
END
GO

使用这种方式时一切正常

select * from fnSplitString('65,1,2,27,28,33,34',',')
/**
Returning
splitdata
-----------
65
1
2
27
28
33
34

(7 row(s) affected)


*/

但是当我在存储过程中使用时返回一个char(甚至不是一行)

-- Procedure which calling the function


CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values varchar
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
     SET NOCOUNT ON;
    select * from fnSplitString(@values,',');

END
GO

用法

DECLARE @result int

EXEC    @result = [dbo].[CallerProcedure]
        @values = '65,1,2,27,28,33,34'

SELECT @result

GO
/*
Returns
splitdata
-----------
6


-----------
0

(1行受影响)

* /

如你所见甚至没有返回“64”。刚刚回归6。

我在哪里做错了?

由于

2 个答案:

答案 0 :(得分:4)

您尚未为VARCHAR输入变量@values定义长度,因此它默认为VARCHAR(1)

CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values varchar

因此,虽然您认为自己正在传递'65,1,2,27,28,33,34',但这会被截断为'6'

将@Values的声明更改为VARCHAR(MAX)将解决您的问题。

CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values VARCHAR(MAX)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
     SET NOCOUNT ON;
    select * from fnSplitString(@values,',');

END
GO

<强> Example on SQL Fiddle

转换为或声明VARCHAR时,始终应定义长度。进一步阅读:

<强> Bad habits to kick : declaring VARCHAR without (length)

答案 1 :(得分:1)

按如下方式修改您的程序。首先将结果插入变量表中,然后返回它。另外,不要忘记设置VARCHAR字段的大小。

CREATE PROCEDURE [dbo].[CallerProcedure] @values VARCHAR(MAX)
AS
    BEGIN
        SET NOCOUNT ON;

        DECLARE @MyTable AS TABLE
        (
            value VARCHAR(20)
        )

        INSERT INTO @MyTable
        SELECT *
            FROM fnSplitString(@values, ',');

        SELECT *
        FROM @MyTable
    END
GO