存储过程不接受参数中的换行符

时间:2016-09-15 15:01:04

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

我试图将逗号分隔值作为参数存储到存储过程中,但是当我按下"输入"为了能够在单个屏幕中看到它(不滚动),SP不接受在"输入"之后提供的值。按下键(表示新行)

USP_SAMPLE_SP @YEAR, @EMPIDS

如果我正在执行以下存储过程:

USP_SAMPLE_SP '2016','111,222,333,444,555'

正在执行

但如果我尝试执行如下:

USP_SAMPLE_SP '2016','111,222,
333,444,555'

它接受所有值,但它显示的值高达' 222'之后,它没有考虑任何价值。

参考" Newline"我的意思是它接受如下:

USP_SAMPLE_SP '2016','111,        222,333,444,555'

但如果我按下"输入"

之后它不接受价值观

如果有人能解释这种情况,那将会有所帮助。

注意:有时我需要传递大量值(例如1000或以上)。

请建议是否有人知道更好,更有效的方法。

首先,我将用户定义的表类型创建为EMPType

  CREATE TYPE [dbo].[EMPType] AS TABLE(
      FinStartYear varchar(4),
      EmpId nvarchar(max) NULL
)

然后我试图传递这些值来改变我的存储过程,如下所示:

ALTER PROCEDURE  [USP_SAMPLE_SP]   
 -- Add the parameters for the stored procedure here  
  @FinStartYear EMPType readonly ,  
 @EmpIDs  EMPType  readonly

AS  

但是当我将鼠标悬停在参数上时,它会显示错误信息:

The Parameter '@FinStartYear' cannot be declared READONLY since it is not table valued parameter.   

The Parameter '@EmpIDs' cannot be declared READONLY since it is not table valued parameter.   

但是当我试图改变存储过程时,它会向我显示以下错误:

    Must declare the scalar variable "@EmpIDs".
    Must declare the scalar variable "@FinStartYear"

当我将鼠标悬停在EMPType'它显示我的错误:

Parameter or variable '@FinStartYear' has an invalid datatype. 

注意:在可编程性下 - >类型 - >用户定义的表类型 - > dbo.EMPType

它显示我已经创建了EMPType。

1 个答案:

答案 0 :(得分:0)

如果没有看到存储过程的代码,就不可能确定,但​​我怀疑换行符会以某种方式破坏用于将分隔字符串拆分为结果集的代码;换行符被解释为终止符,后面的所有值都被忽略。

有几种可能的解决方案。

一种是从一系列较短的字符串构建输入值列表,使您可以控制列表在屏幕上的显示方式而不会影响其内容。请注意,这需要使用变量:

-- I am guessing the data type of the @EMPIDS parameter. Use a matching type for @IDS
DECLARE @IDS VARCHAR(MAX) = '111,222,'       
                             + '333,444,555'

EXEC USP_SAMPLE_SP @YEAR = '2016', @EMPIDS = @IDS

另一种方法是在拆分分隔列表之前修改存储过程的代码以去掉换行符。我不推荐这样做,因为代码的其他用户可能会依赖此行为。

修改

以下是如何替换换行符的示例:

DECLARE @EMPID varchar(100) = '111,222,
333,444,555'

SET @EMPID = REPLACE(REPLACE(@EMPID,CHAR(13),''),CHAR(10),'')

SELECT @EMPID

在使用此功能之前,请确保您不会影响此代码中可能依赖当前行为的任何其他用户。

另一种解决方案是修改存储过程以接受table-valued parameter而不是分隔列表。设置起来有点复杂,但可能比分割分隔字符串更好,特别是如果字符串包含数千个值。

修改2

我认为您可能误解了表值参数的工作原理。它使您能够完全避免连接的EMPID列表,而是使用每行包含一个EMPID的表变量,该变量可以作为参数传递给存储过程。

这是一个有效的例子:

CREATE TYPE dbo.EMPType AS TABLE(
      EmpId int NOT NULL PRIMARY KEY
)
GO

-- I don't know what your procedure does so I've created a simple stub
-- which shows how to use the table-valued parameter like a table
CREATE PROCEDURE dbo.USP_SAMPLE_SP
    @FinStartYear varchar(4),
    @empids EMPType readonly
AS
    SELECT @FinStartYear AS out_year, EmpId
    FROM    @empids
    ORDER BY EmpId
GO

-- use the code from here to the end of the example every time
-- you want to execute the procedure (setting the list of EMPID values appropriately
DECLARE @in_emp EMPType --declare an instance of EMPType as a variable

INSERT @in_emp(EmpId) VALUES (111),(333),(222),(555),(444) --insert some values into the variable

EXEC dbo.USP_SAMPLE_SP @FinStartYear = '2016',@empids = @in_emp --pass the variable as a parameter to the stored procedure
GO