2010-04-26 14 views
7

Ich habe eine Zeichenfolge der Länge 1,44,000, die als Parameter an eine gespeicherte Prozedur übergeben werden muss, die eine Auswahlabfrage für eine Tabelle ist. Wenn dies in einer Abfrage (in C#) ist, funktioniert es gut. Aber wenn ich es als ein Parameter an gespeicherte Prozedur übergeben, funktioniert es nicht.Was ist die maximale Länge eines Zeichenfolgenparameters für gespeicherte Prozedur?

Hier ist meine gespeicherten Prozedur, wo in i diesen Parameter als NVARCHAR (MAX) erklärt haben

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

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

Hier die Parameter @ItemNames ist ein String mit unterschiedlichen Namen wie 'Element1' verkettet 'Element2' , "Item3" .... usw.

Kann jemand sagen, was hier schief gelaufen ist?

Dank & Grüße

Padma

+2

Die maximale Länge eines Zeichenfolgenparameters für eine gespeicherte Prozedur hängt wahrscheinlich von der Datenbank ab. Verwenden Sie SQL Server? Welche Version? –

Antwort

3

Von den Blicken der Datenbank Syntax es wie SQL Server aussieht, these are the maximum sizes of things in Sql Server.

Bytes per short string column 8,000 

Ist wahrscheinlich der Begrenzer.

Obwohl:

Bytes pro VARCHAR (max), varbinary (max), XML, Text oder Bild Spalte 2^31-1

(dh 2,147,483,647) legt nahe, dass Sql Server würde es aber für ado.net handhaben.

+0

obwohl die Größenbeschränkung 2^31-1 ist, nimmt es nicht diesen Parameter, der wie folgt aus dem Code gegeben wird: command.Parameters.Add ("@ ItemNames", SqlDbType.VarChar) .Value = itemNames.ToString (); – padmavathi

+0

Ich denke nicht, dass der Begrenzer Sql Server ist, in diesem Fall - aber ADO.NET. Ich erinnere mich (damals), als ich ADO/VBScript verwendete, gab es ein Limit von etwa 8.040 Bytes für ein Recordset - ich werde sehen, ob ich eine Referenz finden kann, aber es könnte durchaus eine kumulative Grenze für die Eingabe oder Ausgabe geben Parameter auf ADO.NET – amelvin

+0

OK, also nur um klar zu sein, gibt es etwa 1000 Bytes pro Zeichen –

0

Maximal können Sie 8000 Zeichen in VARCHAR(MAX) Eigenschaft und 4000 Zeichen in NVARCAHR(MAX)

passieren Wenn Sie mehr passieren wollen dann, dass dann müssen Sie User Define Tabellentyp als Parameter verwenden.

Schritt 1: Erstellen Sie einen benutzerdefinierten Tabellentyp.

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

Schritt 2: Verfahren Benutzer die udtt_ItemNames in store

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] 

So, jetzt müssen Sie Tabelle passieren, während der Speichervorgang auszuführen.

4

Ich weiß, dass dies eine alte Frage ist, aber das Problem, das ich sehe, ist nicht eine der Feldbegrenzung, sondern Syntax. Das Problem besteht darin, dass die gespeicherte Prozedur den Parameter nicht als eine Zeichenfolge behandelt, die in den SELECT-Text eingefügt werden soll, sondern buchstäblich nach dem Vorhandensein der Zeichenfolge 1M + in Ihrem Feld sucht. Es gibt ein paar Möglichkeiten, damit umzugehen.

Erstens können Sie die SQL-dynamisch in einer Variablen, bauen und sie dann wie folgt ausführen:

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

Dies wird jedoch immer noch scheitern, weil @ItemNames darin zitiert eingebettet ist, die resultierende SQL verursacht ungültig sein.Möglicherweise können Sie die @ItemNames mit folgenden Parametern ändern:

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

aber ich habe dies nicht getestet. Die Idee hier ist, dass Sie geschriebene einfache Anführungszeichen ('') in dem Zeichenfolge-Text schreiben, um ein einzelnes einzelnes Anführungszeichen (') an den Abfrage-Prozessor zu senden. Die obige REPLACE-Funktion sucht im Text nach einzelnen Anführungszeichen und ersetzt sie durch zwei einfache Anführungszeichen.

Eine robustere Lösung wäre, eine Split-Tabellenwertfunktion zu erstellen, dann IN-Klausel wie mit etwas ändern:

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

Ich gehe davon aus, dass Sie kümmern sich um die eingebetteten Anführungszeichen innerhalb der Split Funktion. Ich empfehle nicht, nur Anführungszeichen mit einem REPLACE zu entfernen, da die Anführungszeichen möglicherweise Kommas innerhalb des Zeichenfolgenwerts schützen.

Verwandte Themen