web-dev-qa-db-fra.com

SQL Server 2005 Utilisation de CHARINDEX () Pour fractionner une chaîne

Comment puis-je scinder la chaîne suivante en fonction du caractère '-'?

Donc si j'avais cette chaîne: LD-23DSP-1430

Comment pourrais-je le séparer en colonnes séparées comme ceci:

LD        23DSP       1430

Aussi, y a-t-il un moyen de scinder chaque caractère dans un champ séparé si je devais le faire (sans le '-')? J'essaie de trouver un moyen de remplacer chaque lettre par l'alphabet OTAN.

Donc, ce serait ..... Lima Delta Vingt Trois Delta Sierra Papa Quatorze Trente .... dans un champ.

Je sais que je peux avoir le côté gauche comme ceci:

LEFT(@item, CHARINDEX('-', @item) - 1)
12
user2531854

Je ne dirais pas que c'est facile ou évident, mais avec seulement deux traits d'union, vous pouvez inverser la chaîne et ce n'est pas trop difficile:

with t as (select 'LD-23DSP-1430' as val)
select t.*,
       LEFT(val, charindex('-', val) - 1),
   SUBSTRING(val, charindex('-', val)+1, len(val) - CHARINDEX('-', reverse(val)) - charindex('-', val)),
       REVERSE(LEFT(reverse(val), charindex('-', reverse(val)) - 1))
from t;

Au-delà de cela, vous pouvez utiliser plutôt split().

11
Gordon Linoff

Voici une petite fonction qui fera "l'encodage OTAN" pour vous:

CREATE FUNCTION dbo.NATOEncode (
   @String varchar(max)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
   WITH L1 (N) AS (SELECT 1 UNION ALL SELECT 1),
   L2 (N) AS (SELECT 1 FROM L1, L1 B),
   L3 (N) AS (SELECT 1 FROM L2, L2 B),
   L4 (N) AS (SELECT 1 FROM L3, L3 B),
   L5 (N) AS (SELECT 1 FROM L4, L4 C),
   L6 (N) AS (SELECT 1 FROM L5, L5 C),
   Nums (Num) AS (SELECT Row_Number() OVER (ORDER BY (SELECT 1)) FROM L6)
   SELECT
      NATOString = Substring((
         SELECT
            Convert(varchar(max), ' ' + D.Word)
         FROM
            Nums N
            INNER JOIN (VALUES
               ('A', 'Alpha'),
               ('B', 'Beta'),
               ('C', 'Charlie'),
               ('D', 'Delta'),
               ('E', 'Echo'),
               ('F', 'Foxtrot'),
               ('G', 'Golf'),
               ('H', 'Hotel'),
               ('I', 'India'),
               ('J', 'Juliet'),
               ('K', 'Kilo'),
               ('L', 'Lima'),
               ('M', 'Mike'),
               ('N', 'November'),
               ('O', 'Oscar'),
               ('P', 'Papa'),
               ('Q', 'Quebec'),
               ('R', 'Romeo'),
               ('S', 'Sierra'),
               ('T', 'Tango'),
               ('U', 'Uniform'),
               ('V', 'Victor'),
               ('W', 'Whiskey'),
               ('X', 'X-Ray'),
               ('Y', 'Yankee'),
               ('Z', 'Zulu'),
               ('0', 'Zero'),
               ('1', 'One'),
               ('2', 'Two'),
               ('3', 'Three'),
               ('4', 'Four'),
               ('5', 'Five'),
               ('6', 'Six'),
               ('7', 'Seven'),
               ('8', 'Eight'),
               ('9', 'Niner')
            ) D (Digit, Word)
               ON Substring(@String, N.Num, 1) = D.Digit
         WHERE
            N.Num <= Len(@String)
         FOR XML PATH(''), TYPE
      ).value('.[1]', 'varchar(max)'), 2, 2147483647)
);

Cette fonction fonctionnera même sur de très longues chaînes, et fonctionnera plutôt bien (je l’ai exécutée avec une chaîne de 100 000 caractères et elle est retournée en 589 ms). Voici un exemple d'utilisation:

SELECT NATOString FROM dbo.NATOEncode('LD-23DSP-1430');
-- Output: Lima Delta Two Three Delta Sierra Papa One Four Three Zero

J'en ai fait intentionnellement une fonction table afin qu'elle puisse être intégrée dans une requête si vous l'exécutez sur plusieurs lignes à la fois. Utilisez simplement CROSS APPLY ou placez l'exemple ci-dessus entre parenthèses pour l'utiliser comme valeur dans la clause SELECT (vous pouvez placez un nom de colonne dans la position du paramètre de la fonction).

5
ErikE

Essayez la requête suivante:

DECLARE @item VARCHAR(MAX) = 'LD-23DSP-1430'

SELECT
SUBSTRING( @item, 0, CHARINDEX('-', @item)) ,
SUBSTRING(
               SUBSTRING( @item, CHARINDEX('-', @item)+1,LEN(@ITEM)) ,
               0 ,
               CHARINDEX('-', SUBSTRING( @item, CHARINDEX('-', @item)+1,LEN(@ITEM)))
              ),
REVERSE(SUBSTRING( REVERSE(@ITEM), 0, CHARINDEX('-', REVERSE(@ITEM))))
2
Hiren Dhaduk
    USE [master]
    GO
    /******  this function returns Pakistan where as if you want to get ireland simply replace (SELECT SUBSTRING(@NEWSTRING,CHARINDEX('$@$@$',@NEWSTRING)+5,LEN(@NEWSTRING))) with
SELECT @NEWSTRING = (SELECT SUBSTRING(@NEWSTRING, 0,CHARINDEX('$@$@$',@NEWSTRING)))******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE FUNCTION [dbo].[FN_RETURN_AFTER_SPLITER] 
    (  
     @SPLITER varchar(max))
    RETURNS VARCHAR(max)
    AS 
    BEGIN

    --declare @testString varchar(100),
    DECLARE @NEWSTRING VARCHAR(max) 
    -- set @teststring = '@ram?eez(ALi)'
     SET @NEWSTRING = @SPLITER ; 

    SELECT @NEWSTRING = (SELECT SUBSTRING(@NEWSTRING,CHARINDEX('$@$@$',@NEWSTRING)+5,LEN(@NEWSTRING)))
    return @NEWSTRING 
    END
    --select [dbo].[FN_RETURN_AFTER_SPLITER]  ('Ireland$@$@$Pakistan')
0
RameezAli
DECLARE @variable VARCHAR(100) = 'LD-23DSP-1430';
WITH    Split
      AS ( SELECT   @variable AS list ,
                    charone = LEFT(@variable, 1) ,
                    R = RIGHT(@variable, LEN(@variable) - 1) ,
                    'A' AS MasterOne
           UNION ALL
           SELECT   Split.list ,
                    LEFT(Split.R, 1) ,
                    R = RIGHT(split.R, LEN(Split.R) - 1) ,
                    'B' AS MasterOne
           FROM     Split
           WHERE    LEN(Split.R) > 0
         )
SELECT  *
FROM    Split
OPTION  ( MAXRECURSION 10000 );
0
Kandarp Patel
Create FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(200), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata NVARCHAR(10) 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@string) + 1

        INSERT INTO @output (splitdata)  
        VALUES(SUBSTRING(@string, @start, @end - @start)) 
        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END 
    RETURN 

END**strong text**
0
user3748437