存储过程的字符串参数的最大长度是多少?

时间:2010-04-26 09:32:50

标签: sql

我有一个长度为1,44,000的字符串,必须作为参数传递给存储过程,该存储过程是对表的选择查询。 当这是一个查询(在c#中)它的工作正常。但是,当我将它作为参数传递给存储过程时,它无法正常工作。

这是我的存储过程,其中我已将此参数声明为NVARCHAR(MAX)

------------------------------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

CREATE PROCEDURE [dbo].[ReadItemData](@ItemNames NVARCHAR(MAX),@TimeStamp as DATETIME)

AS

select * from ItemData

where ItemName in (@ItemNames) AND TimeStamp=@TimeStamp

---------------------------------------------------------------------

这里的参数@ItemNames是一个用不同名称连接的字符串,例如 '项目1', '项目2', '项目3' ....等。

谁能告诉我这里出了什么问题?

谢谢&此致

帕德玛

3 个答案:

答案 0 :(得分:5)

我意识到这是一个老问题,但我看到的问题不是字段限制,而是语法。问题是存储过程不会将参数视为要插入SELECT文本的字符串,而是在字面上查找字段中是否存在1M +字符串。有几种方法可以解决这个问题。

首先,您可以在变量中动态构建SQL,然后像这样运行它:

DECLARE @SQL as nvarchar(max)
SET @SQL = 'SELECT * FROM ItemData WHERE ItemName in (' + @ItemsNames + ')'
         + ' AND TimeStamp = ''' + @TimeStamp + ''''
EXEC (@SQL)

但是,这仍然会失败,因为@ItemNames中嵌入了引号,导致生成的SQL无效。您可以使用以下命令更改@ItemNames:

REPLACE(@ItemNames, '''', '''''')

但我没有测试过这个。这里的想法是你在字符串文本中编写转义的单引号('')以向查询处理器发送单个单引号(')。上面的REPLACE函数查看任何单引号的文本,并用两个单引号替换它们。

更强大的解决方案是创建一个Split表值函数,然后用以下内容更改IN子句:

WHERE ItemName IN (SELECT SplitText FROM dbo.Split(@ItemNames))

我假设您正在处理Split函数中的嵌入式引号。我不建议只使用REPLACE删除引号,因为引号可能是保护字符串值中的逗号。

答案 1 :(得分:3)

从数据库语法看起来它看起来像Sql Server,these are the maximum sizes of things in Sql Server

Bytes per short string column 8,000 

可能是限制器。

虽然:

  

每个varchar的字节数(最大值),   varbinary(max),xml,text或image   第2栏^ 31-1

(即2,147,483,647)表明Sql Server会处理它,但对于ado.net。

答案 2 :(得分:1)

最高可以在VARCHAR(MAX)属性中传递8000个字符,在NVARCAHR(MAX)

中传递4000个字符

如果要传递更多信息,则需要使用“用户定义表格类型”作为参数。

步骤1:需要创建用户定义表类型。

CREATE TYPE udtt_ItemNames AS TABLE 
(
    Item nvarchar(100)    
)

步骤2:将udtt_ItemNames用户存储过程

CREATE PROCEDURE [dbo].[ReadItemData](@ItemNames udtt_ItemNames readonly,@TimeStamp as DATETIME)

AS

select * from ItemData

where ItemName in (select Item from @ItemNames) AND TimeStamp=@TimeStamp

所以现在你需要在执行存储过程时传递Table。