【问题标题】:Stored procedure Not Accepting Newline character in parameter存储过程不接受参数中的换行符
【发布时间】:2016-09-15 15:01:03
【问题描述】:

我试图将逗号分隔的值作为存储过程的参数,但是当我按下“Enter”键以继续这些值以便它可以在单个屏幕中看到(不滚动)时,SP 不接受这些值按下“Enter”键后提供(表示换行)

USP_SAMPLE_SP @YEAR, @EMPIDS

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

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

运行正常

但如果我想像下面这样执行:

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

它接受所有值,但是它显示的值最高为“222”,之后它不考虑任何值。

提到“换行符”,我的意思是它接受如下:

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

但如果我按下“Enter”,之后就不再接受值了

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

注意:有时我需要传递大量值(例如 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. 

注意:在 Programmability -> Types -> User-Defined Table Types ->dbo.EMPType

它显示 EMPType 已创建。

【问题讨论】:

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


    【解决方案1】:

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

    有几种可能的解决方案。

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

    -- 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
    

    【讨论】:

    • 谢谢...你能告诉我如何从字符串中删除换行符吗?
    • 实际上我正在使用 SplitString 函数,并且我正在将 @EMPIDS 参数传递给它。我尝试在其上使用 LTRIM 和 RTRIM 函数,但它不起作用
    • @Shardul - 查看我的更新。 SplitString 不是内置 SQL Server 函数的名称,因此如果不查看代码,就不可能知道它的行为方式。
    • Edharper 我尝试了同样的事情,但以不同的方式 SET @EMPID = REPLACE(@EMPID,CHAR(13)+char(10)) 但只有大约 100 个值我可以降低性能差异。我想按照您建议的使用表值参数的另一种方式尝试。我尝试使用表值参数来完成它,但我发现它非常困难。如果你能帮我做这件事会很有帮助。
    • @Shardul - 编辑您的问题以包含您在使用表值参数时尝试过的详细信息,并详细说明您遇到的问题
    猜你喜欢
    • 1970-01-01
    • 2019-01-20
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 2017-03-12
    • 1970-01-01
    • 2017-09-22
    相关资源
    最近更新 更多