2009-07-01 13 views
50

ich den folgenden Code bin mit:Begrenzung der WHERE col IN (...) Zustand

SELECT * FROM table 
WHERE Col IN (123,123,222,....) 

Allerdings, wenn ich mehr als ~ 3000 Zahlen in der IN Klausel setzen, wirft SQL einen Fehler.

Weiß jemand, ob es eine Größenbeschränkung oder etwas Ähnliches gibt? !!

+2

Teilen Sie die Zahlen in der IN-Klausel nach Gruppen auf, die groß genug sind, um sie zu verarbeiten und alle gleichzeitig zu synchronisieren. –

Antwort

51

Je nach verwendeter Datenbank-Engine kann die Länge einer Anweisung begrenzt sein.

SQL Server hat eine sehr große Grenze:

http://msdn.microsoft.com/en-us/library/ms143432.aspx

ORACLE hat eine sehr einfache Grenze auf der anderen Seite zu erreichen.

Also, für große IN-Klauseln, ist es besser, eine temporäre Tabelle zu erstellen, die Werte einzufügen und einen JOIN zu machen. Es funktioniert auch schneller.

+3

nicht korrekt. Max Größe der SQL-Anweisung oder ein Batch ist 65K * (Netzwerkpaketgröße, die in der Regel 4K ist) = mehr als 250 Mb ... http://msdn.microsoft.com/en-us/library/ms143432.aspx. –

+0

Sie sind verdammt direkt vor Ort, ergänzte ich die Antwort. Übrigens, in ORACLE ist das Limit SEHR einfach zu erreichen! – tekBlues

+0

Mit einem Temp-Tabelle war meine perfekte Lösung, rettete meinen Tag! Vielen Dank! – Yaroslav

28

Es gibt eine Grenze, aber Sie können Ihre Werte in separate Blöcke in()

Select * 
From table 
Where Col IN (123,123,222,....) 
or Col IN (456,878,888,....) 
+0

IN() ist nicht SARGable.Es ist viel besser, wenn Sie Ihre Parameter in eine temporäre Tabelle oder einen TVP schieben und dann einen INNEREN JOIN verwenden. –

+0

Was ist das Limit für obige Abfrage? Ich meine, wie viele IN Klauseln kann ich mit OR definieren? –

3

gespalten Warum nicht ein, wo in einem Unter wählen tun ...

Pre-Abfrage in eine temporäre Tabelle oder etwas ...

CREATE TABLE SomeTempTable AS 
    SELECT YourColumn 
    FROM SomeTable 
    WHERE UserPickedMultipleRecordsFromSomeListOrSomething 

dann ...

SELECT * FROM OtherTable 
WHERE YourColumn IN (SELECT YourColumn FROM SomeTempTable) 
+3

Besser, eine Verbindung zu der Temp-Tabelle als ein Subselect normalerweise zu machen. – HLGEM

+0

Wäre eine bestehende Klausel nicht noch besser? – Lukazoid

7

Du es falsch zu machen.

Parametrieren Sie Ihre Abfrage und übergeben Sie die IDs mit einem Table Valued Parameter.

Zum Beispiel könnten Sie die folgende Art

CREATE TYPE IdTable AS TABLE (Id INT NOT NULL PRIMARY KEY) 

Und haben die folgende gespeicherte Prozedur

CREATE PROCEDURE sp__Procedure_Name 
    @OrderIDs IdTable READONLY, 
AS 

    SELECT * 
    FROM table 
    WHERE Col IN (SELECT Id FROM @OrderIDs) 
+0

3 downvotes aber keine Kommentare, jemanden interessiert zu erklären? –

+1

Ich weiß nicht, warum Sie downvoted werden, weil dies eine vollständig gültige Lösung ist. Obwohl ich die 'ID ID von @ OrderIDs 'zu einem Join ändern würde. – Logan

+0

Ich weiß, dass dies eine alte Antwort ist, aber wissen Sie, was mit Ihren OrderIds passiert? bleibt es? oder ist es einfach eine temporäre Datei? –

-2

definieren Sie Tupel wie folgt verwenden können: SELECT * FROM Tabelle WHERE (Col, 1) IN ((123,1), (123,1), (222,1), ....)

Es gibt keine Beschränkungen hinsichtlich der Anzahl von diesen. Es vergleicht Paare.

+0

Nein, in SQL Server können Sie nicht. SQL Server verwendet T-SQL, das nicht ANSI SQL-kompatibel ist (kein anderer Dialekt). –