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)
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()
.
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).
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))))
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')
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 );
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**