2010-11-03 8 views
0

Je pose la question au nom de quelqu'un qui travaille pour mon client qui me l'a demandé. Je suis en fait plus familier avec MySQL que SQL Server, mais malheureusement, SQL Server est ce que le client a utilisé pendant des années.Fractionner une chaîne en plusieurs valeurs dans SQL Server 2000

La question est la suivante: existe-t-il un moyen dans SQL Server de diviser une chaîne en plusieurs valeurs (par exemple, tableau?) Pouvant être utilisées dans une instruction WHERE.

Voici un exemple PHP de ce dont je parle.

<?php 
    $string = "10,11,12,13"; 
    $explode = explode(",", $string); 
?> 

$ explode serait égal à array (10,11,12,13). Ce que je dois faire quelque chose comme ceci:

SELECT {long field list] FROM {tables} WHERE hour IN SPLIT(",", "10,11,12,13") 

Avec SPLIT étant ma fonction pseudo-code qui effectue la division

La raison pour laquelle je ne fais pas cela dans, disons, PHP , parce que la requête est construite en rapportant un logiciel où nous ne pouvons pas exécuter de logique (comme mon code PHP) avant de l'envoyer à la base de données, et les valeurs multiples sont retournées par le logiciel comme une seule chaîne séparée par des tuyaux |). Malheureusement, je n'ai pas accès au logiciel de reporting (je pense qu'il a dit qu'il s'appelait Logi ou LogiReports ou quelque chose) ou à la requête que mon associé était en train de rédiger, mais tout ce qui est vraiment important pour cette question est la clause WHERE .

Des idées?

+0

Ceci est étiqueté comme serveur SQL 2000; si c'est en fait en 2005, il y a une nouvelle fonction table définie par l'utilisateur qui peut faire ce genre de chose TRÈS joliment – Nikki9696

+0

Haha, vous n'avez aucune idée de ce que j'ai dit "si seulement ces gars utilisaient 2005" - j'ai dit à propos de beaucoup de choses, y compris l'absence de la fonction HashBytes(). Malheureusement, c'est le serveur 2000. – WhiskeyTangoFoxtrot

Répondre

3

SQL dynamique peut être utilisé:

declare @in varchar(10) 
set @in = '10,11,12,13' 
exec ('SELECT {long field list] FROM {tables} WHERE hour IN (' + @in + ')') 
+0

Cela semble être la solution la plus pratique. Je l'ai essayé sur une requête simple avec des identifiants de client et fonctionne parfaitement. J'ai transmis cela à mon collègue. – WhiskeyTangoFoxtrot

+0

Une note: le SQL du dynamique ne donne pas de très bonnes performances. Il recompile l'instruction SQL et reconstruit le plan d'exécution à chaque fois. Mais si ce n'est pas très fréquent ou si vous n'avez pas besoin d'un plan rigoureux, cela semble raisonnable. – Badiboy

3

Plusieurs méthodes ici: Arrays and list in SQL Server

Pour les chaînes courtes, je préfère un numbers table

je pourrais copier/coller à partir d'ici, mais il vraiment mérite d'être lu

+0

Je ne suis pas sûr que cela soit utilisable dans ma situation puisque techniquement ce qu'il fait n'est pas le projet que mon contrat décrit, mais je vais lui faire suivre le lien et supposer que le guide bien écrit est utile. – WhiskeyTangoFoxtrot

1

Vous pouvez utiliser une fonction qui reçoit une chaîne contenant t il « id de » séparés par des tuyaux, et le retourner comme une table, que vous pouvez interroger et utiliser dans un sous-requête peut-être, comme ceci:

SELECT {long field list] FROM {tables} WHERE hour IN 
(SELECT OrderID from dbo.SplitOrderIDs('2001,2002')) 


ALTER FUNCTION [dbo].[SplitOrderIDs] 
(
@OrderList varchar(500) 
) 
RETURNS 
@ParsedList table 
(
OrderID int 
) 
    AS 
    BEGIN 
    DECLARE @OrderID varchar(10), @Pos int 

SET @OrderList = LTRIM(RTRIM(@OrderList))+ ',' 
SET @Pos = CHARINDEX(',', @OrderList, 1) 

IF REPLACE(@OrderList, ',', '') <> '' 
BEGIN 
    WHILE @Pos > 0 
    BEGIN 
     SET @OrderID = LTRIM(RTRIM(LEFT(@OrderList, @Pos - 1))) 
     IF @OrderID <> '' 
     BEGIN 
      INSERT INTO @ParsedList (OrderID) 
      VALUES (CAST(@OrderID AS int)) --Use Appropriate conversion 
     END 
     SET @OrderList = RIGHT(@OrderList, LEN(@OrderList) - @Pos) 
     SET @Pos = CHARINDEX(',', @OrderList, 1) 

    END 
END 

RETURN 
END