2010-04-26 31 views
7

Tengo una cadena de longitud 1,44,000 que se debe pasar como un parámetro a un procedimiento almacenado que es una consulta de selección en una tabla. Cuando un dar esto está en una consulta (en C#) está funcionando bien. Pero cuando lo paso como un parámetro para el procedimiento almacenado, no funciona.¿Cuál es la longitud máxima de un parámetro de cadena para el procedimiento Almacenado?

Aquí está mi procedimiento almacenado en donde he declarado este parámetro como 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 [email protected] 

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

Aquí los @ItemNames parámetro es una cadena concatinated con diferentes nombres como 'Elemento1', 'Item2' , 'Item3' ... etc.

¿Alguien puede decir qué salió mal aquí?

Gracias Saludos &

Padma

+2

La longitud máxima de un parámetro de cadena a un procedimiento almacenado probablemente depende de la base de datos. ¿Estás usando SQL Server? ¿Cual version? –

Respuesta

3

Desde el aspecto de la base de datos de sintaxis se ve como SQL Server, these are the maximum sizes of things in Sql Server.

Bytes per short string column 8,000 

Probablemente es el limitador.

Aunque:

Bytes por varchar (max), varbinary (max), XML, texto o imagen columna 2^31-1

(es decir, 2147483647) sugiere que Servidor Sql lo manejaría, pero para ado.net.

+0

aunque el límite de tamaño es 2^31-1, no está tomando este parámetro que se da como sigue del código: command.Parameters.Add ("@ ItemNames", SqlDbType.VarChar) .Value = itemNames.ToString (); – padmavathi

+0

No creo que el limitador sea Sql Server, en este caso, sino ADO.NET. Recuerdo (de vuelta en el día) cuando estaba usando ADO/VBScript había un límite de aproximadamente 8,040 bytes para un conjunto de registros. Veré si puedo encontrar una referencia, pero bien podría haber un límite acumulativo para la entrada o la salida. parámetros en ADO.NET – amelvin

+0

OK, así que para ser claros, hay alrededor de 1000 bytes por carácter –

0

máximo que puede pasar a 8000 caracteres en VARCHAR(MAX) propiedad y 4000 caracteres en NVARCAHR(MAX)

Si desea pasar más que eso, entonces tienes que utilizar usuario Definir tipo de tabla como parámetro.

Paso 1: Necesita crear el tipo de tabla Definir usuario.

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

Paso 2: El usuario los udtt_ItemNames en el almacén Procedimiento

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

AS 

select * from ItemData 

where ItemName in (select Item from @ItemNames) AND [email protected] 

Así que ahora lo que necesita para pasar la tabla, mientras que ejecutar el procedimiento tienda.

4

Me doy cuenta de que esta es una vieja pregunta, pero el problema que veo no es de limitación de campo, sino de sintaxis. El problema es que el procedimiento almacenado no trata el parámetro como una cadena que se insertará en el texto SELECCIONAR, sino que busca literalmente la presencia de la cadena 1M + en su campo. Hay un par de formas de lidiar con esto.

En primer lugar, se puede construir el SQL de forma dinámica en una variable, y luego ejecutarlo así:

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

Sin embargo, esto todavía va a fracasar, porque @ItemNames ha incrustado cotizaciones en el mismo, haciendo que el SQL resultante ser inválidoEs posible que pueda cambiar @ItemNames con:

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

pero no he probado esto. La idea aquí es que está escribiendo comillas simples escapadas ('') en el texto de cadena para enviar una sola comilla simple (') al procesador de consultas. La función REEMPLAZAR arriba está mirando dentro del texto para cualquier comilla simple, y reemplazándolas por dos comillas simples.

Una solución más robusta sería la creación de una función con valores de tabla de Split, a continuación, cambiar su cláusula IN con algo como:

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

Estoy asumiendo que usted está tomando el cuidado de las comillas incrustadas dentro de la división función. No recomiendo simplemente eliminar comillas con un REEMPLAZO, ya que las comillas pueden proteger las comas dentro del valor de la cadena.

Cuestiones relacionadas