我有一个长度为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是一个用不同名称连接的字符串,例如'Item1','Item2','Item3'....等等.
谁能告诉我这里出了什么问题?
感谢和问候
帕德玛
从数据库语法的外观看起来像Sql Server,这些是Sql Server中事物的最大大小。
Bytes per short string column 8,000 
可能是限制器。
虽然:
每个varchar(max),varbinary(max),xml,text或image列的字节数2 ^ 31-1
(即2,147,483,647)表明Sql Server可以处理它,但仅适用于ado.net。
小智 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删除引号,因为引号可能会保护字符串值内的逗号。